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/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/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..caa5ecbea521dcf891c15d0653129025e32f45d1 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) { @@ -280,7 +284,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); 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/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/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/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 isagetBeginLoc())).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/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..03dcfa5f811095b0b2045a84c658c2d6828c62da 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -889,7 +889,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)) 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/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/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/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..f43ce928463b90cd2e863fff34be2ad418215218 100644 --- a/clang-tools-extra/clangd/CompileCommands.cpp +++ b/clang-tools-extra/clangd/CompileCommands.cpp @@ -338,7 +338,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 +587,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/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/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..6fbb310b660a178540707cb7a2cb27d6599418d5 100644 --- a/clang-tools-extra/clangd/InlayHints.cpp +++ b/clang-tools-extra/clangd/InlayHints.cpp @@ -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..cf6102db8dd317c4587e6b31a75a02d4406bb692 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. 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/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index 9fd002d0eebba5f314d0bd953210bb9275ab58b9..c3ba655ee2dc6a7b0cb8bff5f3fd36773801f712 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -563,7 +563,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); 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/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..2a6ae9c325b736c4dc6156fcb71c3a8652901579 100644 --- a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp +++ b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp @@ -228,14 +228,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(); diff --git a/clang-tools-extra/clangd/unittests/IndexActionTests.cpp b/clang-tools-extra/clangd/unittests/IndexActionTests.cpp index fad751bd0f7dc220d8ffb4434b7eefec6b1d2762..fa3d9c3212f9ca7ee1cf9de66c4f1d12b08d468e 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, diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp index 6e91053632e00bfac1800f2771c2cbee097c53ae..0ca95b5fed5d31d4c30d2ce0bff2e0de468b9c12 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; } 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/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/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/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/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 066e4ac5b9e54b83965d0cbc64740f12a06aaa0f..2e32f8b36d23deecf0e5c6a2411877a33c7b2e8a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -521,6 +521,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 +688,9 @@ 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 `_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -968,6 +974,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 ^^^^^^^^^^^^^^^^^^^^^^^^^ 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/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index d7e39ab2616fd90514327ca57ecc0a226cc58590..5943af50b6ad8f210ae5ed60bec3b3a96dca8359 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -325,7 +325,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 +435,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` @@ -608,14 +599,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. /// diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 0d94ea2851c9ab6bc8e2a8057b517ebc7f9e7af8..2b57058d3f1c75fc17e31a616e9c5328ed8a00c7 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); } } diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 1a98196834cefc31a73523b79a82035c408db535..90041fa8dbb30b9b7d7be0f91eb4e03437152a29 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. }]; } 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..7cf347e92d99722e56a4098f93e9495295ed02e9 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">; @@ -1487,4 +1488,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/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 94e97a891baedcdcbbfb02805d771201d82d8db4..6e6f56ff75e5f996a21f0b9b6550c3af26d3a9a2 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< @@ -8729,7 +8732,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 +11371,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/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..aa0f5023104a1a9468c017ce92fa850e8c0378e4 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1423,6 +1423,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/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index aa9b105364a51a1004873c95e4dda5ac811268df..98d7028eb28309558bd706a9b81265196b3f8708 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,23 +1958,36 @@ 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>]>; -} - -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 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>]>; 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">; @@ -2042,21 +2067,13 @@ def SVDOT_X2_F : SInst<"svdot[_{d}_{2}_{3}]", "ddhh", "f", MergeNone, "aarch64_ 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,6 +2081,9 @@ 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 { @@ -2168,6 +2188,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 +2284,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 +2300,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 +2326,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/Driver/Options.td b/clang/include/clang/Driver/Options.td index 25c76cf2ad2c84ad15c2ac6a39390043477afd91..1b02087425b751516424103857846a665b76b53c 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))">; @@ -8217,7 +8219,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 +8234,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/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 1d7b4c729ce84e0968f78d5250c70438e86e927a..a4f8fc1845b1ce8f82252fdcf9cea00d0999162b 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); @@ -13851,6 +13851,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/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 9bb89ec9410911afb362830ffdd35ff1059af899..59358e77edb072738144052f478baa51909557bb 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. 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/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp index ec1fb3ffa961c95cbfba635388ff19f8751401dc..a921c8b9fce3e0e0923f4bb621234dbaa189cac3 100644 --- a/clang/lib/APINotes/APINotesManager.cpp +++ b/clang/lib/APINotes/APINotesManager.cpp @@ -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/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/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/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..27096a83b8dd603eff2dd9d42b542eb6061d3795 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 { @@ -737,7 +737,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..93919cd0243d0c8f15b7ffa0da69de17fa1988de 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) { @@ -1044,6 +1080,7 @@ RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env) { if (auto *ExistingVal = cast_or_null(Env.getValue(Expr))) { auto &NewVal = Env.create(ExistingVal->getLoc()); Env.setValue(Expr, NewVal); + Env.setValue(NewVal.getLoc(), 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/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index bbf5f12359bc70e91ef4c3f2a1780a594cda0603..346469660662e0d3afc4c60a5775b00d011fbeb7 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -489,7 +489,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); @@ -582,6 +581,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); } } 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..5902c6dc3ce0b48073bac9663a50e6cc82106fa0 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) { @@ -742,7 +742,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..def16c032c869e59c3acb51bd4e8dfd19880fe2b 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -1062,7 +1062,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 +1071,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 +1095,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 +1106,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()) 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/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..60a4e0ed69c34dcc5b9106cbc4630665f64ca2d6 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -434,14 +434,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 +461,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 +475,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/Warnings.cpp b/clang/lib/Basic/Warnings.cpp index cc8c138233ca1d9fcc4ef04840b87fb2efb94655..cb23d844ef8f6f24538e920f80f7f483c9d50732 100644 --- a/clang/lib/Basic/Warnings.cpp +++ b/clang/lib/Basic/Warnings.cpp @@ -97,7 +97,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-")) { + if (Opt.starts_with("no-")) { isPositive = false; Opt = Opt.substr(3); } @@ -133,7 +133,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 +162,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) { @@ -204,7 +204,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 = !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..480410db1021b73b65e524945ff89cbd1fc96f4a 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) { @@ -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..4eb1686f095062f023800d30dbcd567c5b4f3508 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -232,19 +232,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()); } @@ -942,7 +942,7 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, : Builder.CreateZExtOrTrunc(FAMSize, ResType); Value *Res = FAMSize; - if (const auto *DRE = dyn_cast(Base)) { + if (isa(Base)) { // The whole struct is specificed in the __bdos. const RecordDecl *OuterRD = CountedByFD->getDeclContext()->getOuterLexicalRecordContext(); @@ -3214,7 +3214,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 +3410,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 +9992,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}; } @@ -17023,7 +17034,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 +17272,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..ed9aaa28c257337c321592b88e3af54103c2c968 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -431,7 +431,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:: @@ -3156,7 +3156,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/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/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index bb6b1a3bc228cf9889bfc3655c48884c20410acb..4121a3709bc3afbae86b7ac3f1ab86f948b2cd32 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -418,6 +418,8 @@ void BackendConsumer::anchor() { } } // namespace clang bool ClangDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) { + if (DI.getSeverity() == DS_Error) + HasErrors = true; BackendCon->DiagnosticHandlerImpl(DI); return true; } @@ -1139,7 +1141,7 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) { // Strip off a leading diagnostic code if there is one. StringRef Msg = Err.getMessage(); - if (Msg.startswith("error: ")) + if (Msg.starts_with("error: ")) Msg = Msg.substr(7); unsigned DiagID = diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index b931a81bc00871b6d1de5fc0919e64467324b6cb..7ad26ace328ab2e324c3470f6265104a3a16e4f1 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); @@ -1715,7 +1715,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 +1769,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 +3828,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 +4164,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/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..ff95c899c5f3d4e91770f8203001a62eafddb199 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1451,7 +1451,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 +1540,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 +1551,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 +1780,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 +2001,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 +2041,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 +2053,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 +2535,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 +6565,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 +6606,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 +6620,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..f9670ea6f251bd2ed7e8b4334dbd0c3cb99fd512 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; } 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/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index 3e51b2b5ce8642e0ac08afc98617e96b630e2816..fef0522aaf45b8a3d34b12782bf6c4ca27ab5645 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -234,15 +234,15 @@ 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-"); + bool IsNegative = Name.starts_with("no-"); if (IsNegative) Name = Name.substr(3); #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 +260,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 +269,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..de9fd5eaa1e020f6f6d3d43ffccb0dd4f82e9840 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; } @@ -1715,7 +1715,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; @@ -2503,7 +2503,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 +2528,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 +2570,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 +2581,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 +2597,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; @@ -3331,7 +3331,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 +5615,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 +5886,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 +7951,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 +8382,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 +8653,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..45901ee7157f77b36ef878faecbe745f8a513047 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,91 @@ 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; +} + +/// 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) { + // 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. + if (!isWholeArchivePresent(Args) && !TC.getTriple().isMacOSX()) { + 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; - } - } } } @@ -2336,20 +2361,20 @@ 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")) + if (Lib.starts_with("-l")) Lib = Lib.drop_front(2); 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..835215a83c4037eee2e5351993fff8983432f0ff 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -1084,7 +1084,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 +1288,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"); @@ -3055,7 +3055,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..9a9792d019d5edb2fef62359e9cd07d4ed3a9fd1 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -328,7 +328,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/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 9e4e939503dfe4a0b5dd501e14353cdb4133c664..bd319f21b05f86415bd4677cc81d2fb5c42a8523 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; } @@ -608,7 +608,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 +2293,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 +2316,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 +2345,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 +2757,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..28271181e07d0c0e32d8f1e3c968a92835b7f6ba 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; @@ -1909,7 +1905,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 +2341,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 +2927,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 +3212,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 +3238,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 +3266,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 +3421,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 +3533,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 +3555,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 +3877,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 +3958,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 +4118,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/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..f3551af3424396967c2ec5ce1250d7d4911fd63a 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 @@ -3724,8 +3728,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 +4228,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 +4576,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 +5216,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..c38b4c884070bb74ccad00dcf8a2539a3653c30e 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, @@ -4459,8 +4459,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..e96669f856bb18536aa91a087c258149adad4748 100644 --- a/clang/lib/Frontend/DependencyGraph.cpp +++ b/clang/lib/Frontend/DependencyGraph.cpp @@ -110,7 +110,7 @@ void DependencyGraphCallback::OutputGraphFile() { writeNodeReference(OS, AllFiles[I]); OS << " [ shape=\"box\", label=\""; StringRef FileName = AllFiles[I].getName(); - if (FileName.startswith(SysRoot)) + if (FileName.starts_with(SysRoot)) FileName = FileName.substr(SysRoot.size()); OS << DOT::EscapeString(std::string(FileName)) << "\"];\n"; 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..09c1460d54e1d7701542de30e34e4f738e7b1129 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,7 +1144,7 @@ std::unique_ptr Directive::create(bool RegexKind, std::string RegexStr; StringRef S = Text; while (!S.empty()) { - if (S.startswith("{{")) { + if (S.starts_with("{{")) { S = S.drop_front(2); size_t RegexMatchLength = S.find("}}"); assert(RegexMatchLength != StringRef::npos); diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index fdd54c05eedf8250436b1bff46c66178846f5f91..f8fdd402777e484695b92a87225f45f5b33bba21 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -387,6 +387,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 +405,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/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/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/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/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..42e29e43093789dd7a88d97adc612477f8ed67d8 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1219,7 +1219,7 @@ 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_")) { + } else if (FunctionName.starts_with("__builtin_")) { FunctionName = FunctionName.drop_front(std::strlen("__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: @@ -5323,9 +5390,9 @@ bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, 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"; + return Diag(TheCall->getBeginLoc(), + diag::err_riscv_type_requires_extension) + << Op1Type << "zvknhb"; return CheckInvalidVLENandLMUL(TI, TheCall, *this, Op1Type, ElemSize << 2) || CheckInvalidVLENandLMUL(TI, TheCall, *this, Op2Type, ElemSize << 2) || @@ -8177,13 +8244,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 +18355,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..be6a136ef37bc4e9e290aac066d833395d5ae525 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15800,7 +15800,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 +16005,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 +16359,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) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 59e456fd9f729837de00d86e5511db839d960c6d..5b29b05dee54b3e95032df22b729594fda8ea7dd 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,7 +5825,7 @@ struct IntrinToName { static bool ArmBuiltinAliasValid(unsigned BuiltinID, StringRef AliasName, ArrayRef Map, const char *IntrinNames) { - if (AliasName.startswith("__arm_")) + if (AliasName.starts_with("__arm_")) AliasName = AliasName.substr(6); const IntrinToName *It = llvm::lower_bound(Map, BuiltinID, [](const IntrinToName &L, unsigned Id) { @@ -6663,10 +6669,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 +7298,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; } 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..c7185d56cc99739882d5f7a75aed0d2f81ba0a24 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13808,12 +13808,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 +15508,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/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 5ca6b232df66a560b97751c73f3c6ff87cb978d5..d6459fd9d7875d4309f409c939556b5d631790c3 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4414,7 +4414,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 +4469,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 +4929,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 +4951,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 +4975,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 +5250,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 @@ -6210,7 +6215,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; } @@ -10413,7 +10419,7 @@ static void DiagnoseNarrowingInInitList(Sema &S, : diag::warn_init_list_type_narrowing) << PostInit->getSourceRange() << PreNarrowingType.getLocalUnqualifiedType() - << EntityType.getLocalUnqualifiedType(); + << EntityType.getNonReferenceType().getLocalUnqualifiedType(); break; case NK_Constant_Narrowing: @@ -10424,7 +10430,7 @@ static void DiagnoseNarrowingInInitList(Sema &S, : diag::warn_init_list_constant_narrowing) << PostInit->getSourceRange() << ConstantValue.getAsString(S.getASTContext(), ConstantType) - << EntityType.getLocalUnqualifiedType(); + << EntityType.getNonReferenceType().getLocalUnqualifiedType(); break; case NK_Variable_Narrowing: @@ -10435,7 +10441,7 @@ static void DiagnoseNarrowingInInitList(Sema &S, : diag::warn_init_list_variable_narrowing) << PostInit->getSourceRange() << PreNarrowingType.getLocalUnqualifiedType() - << EntityType.getLocalUnqualifiedType(); + << EntityType.getNonReferenceType().getLocalUnqualifiedType(); break; } diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index 9282ceb8dee03de050315306ade7710f0f40f97d..db0cbd5ec6d6ca6c9efe0ebe8b7943bf21844dec 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; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index e400f248d15aa3497b9513603646803f1fb961cb..3826994ef2126cee9a93d3f3580e1ea710ad17d2 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -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..e4642e4da016a44d3c770a178f48c56784ebd2d6 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, @@ -386,7 +386,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 +403,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/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/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp index bd6655cc1e3fa352daf2e3a2145f5a8357cd36b2..fedc6db3723aac815aba0f6c1e60376868a53b7c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -1045,8 +1045,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..afc5e6b48008d869d0d1077df33f04abcc1c8f24 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -140,7 +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_")) + if (Name.starts_with("__builtin_")) Name = Name.substr(10); // Set the evaluation function by switching on the callee name. @@ -763,7 +763,7 @@ void WalkAST::checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE, enum { DEPR_ONLY = -1, UNKNOWN_CALL = -2 }; StringRef Name = FD->getIdentifier()->getName(); - if (Name.startswith("__builtin_")) + if (Name.starts_with("__builtin_")) Name = Name.substr(10); int ArgIndex = 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/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/LocalizationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp index b77e9bf09a33204c57dd52275b3f129bb1299a39..70f911fc66abca8625a384f97e28a7568d80bf32 100644 --- a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp @@ -817,9 +817,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/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/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/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/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/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..bb9f7dc7e7e3d439f97608d50eee874bdec57180 100644 --- a/clang/lib/Support/RISCVVIntrinsicUtils.cpp +++ b/clang/lib/Support/RISCVVIntrinsicUtils.cpp @@ -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(')'); 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..52799f16fab2a99b1dc28ad1fd57e602416f080e 100644 --- a/clang/lib/Tooling/Refactoring/Lookup.cpp +++ b/clang/lib/Tooling/Refactoring/Lookup.cpp @@ -98,7 +98,7 @@ static StringRef getBestNamespaceSubstr(const DeclContext *DeclA, // from NewName if it has an identical prefix. std::string NS = "::" + cast(DeclA)->getQualifiedNameAsString() + "::"; - if (NewName.startswith(NS)) + if (NewName.starts_with(NS)) return NewName.substr(NS.size()); // No match yet. Strip of a namespace from the end of the chain and try @@ -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..33bfa8d3d81f1e3da6f127259c305ac1f98e1312 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -255,7 +255,7 @@ llvm::Expected getAbsolutePath(llvm::vfs::FileSystem &FS, StringRef File) { StringRef RelativePath(File); // FIXME: Should '.\\' be accepted on Win32? - if (RelativePath.startswith("./")) { + if (RelativePath.starts_with("./")) { RelativePath = RelativePath.substr(strlen("./")); } @@ -294,9 +294,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 +507,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/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/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/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/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/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/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-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_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_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_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-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_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_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_qcvtn.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_qcvtn.c new file mode 100644 index 0000000000000000000000000000000000000000..be7ec719edea553629e262a3e1a9f7c2c8c689d1 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_qcvtn.c @@ -0,0 +1,78 @@ +// 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 -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 -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 -D__SVE_OVERLOADED_FORMS -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 -D__SVE_OVERLOADED_FORMS -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 -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 + +// 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); +} 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_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/arm-vector_type-params-returns.c b/clang/test/CodeGen/arm-vector_type-params-returns.c new file mode 100644 index 0000000000000000000000000000000000000000..14c3512ab81a9fa6069ff6fce339b7e4a45e09e2 --- /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 <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 <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 <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 <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 <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 <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 <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 <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 <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 <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 <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 <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/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-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/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..a29b500e80bd50be8ac2cbb916e5211c269af72e 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"))); @@ -44,9 +52,13 @@ void* goo_ifunc(void) { // CHECK: call void @goo() // SAN: define internal nonnull ptr @foo_ifunc() #[[#FOO_IFUNC:]] { +// MACSAN: define internal nonnull ptr @foo_ifunc() #[[#FOO_IFUNC:]] { // SAN: define dso_local noalias ptr @goo_ifunc() #[[#GOO_IFUNC:]] { +// MACSAN: define noalias 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/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/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/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/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/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/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/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/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..d7fa7c9854a48f09337aaf88a22ed56cf91005e3 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 @@ -178,7 +178,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 diff --git a/clang/test/Headers/wasm.c b/clang/test/Headers/wasm.c index 9643cafc1ce6c31e13c54999f311c9a3bbe3040d..f77b95a52ee74b431f42ec36af665e2c959652d8 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]] @@ -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/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/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/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/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/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index 6fc921a8c6ee155d65d9a2d762487f6392da8194..35208b2eae8fbd329e46983149179eca73f98bd1 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -1056,12 +1056,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 \ 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..41cd3c75976383aa63361a73e3ee7cefdc76a346 100644 --- a/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_imm.cpp +++ b/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_imm.cpp @@ -185,3 +185,8 @@ 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]}} +} 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/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/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..2c7533ed88f3bbe7ed53d5efeb24c785f4448087 --- /dev/null +++ b/clang/test/SemaCXX/GH63151.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + + +struct A { A(const unsigned &x) {} }; + +void foo(int p) { + A a { -1 }; // expected-error {{constant expression evaluates to -1 which cannot be narrowed to type 'unsigned int'}} + A b { 0 }; + A c { p }; // expected-error {{non-constant-expression cannot be narrowed from type 'int' to 'unsigned int' in initializer list}} + A d { 0.5 }; // expected-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/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/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/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..b9b287127015fd920d66e7097b331a843cb6166a 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -234,7 +234,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..0623ae69fe01ed3feb583a4b5c021516a101ff36 100644 --- a/clang/tools/libclang/CIndexer.cpp +++ b/clang/tools/libclang/CIndexer.cpp @@ -17,6 +17,7 @@ #include "clang/Driver/Driver.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include "llvm/Config/config.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MD5.h" #include "llvm/Support/Path.h" @@ -125,21 +126,28 @@ const std::string &CIndexer::getClangResourcesPath() { #elif defined(_AIX) getClangResourcesPathImplAIX(LibClangPath); #else + bool PathFound = false; +#if defined(HAVE_DLFCN_H) && defined(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/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/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/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/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 24b2fd599dc39733911c56a2a7cf64d0ffb8a189..0e08723aa9e9470dcfcbd03ce5714dc34678c9df 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -4571,6 +4571,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; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 65b1f0f4b57659870048ca86e2e00d863402afae..8e6935319b2f3d6da5b40a0d7b2d3bfaddc71b0d 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) { 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/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/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/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/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp index b8a1fb4bab0f499d74cc1e0c2cf9128c32d8754d..311c6b09dc790135cc774aaf15ac0be784cc5c63 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"; @@ -1694,6 +1708,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 +1799,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 +1818,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/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_posix.cpp b/compiler-rt/lib/asan/asan_posix.cpp index e1f66641617cc14b4336ccc25d012ff1194d5772..a5b87b7fbf1b5ab6ab14f31960756d26067fb6e8 100644 --- a/compiler-rt/lib/asan/asan_posix.cpp +++ b/compiler-rt/lib/asan/asan_posix.cpp @@ -148,6 +148,33 @@ void PlatformTSDDtor(void *tsd) { } #endif +void InstallAtForkHandler() { +# if SANITIZER_SOLARIS || SANITIZER_NETBSD || SANITIZER_APPLE + return; // FIXME: Implement FutexWait. +# endif + auto before = []() { + if (CAN_SANITIZE_LEAKS) { + __lsan::LockGlobal(); + } + // `_lsan` functions defined regardless of `CAN_SANITIZE_LEAKS` and lock the + // stuff we need. + __lsan::LockThreads(); + __lsan::LockAllocator(); + StackDepotLockAll(); + }; + auto after = []() { + StackDepotUnlockAll(); + // `_lsan` functions defined regardless of `CAN_SANITIZE_LEAKS` and unlock + // the stuff we need. + __lsan::UnlockAllocator(); + __lsan::UnlockThreads(); + if (CAN_SANITIZE_LEAKS) { + __lsan::UnlockGlobal(); + } + }; + pthread_atfork(before, after, after); +} + void InstallAtExitCheckLeaks() { if (CAN_SANITIZE_LEAKS) { if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) { 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_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/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..3271a955e7ed102de886e750c631a62597f9f555 100644 --- a/compiler-rt/lib/hwasan/hwasan_linux.cpp +++ b/compiler-rt/lib/hwasan/hwasan_linux.cpp @@ -523,12 +523,24 @@ uptr TagMemoryAligned(uptr p, uptr size, tag_t tag) { void HwasanInstallAtForkHandler() { auto before = []() { - HwasanAllocatorLock(); + if (CAN_SANITIZE_LEAKS) { + __lsan::LockGlobal(); + } + // `_lsan` functions defined regardless of `CAN_SANITIZE_LEAKS` and lock the + // stuff we need. + __lsan::LockThreads(); + __lsan::LockAllocator(); StackDepotLockAll(); }; auto after = []() { StackDepotUnlockAll(); - HwasanAllocatorUnlock(); + // `_lsan` functions defined regardless of `CAN_SANITIZE_LEAKS` and unlock + // the stuff we need. + __lsan::UnlockAllocator(); + __lsan::UnlockThreads(); + if (CAN_SANITIZE_LEAKS) { + __lsan::UnlockGlobal(); + } }; pthread_atfork(before, after, after); } 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..4bfadf1ef809c36335e6ecd7e7295ef51707daf1 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,25 @@ void InstallAtExitCheckLeaks() { Atexit(DoLeakCheck); } +void InstallAtForkHandler() { +# if SANITIZER_SOLARIS || SANITIZER_NETBSD || SANITIZER_APPLE + return; // FIXME: Implement FutexWait. +# endif + auto before = []() { + LockGlobal(); + LockThreads(); + LockAllocator(); + StackDepotLockAll(); + }; + auto after = []() { + StackDepotUnlockAll(); + UnlockAllocator(); + UnlockThreads(); + UnlockGlobal(); + }; + pthread_atfork(before, after, after); +} + } // namespace __lsan #endif // SANITIZER_POSIX 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_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..04af6f4b27ac8921c2fd52a9b6b36a0f25573366 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 { @@ -256,6 +258,22 @@ void MsanTSDDtor(void *tsd) { } #endif +void InstallAtForkHandler() { + auto before = []() { + // Usually we lock ThreadRegistry, but msan does not have one. + LockAllocator(); + StackDepotLockAll(); + ChainedOriginDepotLockAll(); + }; + auto after = []() { + ChainedOriginDepotUnlockAll(); + StackDepotUnlockAll(); + UnlockAllocator(); + // Usually we unlock ThreadRegistry, but msan does not have one. + }; + pthread_atfork(before, after, after); +} + } // namespace __msan #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD 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..9070b8a606eb5446528e100208a7b5dbd37c5521 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. */ 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/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 80f86ca98ed9cd98804a9ae7ffe09f7b6390bae2..da0ad8eb42ab4ab275dcf60c9457213530687ac3 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -1380,6 +1380,20 @@ TSAN_INTERCEPTOR(int, pthread_mutex_unlock, void *m) { return res; } +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; +} + #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 +2916,7 @@ void InitializeInterceptors() { TSAN_INTERCEPT(pthread_mutex_trylock); TSAN_INTERCEPT(pthread_mutex_timedlock); TSAN_INTERCEPT(pthread_mutex_unlock); + TSAN_INTERCEPT(pthread_mutex_clocklock); #if SANITIZER_GLIBC # if !__GLIBC_PREREQ(2, 34) TSAN_INTERCEPT(__pthread_mutex_lock); 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/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/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/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..dbca0b420391819811e9647ec242f289b3889a87 --- /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 +// UNSUPPORTED: darwin +#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 \ No newline at end of file diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h index 980fde881373249d9127c8e965e329ccea964194..b91303387f3d710d6bf4159f0ae433bca7cf261c 100644 --- a/flang/include/flang/Lower/AbstractConverter.h +++ b/flang/include/flang/Lower/AbstractConverter.h @@ -280,6 +280,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/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/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h index 2abcc6547bbabf6343272695b7bd257f9fa38742..a79c67dfe6de862be6bd704d445e1757cd0781f8 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; } 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/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..4ce6171801d2c964f9c695dc680469b859647fe7 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -1085,7 +1085,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 +1096,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 +1128,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 +1141,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 +1162,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 +1213,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..61393d2c9d64c46291f1389637ddf00f10ca693e 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -839,6 +839,11 @@ public: } } + void genEval(Fortran::lower::pft::Evaluation &eval, + bool unstructuredContext) override final { + genFIR(eval, unstructuredContext); + } + //===--------------------------------------------------------------------===// // Utility methods //===--------------------------------------------------------------------===// @@ -2416,48 +2421,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 +2438,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); } @@ -4238,15 +4201,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 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..a60ca92a8733e360071b4a8a4eae1cc69f70ab06 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); diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index e2abed1b9f4f67590b2fbc7e6fb4c4cda90a7543..75432db33a790d30cbb8fdaef6be7177436632b4 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(); } @@ -265,14 +283,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 +311,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); } } @@ -747,20 +770,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 +795,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 +1347,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 +1362,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( diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index eeba87fcd151169ac0f2abdf5ea2b16ffa6dd1b1..9213cff95d3f112b046aa41cb7d4a942bccefd9c 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" @@ -1793,27 +1794,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)); } @@ -2117,12 +2119,8 @@ 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 @@ -2658,20 +2656,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; @@ -3388,27 +3386,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 +3432,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 +3470,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/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 45c75fc5dd28bc0534daefff90fd721fde6dee92..ff5dbff04360a034d4ea28eef7eda31c83e5de3d 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -1418,13 +1418,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 +1433,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(); 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..d99245f0a012e6664b3265a12729dd6a31665418 100644 --- a/flang/lib/Optimizer/Support/InternalNames.cpp +++ b/flang/lib/Optimizer/Support/InternalNames.cpp @@ -240,7 +240,7 @@ llvm::StringRef fir::NameUniquer::doProgramEntry() { std::pair fir::NameUniquer::deconstruct(llvm::StringRef uniq) { - if (uniq.startswith("_Q")) { + if (uniq.starts_with("_Q")) { llvm::SmallVector modules; llvm::SmallVector procs; std::int64_t blockId = 0; diff --git a/flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp b/flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp index 3eddb9e61ae3b3df4aad127678795b2eff8bc03c..c89ee6d5e20391e904d9177570a8b50deca8a8dc 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,8 +1157,8 @@ 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(); @@ -1217,11 +1224,11 @@ void SimplifyIntrinsicsPass::simplifyMinlocReduction( 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 = @@ -1279,11 +1286,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 +1357,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/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/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/test/Driver/no-duplicate-main.f90 b/flang/test/Driver/no-duplicate-main.f90 index 12d5e46247bad277d55262b6d503d00c3443d5f3..b884e7ecd7f12ad5cef785d30997e9ec66f97143 100644 --- a/flang/test/Driver/no-duplicate-main.f90 +++ b/flang/test/Driver/no-duplicate-main.f90 @@ -1,4 +1,4 @@ -! UNSUPPORTED: system-windows +! UNSUPPORTED: system-windows, system-darwin ! RUN: %flang -x ir -o %t.c-object -c %S/Inputs/no_duplicate_main.ll ! RUN: %flang -o %t -c %s diff --git a/flang/test/Fir/commute.fir b/flang/test/Fir/commute.fir index b39fe48145b3f3eabb298b9abfa9ced174049cf1..be25fd61953debc2c2ba8b0b9957479228666304 100644 --- a/flang/test/Fir/commute.fir +++ b/flang/test/Fir/commute.fir @@ -1,7 +1,4 @@ // RUN: fir-opt %s | tco | FileCheck %s -// -// XFAIL:* -// See: https://github.com/llvm/llvm-project/issues/63784 // CHECK-LABEL: define i32 @f1(i32 %0, i32 %1) func.func @f1(%a : i32, %b : i32) -> i32 { diff --git a/flang/test/HLFIR/count-lowering-default-int-kinds.fir b/flang/test/HLFIR/count-lowering-default-int-kinds.fir index b34639a0aa0af08760e4963e33465f3708677c16..ea66c435e6a8a7d78d74772c2f27d573697e927b 100644 --- a/flang/test/HLFIR/count-lowering-default-int-kinds.fir +++ b/flang/test/HLFIR/count-lowering-default-int-kinds.fir @@ -8,9 +8,8 @@ module attributes {fir.defaultkind = "a1c4d8i8l4r4", fir.kindmap = ""} { } } // CHECK-LABEL: func.func @test_i8 -// CHECK: %[[KIND:.*]] = arith.constant 8 : index -// CHECK: %[[KIND_ARG:.*]] = fir.convert %[[KIND]] : (index) -> i32 -// CHECK: fir.call @_FortranACountDim(%{{.*}}, %{{.*}}, %{{.*}}, %[[KIND_ARG]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32) -> none +// CHECK: %[[KIND:.*]] = arith.constant 8 : i32 +// CHECK: fir.call @_FortranACountDim(%{{.*}}, %{{.*}}, %{{.*}}, %[[KIND]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32) -> none module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = ""} { func.func @test_i4(%arg0: !fir.box>> {fir.bindc_name = "x"}, %arg1: i64) { @@ -19,9 +18,8 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = ""} { } } // CHECK-LABEL: func.func @test_i4 -// CHECK: %[[KIND:.*]] = arith.constant 4 : index -// CHECK: %[[KIND_ARG:.*]] = fir.convert %[[KIND]] : (index) -> i32 -// CHECK: fir.call @_FortranACountDim(%{{.*}}, %{{.*}}, %{{.*}}, %[[KIND_ARG]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32) -> none +// CHECK: %[[KIND:.*]] = arith.constant 4 : i32 +// CHECK: fir.call @_FortranACountDim(%{{.*}}, %{{.*}}, %{{.*}}, %[[KIND]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32) -> none module attributes {fir.defaultkind = "a1c4d8i2l4r4", fir.kindmap = ""} { func.func @test_i2(%arg0: !fir.box>> {fir.bindc_name = "x"}, %arg1: i64) { @@ -30,9 +28,8 @@ module attributes {fir.defaultkind = "a1c4d8i2l4r4", fir.kindmap = ""} { } } // CHECK-LABEL: func.func @test_i2 -// CHECK: %[[KIND:.*]] = arith.constant 2 : index -// CHECK: %[[KIND_ARG:.*]] = fir.convert %[[KIND]] : (index) -> i32 -// CHECK: fir.call @_FortranACountDim(%{{.*}}, %{{.*}}, %{{.*}}, %[[KIND_ARG]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32) -> none +// CHECK: %[[KIND:.*]] = arith.constant 2 : i32 +// CHECK: fir.call @_FortranACountDim(%{{.*}}, %{{.*}}, %{{.*}}, %[[KIND]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32) -> none module attributes {fir.defaultkind = "a1c4d8i1l4r4", fir.kindmap = ""} { func.func @test_i1(%arg0: !fir.box>> {fir.bindc_name = "x"}, %arg1: i64) { @@ -41,7 +38,5 @@ module attributes {fir.defaultkind = "a1c4d8i1l4r4", fir.kindmap = ""} { } } // CHECK-LABEL: func.func @test_i1 -// CHECK: arith.constant 1 : index -// CHECK: %[[KIND:.*]] = arith.constant 1 : index -// CHECK: %[[KIND_ARG:.*]] = fir.convert %[[KIND]] : (index) -> i32 -// CHECK: fir.call @_FortranACountDim(%{{.*}}, %{{.*}}, %{{.*}}, %[[KIND_ARG]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32) -> none +// CHECK: %[[KIND:.*]] = arith.constant 1 : i32 +// CHECK: fir.call @_FortranACountDim(%{{.*}}, %{{.*}}, %{{.*}}, %[[KIND]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32) -> none diff --git a/flang/test/HLFIR/count-lowering.fir b/flang/test/HLFIR/count-lowering.fir index b391a651a6ae7fd62f6171e330b505e0fefc7a80..da0f250dceef350561a8da17f483d02f0bd4f9e4 100644 --- a/flang/test/HLFIR/count-lowering.fir +++ b/flang/test/HLFIR/count-lowering.fir @@ -34,12 +34,12 @@ func.func @_QPcount2(%arg0: !fir.box>> {fir.bindc // CHECK: %[[ARG0:.*]]: !fir.box>> // CHECK: %[[ARG1:.*]]: !fir.box // CHECK: %[[ARG2:.*]]: !fir.ref +// CHECK-DAG: %[[KIND:.*]] = arith.constant 4 : i32 // CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG0]] // CHECK-DAG: %[[DIM_VAR:.*]]:2 = hlfir.declare %[[ARG2]] // CHECK-DAG: %[[RES:.*]]:2 = hlfir.declare %[[ARG1]] // CHECK-DAG: %[[RET_BOX:.*]] = fir.alloca !fir.box>> -// CHECK-DAG: %[[KIND:.*]] = arith.constant 4 : index // CHECK-DAG: %[[RET_ADDR:.*]] = fir.zero_bits !fir.heap> // CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index // CHECK-DAG: %[[RET_SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1> @@ -49,9 +49,8 @@ func.func @_QPcount2(%arg0: !fir.box>> {fir.bindc // CHECK-DAG: %[[DIM:.*]] = fir.load %[[DIM_VAR]]#0 : !fir.ref // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]]#1 -// CHECK-DAG: %[[KIND_ARG:.*]] = fir.convert %[[KIND]] : (index) -> i32 -// CHECK: %[[NONE:.*]] = fir.call @_FortranACountDim(%[[RET_ARG]], %[[MASK_ARG]], %[[DIM]], %[[KIND_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]]) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32) -> none +// CHECK: %[[NONE:.*]] = fir.call @_FortranACountDim(%[[RET_ARG]], %[[MASK_ARG]], %[[DIM]], %[[KIND]], %[[LOC_STR:.*]], %[[LOC_N:.*]]) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32) -> none // CHECK: %[[RET:.*]] = fir.load %[[RET_BOX]] // CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[RET]] // CHECK-NEXT: %[[ADDR:.*]] = fir.box_addr %[[RET]] @@ -82,7 +81,7 @@ func.func @_QPcount3(%arg0: !fir.ref> {fir.bindc_name = "s"}) // CHECK-LABEL: func.func @_QPcount3( // CHECK: %[[ARG0:.*]]: !fir.ref> // CHECK-DAG: %[[RET_BOX:.*]] = fir.alloca !fir.box>> -// CHECK-DAG: %[[KIND:.*]] = arith.constant 4 : index +// CHECK-DAG: %[[KIND:.*]] = arith.constant 4 : i32 // CHECK-DAG: %[[RET_ADDR:.*]] = fir.zero_bits !fir.heap> // CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index // CHECK-DAG: %[[RET_SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1> @@ -98,9 +97,8 @@ func.func @_QPcount3(%arg0: !fir.ref> {fir.bindc_name = "s"}) // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK_BOX]] : (!fir.box>>) -> !fir.box -// CHECK-DAG: %[[KIND_ARG:.*]] = fir.convert %[[KIND]] : (index) -> i32 -// CHECK: %[[NONE:.*]] = fir.call @_FortranACountDim(%[[RET_ARG]], %[[MASK_ARG]], %[[DIM]], %[[KIND_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]]) +// CHECK: %[[NONE:.*]] = fir.call @_FortranACountDim(%[[RET_ARG]], %[[MASK_ARG]], %[[DIM]], %[[KIND]], %[[LOC_STR:.*]], %[[LOC_N:.*]]) // CHECK: %[[RET:.*]] = fir.load %[[RET_BOX]] // CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[RET]] // CHECK-NEXT: %[[ADDR:.*]] = fir.box_addr %[[RET]] @@ -117,9 +115,8 @@ func.func @_QPcount4(%arg0: !fir.box>> {fir.bindc %0:2 = hlfir.declare %arg0 {uniq_name = "_QFcount4Ea"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFcount4Ed"} : (!fir.ref) -> (!fir.ref, !fir.ref) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFcount4Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %c8_i32 = arith.constant 8 : i32 %3 = fir.load %1#0 : !fir.ref - %4 = hlfir.count %0#0 dim %3 kind %c8_i32 {fastmath = #arith.fastmath} : (!fir.box>>, i32, i32) -> !hlfir.expr + %4 = hlfir.count %0#0 dim %3 {fastmath = #arith.fastmath} : (!fir.box>>, i32) -> !hlfir.expr %5 = hlfir.shape_of %4 : (!hlfir.expr) -> !fir.shape<1> %6 = hlfir.elemental %5 : (!fir.shape<1>) -> !hlfir.expr { ^bb0(%arg3: index): diff --git a/flang/test/HLFIR/invalid.fir b/flang/test/HLFIR/invalid.fir index ce0d728749b960bcb9515f59d936895c7c942d1c..56f74d8bf29e68a0d31345db48da88a5cfec76b4 100644 --- a/flang/test/HLFIR/invalid.fir +++ b/flang/test/HLFIR/invalid.fir @@ -614,6 +614,71 @@ func.func @bad_minloc11(%arg0: !hlfir.expr>, %arg1: i32, %arg %0 = hlfir.minloc %arg0 dim %arg1 mask %arg2 : (!hlfir.expr>, i32, !fir.box>) -> !hlfir.expr } +// ----- +func.func @bad_maxloc1(%arg0: !hlfir.expr, %arg1: i32, %arg2: !fir.box>) { + // expected-error@+1 {{'hlfir.maxloc' op result must be scalar integer}} + %0 = hlfir.maxloc %arg0 dim %arg1 mask %arg2 : (!hlfir.expr, i32, !fir.box>) -> f32 +} + +// ----- +func.func @bad_maxloc2(%arg0: !hlfir.expr, %arg1: i32, %arg2: !fir.box>>) { + // expected-warning@+1 {{MASK must be conformable to ARRAY}} + %0 = hlfir.maxloc %arg0 dim %arg1 mask %arg2 : (!hlfir.expr, i32, !fir.box>>) -> !hlfir.expr +} + +// ----- +func.func @bad_maxloc3(%arg0: !hlfir.expr, %arg1: i32, %arg2: !fir.box>>) { + // expected-warning@+1 {{MASK must be conformable to ARRAY}} + %0 = hlfir.maxloc %arg0 dim %arg1 mask %arg2 : (!hlfir.expr, i32, !fir.box>>) -> !hlfir.expr +} + +// ----- +func.func @bad_maxloc4(%arg0: !hlfir.expr, %arg1: i32, %arg2: !fir.box>) { + // expected-error@+1 {{'hlfir.maxloc' op result rank must be one less than ARRAY}} + %0 = hlfir.maxloc %arg0 dim %arg1 mask %arg2 : (!hlfir.expr, i32, !fir.box>) -> !hlfir.expr +} + +// ----- +func.func @bad_maxloc5(%arg0: !hlfir.expr, %arg1: i32, %arg2: !fir.box>) { + // expected-error@+1 {{'hlfir.maxloc' op result must be scalar integer}} + %0 = hlfir.maxloc %arg0 dim %arg1 mask %arg2 : (!hlfir.expr, i32, !fir.box>) -> !fir.logical<4> +} + +// ----- +func.func @bad_maxloc6(%arg0: !hlfir.expr, %arg1: i32){ + // expected-error@+1 {{'hlfir.maxloc' op result must be an array}} + %0 = hlfir.maxloc %arg0 dim %arg1 : (!hlfir.expr, i32) -> !hlfir.expr +} + +// ----- +func.func @bad_maxloc7(%arg0: !hlfir.expr){ + // expected-error@+1 {{'hlfir.maxloc' op result must be of numerical expr type}} + %0 = hlfir.maxloc %arg0 : (!hlfir.expr) -> i32 +} + +// ----- +func.func @bad_maxloc8(%arg0: !hlfir.expr){ + // expected-error@+1 {{'hlfir.maxloc' op result must have integer elements}} + %0 = hlfir.maxloc %arg0 : (!hlfir.expr) -> !hlfir.expr +} + +// ----- +func.func @bad_maxloc9(%arg0: !hlfir.expr>, %arg1: i32, %arg2: !fir.box>>) { + // expected-warning@+1 {{MASK must be conformable to ARRAY}} + %0 = hlfir.maxloc %arg0 dim %arg1 mask %arg2 : (!hlfir.expr>, i32, !fir.box>>) -> !hlfir.expr> +} + +// ----- +func.func @bad_maxloc10(%arg0: !hlfir.expr>, %arg1: i32, %arg2: !fir.box>>) { + // expected-warning@+1 {{MASK must be conformable to ARRAY}} + %0 = hlfir.maxloc %arg0 dim %arg1 mask %arg2 : (!hlfir.expr>, i32, !fir.box>>) -> !hlfir.expr> +} + +// ----- +func.func @bad_maxloc11(%arg0: !hlfir.expr>, %arg1: i32, %arg2: !fir.box>) { + // expected-error@+1 {{'hlfir.maxloc' op result rank must be one less than ARRAY}} + %0 = hlfir.maxloc %arg0 dim %arg1 mask %arg2 : (!hlfir.expr>, i32, !fir.box>) -> !hlfir.expr +} // ----- diff --git a/flang/test/HLFIR/maxloc-lowering.fir b/flang/test/HLFIR/maxloc-lowering.fir new file mode 100644 index 0000000000000000000000000000000000000000..9e52a074a6e285343c30167d0587f0533b23a36e --- /dev/null +++ b/flang/test/HLFIR/maxloc-lowering.fir @@ -0,0 +1,329 @@ +// Test hlfir.maxloc operation lowering to fir runtime call +// RUN: fir-opt %s -lower-hlfir-intrinsics | FileCheck %s + +// simple one argument maxloc +func.func @_QPmaxloc1(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxloc1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc1Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2 = hlfir.maxloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr + hlfir.assign %2 to %1#0 : !hlfir.expr, !fir.box> + hlfir.destroy %2 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @_QPmaxloc1( +// CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"} +// CHECK: %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"} +// CHECK-NEXT: %[[V0:.*]] = fir.alloca !fir.box>> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFmaxloc1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QFmaxloc1Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %c4_i32 = arith.constant 4 : i32 +// CHECK-NEXT: %[[V3:.*]] = fir.absent !fir.box +// CHECK-NEXT: %false = arith.constant false +// CHECK-NEXT: %[[V4:.*]] = fir.zero_bits !fir.heap> +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %[[V5:.*]] = fir.shape %c0 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V6:.*]] = fir.embox %[[V4]](%[[V5]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK-NEXT: fir.store %[[V6]] to %[[V0]] : !fir.ref>>> +// CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> +// CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[V12:.*]] = fir.convert %[[V3]] : (!fir.box) -> !fir.box +// CHECK-NEXT: %[[V13:.*]] = fir.call @_FortranAMaxlocInteger4(%[[V8]], %[[V9]], %c4_i32, {{.*}}, {{.*}}, %[[V12]], %false) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> none +// CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> +// CHECK-NEXT: %c0_0 = arith.constant 0 : index +// CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %c0_0 : (!fir.box>>, index) -> (index, index, index) +// CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> +// CHECK-NEXT: %[[V17:.*]] = fir.shape_shift %[[V15]]#0, %[[V15]]#1 : (index, index) -> !fir.shapeshift<1> +// CHECK-NEXT: %[[V18:.*]]:2 = hlfir.declare %[[V16]](%[[V17]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.heap>, !fir.shapeshift<1>) -> (!fir.box>, !fir.heap>) +// CHECK-NEXT: %true = arith.constant true +// CHECK-NEXT: %[[V19:.*]] = hlfir.as_expr %[[V18]]#0 move %true : (!fir.box>, i1) -> !hlfir.expr +// CHECK-NEXT: hlfir.assign %[[V19]] to %[[V2]]#0 : !hlfir.expr, !fir.box> +// CHECK-NEXT: hlfir.destroy %[[V19]] : !hlfir.expr + + +// maxloc with a dim +func.func @_QPmaxloc2(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}, %arg2: !fir.ref {fir.bindc_name = "d"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxloc2Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFmaxloc2Ed"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc2Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %3 = fir.load %1#0 : !fir.ref + %4 = hlfir.maxloc %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr + hlfir.assign %4 to %2#0 : !hlfir.expr, !fir.box> + hlfir.destroy %4 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @_QPmaxloc2( +// CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"} +// CHECK: %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"} +// CHECK: %[[ARG2:.*]]: !fir.ref +// CHECK-NEXT: %[[V0:.*]] = fir.alloca !fir.box>> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFmaxloc2Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %[[ARG2]] {uniq_name = "_QFmaxloc2Ed"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QFmaxloc2Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V4:.*]] = fir.load %[[V2]]#0 : !fir.ref +// CHECK-NEXT: %c4_i32 = arith.constant 4 : i32 +// CHECK-NEXT: %[[V5:.*]] = fir.convert %[[V4]] : (index) -> i32 +// CHECK-NEXT: %[[V6:.*]] = fir.absent !fir.box +// CHECK-NEXT: %false = arith.constant false +// CHECK-NEXT: %[[V7:.*]] = fir.zero_bits !fir.heap> +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %[[V8:.*]] = fir.shape %c0 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V9:.*]] = fir.embox %[[V7]](%[[V8]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK-NEXT: fir.store %[[V9]] to %[[V0]] : !fir.ref>>> +// CHECK: %[[V11:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> +// CHECK-NEXT: %[[V12:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[V15:.*]] = fir.convert %[[V6]] : (!fir.box) -> !fir.box +// CHECK-NEXT: %[[V16:.*]] = fir.call @_FortranAMaxlocDim(%[[V11]], %[[V12]], %c4_i32, %[[V5]], {{.*}}, {{.*}}, %[[V15]], %false) fastmath : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> none +// CHECK-NEXT: %[[V17:.*]] = fir.load %[[V0]] : !fir.ref>>> +// CHECK-NEXT: %c0_0 = arith.constant 0 : index +// CHECK-NEXT: %[[V18:.*]]:3 = fir.box_dims %[[V17]], %c0_0 : (!fir.box>>, index) -> (index, index, index) +// CHECK-NEXT: %[[V19:.*]] = fir.box_addr %[[V17]] : (!fir.box>>) -> !fir.heap> +// CHECK-NEXT: %[[V20:.*]] = fir.shape_shift %[[V18]]#0, %[[V18]]#1 : (index, index) -> !fir.shapeshift<1> +// CHECK-NEXT: %[[V21:.*]]:2 = hlfir.declare %[[V19]](%[[V20]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.heap>, !fir.shapeshift<1>) -> (!fir.box>, !fir.heap>) +// CHECK-NEXT: %true = arith.constant true +// CHECK-NEXT: %[[V22:.*]] = hlfir.as_expr %[[V21]]#0 move %true : (!fir.box>, i1) -> !hlfir.expr +// CHECK-NEXT: hlfir.assign %[[V22]] to %[[V3]]#0 : !hlfir.expr, !fir.box> +// CHECK-NEXT: hlfir.destroy %[[V22]] : !hlfir.expr +// CHECK-NEXT: return + + +// maxloc with scalar mask +func.func @_QPmaxloc3(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}, %arg2: !fir.ref> {fir.bindc_name = "m"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxloc3Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFmaxloc3Em"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc3Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %3 = hlfir.maxloc %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> !hlfir.expr + hlfir.assign %3 to %2#0 : !hlfir.expr, !fir.box> + hlfir.destroy %3 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @_QPmaxloc3( +// CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"} +// CHECK: %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"} +// CHECK: %[[ARG2:.*]]: !fir.ref> +// CHECK-NEXT: %[[V0:.*]] = fir.alloca !fir.box>> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFmaxloc3Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %[[ARG2]] {uniq_name = "_QFmaxloc3Em"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +// CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QFmaxloc3Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %c4_i32 = arith.constant 4 : i32 +// CHECK-NEXT: %[[V4:.*]] = fir.embox %[[V2]]#1 : (!fir.ref>) -> !fir.box> +// CHECK-NEXT: %false = arith.constant false +// CHECK-NEXT: %[[V5:.*]] = fir.zero_bits !fir.heap> +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %[[V6:.*]] = fir.shape %c0 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V7:.*]] = fir.embox %[[V5]](%[[V6]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK-NEXT: fir.store %[[V7]] to %[[V0]] : !fir.ref>>> +// CHECK: %[[V9:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> +// CHECK-NEXT: %[[V10:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[V13:.*]] = fir.convert %[[V4]] : (!fir.box>) -> !fir.box +// CHECK-NEXT: %[[V14:.*]] = fir.call @_FortranAMaxlocInteger4(%[[V9]], %[[V10]], %c4_i32, {{.*}}, {{.*}}, %[[V13]], %false) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> none +// CHECK-NEXT: %[[V15:.*]] = fir.load %[[V0]] : !fir.ref>>> +// CHECK-NEXT: %c0_0 = arith.constant 0 : index +// CHECK-NEXT: %[[V16:.*]]:3 = fir.box_dims %[[V15]], %c0_0 : (!fir.box>>, index) -> (index, index, index) +// CHECK-NEXT: %[[V17:.*]] = fir.box_addr %[[V15]] : (!fir.box>>) -> !fir.heap> +// CHECK-NEXT: %[[V18:.*]] = fir.shape_shift %[[V16]]#0, %[[V16]]#1 : (index, index) -> !fir.shapeshift<1> +// CHECK-NEXT: %[[V19:.*]]:2 = hlfir.declare %[[V17]](%[[V18]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.heap>, !fir.shapeshift<1>) -> (!fir.box>, !fir.heap>) +// CHECK-NEXT: %true = arith.constant true +// CHECK-NEXT: %[[V20:.*]] = hlfir.as_expr %[[V19]]#0 move %true : (!fir.box>, i1) -> !hlfir.expr +// CHECK-NEXT: hlfir.assign %[[V20]] to %[[V3]]#0 : !hlfir.expr, !fir.box> +// CHECK-NEXT: hlfir.destroy %[[V20]] : !hlfir.expr +// CHECK-NEXT: return + + +// maxloc with array mask +func.func @_QPmaxloc4(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}, %arg2: !fir.box>> {fir.bindc_name = "m"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxloc4Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFmaxloc4Em"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc4Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %3 = hlfir.maxloc %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> !hlfir.expr + hlfir.assign %3 to %2#0 : !hlfir.expr, !fir.box> + hlfir.destroy %3 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @_QPmaxloc4( +// CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"} +// CHECK: %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"} +// CHECK: %[[ARG2:.*]]: !fir.box>> +// CHECK-NEXT: %[[V0:.*]] = fir.alloca !fir.box>> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFmaxloc4Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %[[ARG2]] {uniq_name = "_QFmaxloc4Em"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) +// CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QFmaxloc4Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %c4_i32 = arith.constant 4 : i32 +// CHECK-NEXT: %false = arith.constant false +// CHECK-NEXT: %[[V4:.*]] = fir.zero_bits !fir.heap> +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %[[V5:.*]] = fir.shape %c0 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V6:.*]] = fir.embox %[[V4]](%[[V5]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK-NEXT: fir.store %[[V6]] to %[[V0]] : !fir.ref>>> +// CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> +// CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[V12:.*]] = fir.convert %[[V2]]#1 : (!fir.box>>) -> !fir.box +// CHECK-NEXT: %[[V13:.*]] = fir.call @_FortranAMaxlocInteger4(%[[V8]], %[[V9]], %c4_i32, {{.*}}, {{.*}}, %[[V12]], %false) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> none +// CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> +// CHECK-NEXT: %c0_0 = arith.constant 0 : index +// CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %c0_0 : (!fir.box>>, index) -> (index, index, index) +// CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> +// CHECK-NEXT: %[[V17:.*]] = fir.shape_shift %[[V15]]#0, %[[V15]]#1 : (index, index) -> !fir.shapeshift<1> +// CHECK-NEXT: %[[V18:.*]]:2 = hlfir.declare %[[V16]](%[[V17]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.heap>, !fir.shapeshift<1>) -> (!fir.box>, !fir.heap>) +// CHECK-NEXT: %true = arith.constant true +// CHECK-NEXT: %[[V19:.*]] = hlfir.as_expr %[[V18]]#0 move %true : (!fir.box>, i1) -> !hlfir.expr +// CHECK-NEXT: hlfir.assign %[[V19]] to %[[V3]]#0 : !hlfir.expr, !fir.box> +// CHECK-NEXT: hlfir.destroy %[[V19]] : !hlfir.expr +// CHECK-NEXT: return + + +fir.global internal @_QFmaxloc5Ea : !fir.array<2x2xi32> { + %0 = fir.undefined !fir.array<2x2xi32> + %c1_i32 = arith.constant 1 : i32 + %1 = fir.insert_value %0, %c1_i32, [0 : index, 0 : index] : (!fir.array<2x2xi32>, i32) -> !fir.array<2x2xi32> + %c2_i32 = arith.constant 2 : i32 + %2 = fir.insert_value %1, %c2_i32, [1 : index, 0 : index] : (!fir.array<2x2xi32>, i32) -> !fir.array<2x2xi32> + %c3_i32 = arith.constant 3 : i32 + %3 = fir.insert_value %2, %c3_i32, [0 : index, 1 : index] : (!fir.array<2x2xi32>, i32) -> !fir.array<2x2xi32> + %c4_i32 = arith.constant 4 : i32 + %4 = fir.insert_value %3, %c4_i32, [1 : index, 1 : index] : (!fir.array<2x2xi32>, i32) -> !fir.array<2x2xi32> + %c2 = arith.constant 2 : index + %c2_0 = arith.constant 2 : index + fir.has_value %4 : !fir.array<2x2xi32> +} + +// 3 argument maxloc, using local variables +func.func @_QPmaxloc5(%arg0: !fir.ref> {fir.bindc_name = "s"}) { + %0 = fir.address_of(@_QFmaxloc5Ea) : !fir.ref> + %c2 = arith.constant 2 : index + %c2_0 = arith.constant 2 : index + %1 = fir.shape %c2, %c2_0 : (index, index) -> !fir.shape<2> + %2:2 = hlfir.declare %0(%1) {uniq_name = "_QFmaxloc5Ea"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %c2_1 = arith.constant 2 : index + %3 = fir.shape %c2_1 : (index) -> !fir.shape<1> + %4:2 = hlfir.declare %arg0(%3) {uniq_name = "_QFmaxloc5Es"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) + %c1_i32 = arith.constant 1 : i32 + %true = arith.constant true + %5 = hlfir.maxloc %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> + hlfir.assign %5 to %4#0 : !hlfir.expr<2xi32>, !fir.ref> + hlfir.destroy %5 : !hlfir.expr<2xi32> + return +} +// CHECK-LABEL: func.func @_QPmaxloc5( +// CHECK: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "s"} +// CHECK-NEXT: %[[V0:.*]] = fir.alloca !fir.box>> +// CHECK-NEXT: %[[V1:.*]] = fir.alloca !fir.logical<4> +// CHECK-NEXT: %[[V2:.*]] = fir.address_of(@_QFmaxloc5Ea) : !fir.ref> +// CHECK-NEXT: %c2 = arith.constant 2 : index +// CHECK-NEXT: %c2_0 = arith.constant 2 : index +// CHECK-NEXT: %[[V3:.*]] = fir.shape %c2, %c2_0 : (index, index) -> !fir.shape<2> +// CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %[[V2]](%[[V3]]) {uniq_name = "_QFmaxloc5Ea"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) +// CHECK-NEXT: %c2_1 = arith.constant 2 : index +// CHECK-NEXT: %[[V5:.*]] = fir.shape %c2_1 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V6:.*]]:2 = hlfir.declare %[[ARG0]](%[[V5]]) {uniq_name = "_QFmaxloc5Es"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32 +// CHECK-NEXT: %true = arith.constant true +// CHECK-NEXT: %c4_i32 = arith.constant 4 : i32 +// CHECK-NEXT: %[[V7:.*]] = fir.shape %c2, %c2_0 : (index, index) -> !fir.shape<2> +// CHECK-NEXT: %[[V8:.*]] = fir.embox %[[V4]]#1(%[[V7]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> +// CHECK-NEXT: %[[V9:.*]] = fir.convert %true : (i1) -> !fir.logical<4> +// CHECK-NEXT: fir.store %[[V9]] to %[[V1]] : !fir.ref> +// CHECK-NEXT: %[[V10:.*]] = fir.embox %[[V1]] : (!fir.ref>) -> !fir.box> +// CHECK-NEXT: %false = arith.constant false +// CHECK-NEXT: %[[V11:.*]] = fir.zero_bits !fir.heap> +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %[[V12:.*]] = fir.shape %c0 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V13:.*]] = fir.embox %[[V11]](%[[V12]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK-NEXT: fir.store %[[V13]] to %[[V0]] : !fir.ref>>> +// CHECK: %[[V15:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> +// CHECK-NEXT: %[[V16:.*]] = fir.convert %[[V8]] : (!fir.box>) -> !fir.box +// CHECK: %[[V19:.*]] = fir.convert %[[V10]] : (!fir.box>) -> !fir.box +// CHECK-NEXT: %[[V20:.*]] = fir.call @_FortranAMaxlocDim(%[[V15]], %[[V16]], %c4_i32, %c1_i32, {{.*}}, {{.*}}, %[[V19]], %false) fastmath : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> none +// CHECK-NEXT: %[[V21:.*]] = fir.load %[[V0]] : !fir.ref>>> +// CHECK-NEXT: %c0_2 = arith.constant 0 : index +// CHECK-NEXT: %[[V22:.*]]:3 = fir.box_dims %[[V21]], %c0_2 : (!fir.box>>, index) -> (index, index, index) +// CHECK-NEXT: %[[V23:.*]] = fir.box_addr %[[V21]] : (!fir.box>>) -> !fir.heap> +// CHECK-NEXT: %[[V24:.*]] = fir.shape_shift %[[V22]]#0, %[[V22]]#1 : (index, index) -> !fir.shapeshift<1> +// CHECK-NEXT: %[[V25:.*]]:2 = hlfir.declare %[[V23]](%[[V24]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.heap>, !fir.shapeshift<1>) -> (!fir.box>, !fir.heap>) +// CHECK-NEXT: %true_3 = arith.constant true +// CHECK-NEXT: %[[V26:.*]] = hlfir.as_expr %[[V25]]#0 move %true_3 : (!fir.box>, i1) -> !hlfir.expr +// CHECK-NEXT: hlfir.assign %[[V26]] to %[[V6]]#0 : !hlfir.expr, !fir.ref> +// CHECK-NEXT: hlfir.destroy %[[V26]] : !hlfir.expr +// CHECK-NEXT: return + + +// simple one argument maxloc for character +func.func @_QPmaxloc6(%arg0: !fir.box>> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxloc6Ea"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) + %1:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc4Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2 = hlfir.maxloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr + hlfir.assign %2 to %1#0 : !hlfir.expr, !fir.box> + hlfir.destroy %2 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @_QPmaxloc6( +// CHECK: %[[ARG0:.*]]: !fir.box>> {fir.bindc_name = "a"} +// CHECK: %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"} +// CHECK-NEXT: %[[V0:.*]] = fir.alloca !fir.box>> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFmaxloc6Ea"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QFmaxloc4Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %c4_i32 = arith.constant 4 : i32 +// CHECK-NEXT: %[[V3:.*]] = fir.absent !fir.box +// CHECK-NEXT: %false = arith.constant false +// CHECK-NEXT: %[[V4:.*]] = fir.zero_bits !fir.heap> +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %[[V5:.*]] = fir.shape %c0 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V6:.*]] = fir.embox %[[V4]](%[[V5]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK-NEXT: fir.store %[[V6]] to %[[V0]] : !fir.ref>>> +// CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> +// CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>>) -> !fir.box +// CHECK: %[[V12:.*]] = fir.convert %[[V3]] : (!fir.box) -> !fir.box +// CHECK-NEXT: %[[V13:.*]] = fir.call @_FortranAMaxlocCharacter(%[[V8]], %[[V9]], %c4_i32, {{.*}}, {{.*}}, %[[V12]], %false) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> none +// CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> +// CHECK-NEXT: %c0_0 = arith.constant 0 : index +// CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %c0_0 : (!fir.box>>, index) -> (index, index, index) +// CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> +// CHECK-NEXT: %[[V17:.*]] = fir.shape_shift %[[V15]]#0, %[[V15]]#1 : (index, index) -> !fir.shapeshift<1> +// CHECK-NEXT: %[[V18:.*]]:2 = hlfir.declare %[[V16]](%[[V17]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.heap>, !fir.shapeshift<1>) -> (!fir.box>, !fir.heap>) +// CHECK-NEXT: %true = arith.constant true +// CHECK-NEXT: %[[V19:.*]] = hlfir.as_expr %[[V18]]#0 move %true : (!fir.box>, i1) -> !hlfir.expr +// CHECK-NEXT: hlfir.assign %[[V19]] to %[[V2]]#0 : !hlfir.expr, !fir.box> +// CHECK-NEXT: hlfir.destroy %[[V19]] : !hlfir.expr +// CHECK-NEXT: return + + +// including mask and back +func.func @_QPmaxloc7(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "d"}, %arg2: !fir.box>> {fir.bindc_name = "m"}, %arg3: !fir.ref> {fir.bindc_name = "b"}, %arg4: !fir.box> {fir.bindc_name = "s"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFFtestEa"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg3 {uniq_name = "_QFFtestEb"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestEd"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEm"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) + %4:2 = hlfir.declare %arg4 {uniq_name = "_QFFtestEs"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %5 = fir.load %2#0 : !fir.ref + %6 = hlfir.maxloc %0#0 dim %5 mask %3#0 {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>) -> i32 + hlfir.assign %6 to %4#0 : i32, !fir.box> + return +} +// CHECK-LABEL: func.func @_QPmaxloc7( +// CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"} +// CHECK: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "d"} +// CHECK: %[[ARG2:.*]]: !fir.box>> {fir.bindc_name = "m"} +// CHECK: %[[ARG3:.*]]: !fir.ref> {fir.bindc_name = "b"} +// CHECK: %[[ARG4:.*]]: !fir.box> {fir.bindc_name = "s"} +// CHECK-NEXT: %[[V0:.*]] = fir.alloca !fir.box> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFFtestEa"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %[[ARG3]] {uniq_name = "_QFFtestEb"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +// CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QFFtestEd"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %[[ARG2]] {uniq_name = "_QFFtestEm"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) +// CHECK-NEXT: %[[V5:.*]]:2 = hlfir.declare %[[ARG4]] {uniq_name = "_QFFtestEs"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V6:.*]] = fir.load %[[V3]]#0 : !fir.ref +// CHECK-NEXT: %c4_i32 = arith.constant 4 : i32 +// CHECK-NEXT: %false = arith.constant false +// CHECK-NEXT: %[[V7:.*]] = fir.zero_bits !fir.heap +// CHECK-NEXT: %[[V8:.*]] = fir.embox %[[V7]] : (!fir.heap) -> !fir.box> +// CHECK-NEXT: fir.store %[[V8]] to %[[V0]] : !fir.ref>> +// CHECK: %[[V10:.*]] = fir.convert %[[V0]] : (!fir.ref>>) -> !fir.ref> +// CHECK-NEXT: %[[V11:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[V14:.*]] = fir.convert %[[V4]]#1 : (!fir.box>>) -> !fir.box +// CHECK-NEXT: %[[V15:.*]] = fir.call @_FortranAMaxlocDim(%[[V10]], %[[V11]], %c4_i32, %[[V6]], {{.*}}, {{.*}}, %[[V14]], %false) fastmath : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> none +// CHECK-NEXT: %[[V16:.*]] = fir.load %[[V0]] : !fir.ref>> +// CHECK-NEXT: %[[V17:.*]] = fir.box_addr %[[V16]] : (!fir.box>) -> !fir.heap +// CHECK-NEXT: %[[V18:.*]] = fir.load %[[V17]] : !fir.heap +// CHECK-NEXT: fir.freemem %[[V17]] : !fir.heap +// CHECK-NEXT: hlfir.assign %[[V18]] to %[[V5]]#0 : i32, !fir.box> +// CHECK-NEXT: return + diff --git a/flang/test/HLFIR/maxloc.fir b/flang/test/HLFIR/maxloc.fir new file mode 100644 index 0000000000000000000000000000000000000000..7325644d7e8cd9fd44d3809a88ccdda1a8a63f32 --- /dev/null +++ b/flang/test/HLFIR/maxloc.fir @@ -0,0 +1,272 @@ +// Test hlfir.maxloc operation parse, verify (no errors), and unparse + +// RUN: fir-opt %s | fir-opt | FileCheck %s + +// array is an expression of known shape +func.func @maxloc0(%arg0: !hlfir.expr<42xi32>) { + %mask = fir.alloca !fir.logical<4> + %c_1 = arith.constant 1 : index + %true = arith.constant true + %true_logical = fir.convert %true : (i1) -> !fir.logical<4> + fir.store %true_logical to %mask : !fir.ref> + %mask_box = fir.embox %mask : (!fir.ref>) -> !fir.box> + %0 = hlfir.maxloc %arg0 dim %c_1 mask %mask_box : (!hlfir.expr<42xi32>, index, !fir.box>) -> i32 + return +} +// CHECK: func.func @maxloc0(%[[ARRAY:.*]]: !hlfir.expr<42xi32>) { +// CHECK-NEXT: %[[MASK:.*]] = fir.alloca !fir.logical<4> +// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index +// CHECK-NEXT: %[[TRUE:.*]] = arith.constant true +// CHECK-NEXT: %[[LOGICAL:.*]] = fir.convert %[[TRUE]] : (i1) -> !fir.logical<4> +// CHECK-NEXT: fir.store %[[LOGICAL]] to %[[MASK]] : !fir.ref> +// CHECK-NEXT: %[[BOX:.*]] = fir.embox %0 : (!fir.ref>) -> !fir.box> +// CHECK-NEXT: hlfir.maxloc %[[ARRAY]] dim %[[C1]] mask %[[BOX]] : (!hlfir.expr<42xi32>, index, !fir.box>) -> i32 +// CHECK-NEXT: return +// CHECK-NEXT: } + +// array is an expression of assumed shape +func.func @maxloc1(%arg0: !hlfir.expr) { + %mask = fir.alloca !fir.logical<4> + %c_1 = arith.constant 1 : index + %true = arith.constant true + %true_logical = fir.convert %true : (i1) -> !fir.logical<4> + fir.store %true_logical to %mask : !fir.ref> + %mask_box = fir.embox %mask : (!fir.ref>) -> !fir.box> + %0 = hlfir.maxloc %arg0 dim %c_1 mask %mask_box : (!hlfir.expr, index, !fir.box>) -> i32 + return +} +// CHECK: func.func @maxloc1(%[[ARRAY:.*]]: !hlfir.expr) { +// CHECK-NEXT: %[[MASK:.*]] = fir.alloca !fir.logical<4> +// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index +// CHECK-NEXT: %[[TRUE:.*]] = arith.constant true +// CHECK-NEXT: %[[LOGICAL:.*]] = fir.convert %[[TRUE]] : (i1) -> !fir.logical<4> +// CHECK-NEXT: fir.store %[[LOGICAL:.*]] to %[[MASK:.*]] : !fir.ref> +// CHECK-NEXT: %[[BOX:.*]] = fir.embox %[[MASK:.*]] : (!fir.ref>) -> !fir.box> +// CHECK-NEXT: hlfir.maxloc %[[ARRAY:.*]] dim %[[C1]] mask %[[BOX]] : (!hlfir.expr, index, !fir.box>) -> i32 +// CHECK-NEXT: return +// CHECK-NEXT: } + +// boxed array +func.func @maxloc2(%arg0: !fir.box>) { + %mask = fir.alloca !fir.logical<4> + %c_1 = arith.constant 1 : index + %true = arith.constant true + %true_logical = fir.convert %true : (i1) -> !fir.logical<4> + fir.store %true_logical to %mask : !fir.ref> + %mask_box = fir.embox %mask : (!fir.ref>) -> !fir.box> + %0 = hlfir.maxloc %arg0 dim %c_1 mask %mask_box : (!fir.box>, index, !fir.box>) -> i32 + return +} +// CHECK: func.func @maxloc2(%[[ARRAY:.*]]: !fir.box>) { +// CHECK-NEXT: %[[MASK:.*]] = fir.alloca !fir.logical<4> +// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index +// CHECK-NEXT: %[[TRUE:.*]] = arith.constant true +// CHECK-NEXT: %[[LOGICAL:.*]] = fir.convert %[[TRUE]] : (i1) -> !fir.logical<4> +// CHECK-NEXT: fir.store %[[LOGICAL:.*]] to %[[MASK:.*]] : !fir.ref> +// CHECK-NEXT: %[[BOX:.*]] = fir.embox %[[MASK:.*]] : (!fir.ref>) -> !fir.box> +// CHECK-NEXT: hlfir.maxloc %[[ARRAY:.*]] dim %[[C1]] mask %[[BOX]] : (!fir.box>, index, !fir.box>) -> i32 +// CHECK-NEXT: return +// CHECK-NEXT: } + +// assumed shape boxed array +func.func @maxloc3(%arg0: !fir.box>) { + %mask = fir.alloca !fir.logical<4> + %c_1 = arith.constant 1 : index + %true = arith.constant true + %true_logical = fir.convert %true : (i1) -> !fir.logical<4> + fir.store %true_logical to %mask : !fir.ref> + %mask_box = fir.embox %mask : (!fir.ref>) -> !fir.box> + %0 = hlfir.maxloc %arg0 dim %c_1 mask %mask_box : (!fir.box>, index, !fir.box>) -> i32 + return +} +// CHECK: func.func @maxloc3(%[[ARRAY:.*]]: !fir.box>) { +// CHECK-NEXT: %[[MASK:.*]] = fir.alloca !fir.logical<4> +// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index +// CHECK-NEXT: %[[TRUE:.*]] = arith.constant true +// CHECK-NEXT: %[[LOGICAL:.*]] = fir.convert %[[TRUE]] : (i1) -> !fir.logical<4> +// CHECK-NEXT: fir.store %[[LOGICAL:.*]] to %[[MASK:.*]] : !fir.ref> +// CHECK-NEXT: %[[BOX:.*]] = fir.embox %[[MASK:.*]] : (!fir.ref>) -> !fir.box> +// CHECK-NEXT: hlfir.maxloc %[[ARRAY:.*]] dim %[[C1]] mask %[[BOX]] : (!fir.box>, index, !fir.box>) -> i32 +// CHECK-NEXT: return +// CHECK-NEXT: } + +// known shape expr mask +func.func @maxloc4(%arg0: !fir.box>, %arg1: !hlfir.expr<42x!fir.logical<4>>) { + %c_1 = arith.constant 1 : index + %0 = hlfir.maxloc %arg0 dim %c_1 mask %arg1 : (!fir.box>, index, !hlfir.expr<42x!fir.logical<4>>) -> i32 + return +} +// CHECK: func.func @maxloc4(%[[ARRAY:.*]]: !fir.box>, %[[MASK:.*]]: !hlfir.expr<42x!fir.logical<4>>) { +// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index +// CHECK-NEXT: hlfir.maxloc %[[ARRAY]] dim %[[C1]] mask %[[MASK]] : (!fir.box>, index, !hlfir.expr<42x!fir.logical<4>>) -> i32 +// CHECK-NEXT: return +// CHECK-NEXT: } + +// assumed shape expr mask +func.func @maxloc5(%arg0: !fir.box>, %arg1: !hlfir.expr>) { + %c_1 = arith.constant 1 : index + %0 = hlfir.maxloc %arg0 dim %c_1 mask %arg1 : (!fir.box>, index, !hlfir.expr>) -> i32 + return +} +// CHECK: func.func @maxloc5(%[[ARRAY:.*]]: !fir.box>, %[[MASK:.*]]: !hlfir.expr>) { +// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index +// CHECK-NEXT: hlfir.maxloc %[[ARRAY]] dim %[[C1]] mask %[[MASK]] : (!fir.box>, index, !hlfir.expr>) -> i32 +// CHECK-NEXT: return +// CHECK-NEXT: } + +// known shape array mask +func.func @maxloc6(%arg0: !fir.box>, %arg1: !fir.box>>) { + %c_1 = arith.constant 1 : index + %0 = hlfir.maxloc %arg0 dim %c_1 mask %arg1 : (!fir.box>, index, !fir.box>>) -> i32 + return +} +// CHECK: func.func @maxloc6(%[[ARRAY:.*]]: !fir.box>, %[[MASK:.*]]: !fir.box>>) { +// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index +// CHECK-NEXT: hlfir.maxloc %[[ARRAY]] dim %[[C1]] mask %[[MASK]] : (!fir.box>, index, !fir.box>>) -> i32 +// CHECK-NEXT: return +// CHECK-NEXT: } + +// assumed shape array mask +func.func @maxloc7(%arg0: !fir.box>, %arg1: !fir.box>>) { + %c_1 = arith.constant 1 : index + %0 = hlfir.maxloc %arg0 dim %c_1 mask %arg1 : (!fir.box>, index, !fir.box>>) -> i32 + return +} +// CHECK: func.func @maxloc7(%[[ARRAY:.*]]: !fir.box>, %[[MASK:.*]]: !fir.box>>) { +// CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index +// CHECK-NEXT: hlfir.maxloc %[[ARRAY]] dim %[[C1]] mask %[[MASK]] : (!fir.box>, index, !fir.box>>) -> i32 +// CHECK-NEXT: return +// CHECK-NEXT: } + +// known shape expr return +func.func @maxloc8(%arg0: !fir.box>, %arg1: i32) { + %mask = fir.alloca !fir.logical<4> + %true = arith.constant true + %true_logical = fir.convert %true : (i1) -> !fir.logical<4> + fir.store %true_logical to %mask : !fir.ref> + %mask_box = fir.embox %mask : (!fir.ref>) -> !fir.box> + %0 = hlfir.maxloc %arg0 dim %arg1 mask %mask_box : (!fir.box>, i32, !fir.box>) -> !hlfir.expr<2xi32> + return +} +// CHECK: func.func @maxloc8(%[[ARRAY:.*]]: !fir.box>, %[[DIM:.*]]: i32) { +// CHECK-NEXT: %[[MASK:.*]] = fir.alloca !fir.logical<4> +// CHECK-NEXT: %[[TRUE:.*]] = arith.constant true +// CHECK-NEXT: %[[LOGICAL:.*]] = fir.convert %[[TRUE]] : (i1) -> !fir.logical<4> +// CHECK-NEXT: fir.store %[[LOGICAL]] to %[[MASK]] : !fir.ref> +// CHECK-NEXT: %[[BOX:.*]] = fir.embox %0 : (!fir.ref>) -> !fir.box> +// CHECK-NEXT: hlfir.maxloc %[[ARRAY]] dim %[[DIM]] mask %[[BOX]] : (!fir.box>, i32, !fir.box>) -> !hlfir.expr<2xi32> +// CHECK-NEXT: return +// CHECK-NEXT: } + +// assumed shape expr return +func.func @maxloc9(%arg0: !fir.box>, %arg1: i32) { + %mask = fir.alloca !fir.logical<4> + %true = arith.constant true + %true_logical = fir.convert %true : (i1) -> !fir.logical<4> + fir.store %true_logical to %mask : !fir.ref> + %mask_box = fir.embox %mask : (!fir.ref>) -> !fir.box> + %0 = hlfir.maxloc %arg0 dim %arg1 mask %mask_box : (!fir.box>, i32, !fir.box>) -> !hlfir.expr + return +} +// CHECK: func.func @maxloc9(%[[ARRAY:.*]]: !fir.box>, %[[DIM:.*]]: i32) { +// CHECK-NEXT: %[[MASK:.*]] = fir.alloca !fir.logical<4> +// CHECK-NEXT: %[[TRUE:.*]] = arith.constant true +// CHECK-NEXT: %[[LOGICAL:.*]] = fir.convert %[[TRUE]] : (i1) -> !fir.logical<4> +// CHECK-NEXT: fir.store %[[LOGICAL]] to %[[MASK]] : !fir.ref> +// CHECK-NEXT: %[[BOX:.*]] = fir.embox %0 : (!fir.ref>) -> !fir.box> +// CHECK-NEXT: hlfir.maxloc %[[ARRAY]] dim %[[DIM]] mask %[[BOX]] : (!fir.box>, i32, !fir.box>) -> !hlfir.expr +// CHECK-NEXT: return +// CHECK-NEXT: } + +// hlfir.maxloc with only an array argument +func.func @maxloc10(%arg0: !fir.box>) { + %maxloc = hlfir.maxloc %arg0 : (!fir.box>) -> !hlfir.expr<1xi32> + return +} +// CHECK: func.func @maxloc10(%[[ARRAY:.*]]: !fir.box> +// CHECK-NEXT: %[[maxloc:.*]] = hlfir.maxloc %[[ARRAY]] : (!fir.box>) -> !hlfir.expr<1xi32> +// CHECK-NEXT: return +// CHECK-NEXT: } + +// hlfir.maxloc with only a character array argument +func.func @maxloc11(%arg0: !fir.box>>) { + %maxloc = hlfir.maxloc %arg0 : (!fir.box>>) -> !hlfir.expr<1xi32> + return +} +// CHECK: func.func @maxloc11(%[[ARRAY:.*]]: !fir.box>> +// CHECK-NEXT: %[[maxloc:.*]] = hlfir.maxloc %[[ARRAY]] : (!fir.box>>) -> !hlfir.expr<1xi32> +// CHECK-NEXT: return +// CHECK-NEXT: } + +// hlfir.maxloc with array and dim argument +func.func @maxloc12(%arg0: !fir.box>, %arg1: i32) { + %maxloc = hlfir.maxloc %arg0 dim %arg1 : (!fir.box>, i32) -> !hlfir.expr + return +} +// CHECK: func.func @maxloc12(%[[ARRAY:.*]]: !fir.box>, %[[DIM:.*]]: i32 +// CHECK-NEXT: %[[maxloc:.*]] = hlfir.maxloc %[[ARRAY]] dim %[[DIM]] : (!fir.box>, i32) -> !hlfir.expr +// CHECK-NEXT: return +// CHECK-NEXT: } + +// hlfir.maxloc with array and mask argument +func.func @maxloc13(%arg0: !fir.box>, %arg1: !fir.logical<4>) { + %maxloc = hlfir.maxloc %arg0 mask %arg1 : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> + return +} +// CHECK: func.func @maxloc13(%[[ARRAY:.*]]: !fir.box>, %[[MASK:.*]]: !fir.logical<4> +// CHECK-NEXT: %[[maxloc:.*]] = hlfir.maxloc %[[ARRAY]] mask %[[MASK]] : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> +// CHECK-NEXT: return +// CHECK-NEXT: } + +// hlfir.maxloc with dim argument with an unusual type +func.func @maxloc14(%arg0: !fir.box>, %arg1: index) { + %maxloc = hlfir.maxloc %arg0 dim %arg1 : (!fir.box>, index) -> !hlfir.expr + return +} +// CHECK: func.func @maxloc14(%[[ARRAY:.*]]: !fir.box>, %[[DIM:.*]]: index +// CHECK-NEXT: %[[maxloc:.*]] = hlfir.maxloc %[[ARRAY]] dim %[[DIM]] : (!fir.box>, index) -> !hlfir.expr +// CHECK-NEXT: return +// CHECK-NEXT: } + +// hlfir.maxloc with mask argument of unusual type +func.func @maxloc15(%arg0: !fir.box>, %arg1: i1) { + %maxloc = hlfir.maxloc %arg0 mask %arg1 : (!fir.box>, i1) -> !hlfir.expr<1xi32> + return +} +// CHECK: func.func @maxloc15(%[[ARRAY:.*]]: !fir.box>, %[[MASK:.*]]: i1 +// CHECK-NEXT: %[[maxloc:.*]] = hlfir.maxloc %[[ARRAY]] mask %[[MASK]] : (!fir.box>, i1) -> !hlfir.expr<1xi32> +// CHECK-NEXT: return +// CHECK-NEXT: } + +// hlfir.maxloc with mask argument of ref> type +func.func @maxloc16(%arg0: !fir.box>, %arg1: !fir.ref>>) { + %maxloc = hlfir.maxloc %arg0 mask %arg1 : (!fir.box>, !fir.ref>>) -> !hlfir.expr<1xi32> + return +} +// CHECK: func.func @maxloc16(%[[ARRAY:.*]]: !fir.box>, %[[MASK:.*]]: !fir.ref>> +// CHECK-NEXT: %[[maxloc:.*]] = hlfir.maxloc %[[ARRAY]] mask %[[MASK]] : (!fir.box>, !fir.ref>>) -> !hlfir.expr<1xi32> +// CHECK-NEXT: return +// CHECK-NEXT: } + + +// hlfir.maxloc with kind implied by the return type +func.func @maxloc17(%arg0: !fir.box>, %arg1: i1) { + %maxloc = hlfir.maxloc %arg0 mask %arg1 : (!fir.box>, i1) -> !hlfir.expr<1xi16> + return +} +// CHECK: func.func @maxloc17(%[[ARRAY:.*]]: !fir.box>, %[[MASK:.*]]: i1 +// CHECK-NEXT: %[[maxloc:.*]] = hlfir.maxloc %[[ARRAY]] mask %[[MASK]] : (!fir.box>, i1) -> !hlfir.expr<1xi16> +// CHECK-NEXT: return +// CHECK-NEXT: } + +// hlfir.maxloc with back argument +func.func @maxloc18(%arg0: !fir.box>, %arg1: i1) { + %true = arith.constant true + %maxloc = hlfir.maxloc %arg0 mask %arg1 back %true : (!fir.box>, i1, i1) -> !hlfir.expr<1xi32> + return +} +// CHECK: func.func @maxloc18(%[[ARRAY:.*]]: !fir.box>, %[[MASK:.*]]: i1 +// CHECK-NEXT: %[[C2:.*]] = arith.constant true +// CHECK-NEXT: %[[maxloc:.*]] = hlfir.maxloc %[[ARRAY]] mask %[[MASK]] back %[[C2]] : (!fir.box>, i1, i1) -> !hlfir.expr<1xi32> +// CHECK-NEXT: return +// CHECK-NEXT: } \ No newline at end of file diff --git a/flang/test/HLFIR/memory-effects.fir b/flang/test/HLFIR/memory-effects.fir index c68c71f43a17dd1fb4ba45d1d01640e99112404c..32d6b264d6c11ccdff271ce527dda6098d831cd8 100644 --- a/flang/test/HLFIR/memory-effects.fir +++ b/flang/test/HLFIR/memory-effects.fir @@ -137,6 +137,21 @@ func.func @minloc_effects(%arg0: !fir.ref>, %arg1: i32) { return } +func.func @maxloc_effects_simple(%arg0: !hlfir.expr) { +// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource ''}} + %maxloc = hlfir.maxloc %arg0 : (!hlfir.expr) -> !hlfir.expr +// expected-remark@+1 {{operation has no memory effects}} + return +} + +func.func @maxloc_effects(%arg0: !fir.ref>, %arg1: i32) { +// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} + %maxloc = hlfir.maxloc %arg0 dim %arg1 : (!fir.ref>, i32) -> !hlfir.expr<2xi32> +// expected-remark@+1 {{operation has no memory effects}} + return +} + func.func @dot_product_no_effects(%arg0: !hlfir.expr, %arg1: !hlfir.expr) { // expected-remark@+1 {{operation has no memory effects}} %0 = hlfir.dot_product %arg0 %arg1 : (!hlfir.expr, !hlfir.expr) -> f32 diff --git a/flang/test/Lower/HLFIR/count.f90 b/flang/test/Lower/HLFIR/count.f90 index 252f92789c76074243e4886657ddea4ba59de6e6..e415f77206c510919d0bf8327890ed9af6aaa587 100644 --- a/flang/test/Lower/HLFIR/count.f90 +++ b/flang/test/Lower/HLFIR/count.f90 @@ -70,9 +70,8 @@ end subroutine ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK-DAG: %[[C8:.*]] = arith.constant 8 : i32 ! CHECK-DAG: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-DAG: %[[EXPR:.*]] = hlfir.count %[[MASK]]#0 dim %[[DIM]] kind %[[C8]] : (!fir.box>>, i32, i32) -> !hlfir.expr +! CHECK-DAG: %[[EXPR:.*]] = hlfir.count %[[MASK]]#0 dim %[[DIM]] : (!fir.box>>, i32) -> !hlfir.expr ! CHECK-DAG: %[[RES_SHAPE:.*]] = hlfir.shape_of %[[EXPR]] ! CHECK-DAG: %[[RES:.*]] = hlfir.elemental %[[RES_SHAPE]] unordered : (!fir.shape<1>) -> !hlfir.expr ! CHECK-DAG: hlfir.assign %[[RES]] to %[[OUT]]#0 diff --git a/flang/test/Lower/HLFIR/maxloc.f90 b/flang/test/Lower/HLFIR/maxloc.f90 new file mode 100644 index 0000000000000000000000000000000000000000..ea3cce92ae90119e839238122e0f3e24bd58328e --- /dev/null +++ b/flang/test/Lower/HLFIR/maxloc.f90 @@ -0,0 +1,370 @@ +! Test lowering of MAXLOC intrinsic to HLFIR +! RUN: bbc -emit-hlfir -o - %s 2>&1 | FileCheck %s + +! simple 1 argument MAXLOC +subroutine maxloc1(a, s) + integer :: a(:), s(:) + s = MAXLOC(a) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc1( +! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> +! CHECK-NEXT: return +! CHECK-NEXT: } + +! maxloc with by-ref DIM argument +subroutine maxloc2(a, s, d) + integer :: a(:,:), s(:), d + s = MAXLOC(a, d) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc2( +! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"}, %[[ARG2:.*]]: !fir.ref +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>, i32) -> !hlfir.expr +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] +! CHECK-NEXT: return +! CHECK-NEXT: } + +! maxloc with scalar mask argument +subroutine maxloc3(a, s, m) + integer :: a(:), s(:) + logical :: m + s = MAXLOC(a, m) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc3( +! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"}, %[[ARG2:.*]]: !fir.ref> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> +! CHECK-NEXT: return +! CHECK-NEXT: } + +! maxloc with array mask argument +subroutine maxloc4(a, s, m) + integer :: a(:), s(:) + logical :: m(:) + s = MAXLOC(a, m) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc4( +! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"}, %[[ARG2:.*]]: !fir.box>> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> +! CHECK-NEXT: return +! CHECK-NEXT: } + +! maxloc with all 3 arguments, dim is by-val, array isn't boxed +subroutine maxloc5(s) + integer :: s(2) + integer :: a(2,2) = reshape((/1, 2, 3, 4/), [2,2]) + s = maxloc(a, 1, .true.) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc5 +! CHECK: %[[ARG0:.*]]: !fir.ref> +! CHECK-DAG: %[[ADDR:.*]] = fir.address_of({{.*}}) : !fir.ref> +! CHECK-DAG: %[[ARRAY_SHAPE:.*]] = fir.shape {{.*}} -> !fir.shape<2> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ADDR]](%[[ARRAY_SHAPE]]) +! CHECK-DAG: %[[OUT_SHAPE:.*]] = fir.shape {{.*}} -> !fir.shape<1> +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG0]](%[[OUT_SHAPE]]) +! CHECK-DAG: %[[TRUE:.*]] = arith.constant true +! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<2xi32>, !fir.ref> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<2xi32> +! CHECK-NEXT: return +! CHECK-nEXT: } + +! back argument as .true. +subroutine maxloc_back(a, s) + integer :: a(:), s(:) + s = MAXLOC(a, BACK=.TRUE.) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc_back( +! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-DAG: %[[C1:.*]] = arith.constant true +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 back %[[C1]] {fastmath = #arith.fastmath} : (!fir.box>, i1) -> !hlfir.expr<1xi32> +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> +! CHECK-NEXT: return +! CHECK-NEXT: } + +! back argument as logical +subroutine maxloc_back2(a, s, b) + integer :: a(:), s(:) + logical :: b + s = MAXLOC(a, BACK=b) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc_back2( +! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"}, %[[ARG2:.*]]: !fir.ref> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[BACKD:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-NEXT: %[[BACK:.*]] = fir.load %[[BACKD]]#0 : !fir.ref> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 back %[[BACK]] {fastmath = #arith.fastmath} : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> +! CHECK-NEXT: return +! CHECK-NEXT: } + +! back argument as optional logical +subroutine maxloc_back3(a, s, b) + integer :: a(:), s(:) + logical, optional :: b + s = MAXLOC(a, BACK=b) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc_back3( +! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"}, %[[ARG2:.*]]: !fir.ref> {fir.bindc_name = "b", fir.optional}) { +! CHECK: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-NEXT: %[[BACKD:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-NEXT: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-NEXT: %[[IFP:.*]] = fir.is_present %[[BACKD]]#0 : (!fir.ref>) -> i1 +! CHECK-NEXT: %[[BACK:.*]] = fir.if %[[IFP]] -> (!fir.logical<4>) { +! CHECK-NEXT: %[[IFT:.*]] = fir.load %[[BACKD]]#0 : !fir.ref> +! CHECK-NEXT: fir.result %[[IFT]] : !fir.logical<4> +! CHECK-NEXT: } else { +! CHECK-NEXT: %false = arith.constant false +! CHECK-NEXT: %[[IFE:.*]] = fir.convert %false : (i1) -> !fir.logical<4> +! CHECK-NEXT: fir.result %[[IFE]] : !fir.logical<4> +! CHECK-NEXT: } +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 back %[[BACK]] {fastmath = #arith.fastmath} : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> +! CHECK-NEXT: return +! CHECK-NEXT: } + + +! kind = 2 +subroutine maxloc_kind(a, s) + integer :: a(:), s(:) + s = MAXLOC(a, KIND=2) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc_kind( +! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr<1xi16> +! CHECK: %[[ELM:.*]] = hlfir.elemental +! CHECK: hlfir.assign %[[ELM]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[ELM]] : !hlfir.expr +! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi16> +! CHECK-NEXT: return +! CHECK-NEXT: } + +subroutine maxloc6(a, s, d) + integer, pointer :: d + integer s(:) + real :: a(:,:) + s = maxloc(a, (d)) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc6( +! CHECK: %[[ARG0:.*]]: !fir.box> +! CHECK: %[[ARG1:.*]]: !fir.box> +! CHECK: %[[ARG2:.*]]: !fir.ref>> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-DAG: %[[DIM_VAR:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-NEXT: %[[DIM_BOX:.*]] = fir.load %[[DIM_VAR]]#0 : !fir.ref>> +! CHECK-NEXT: %[[DIM_ADDR:.*]] = fir.box_addr %[[DIM_BOX]] : (!fir.box>) -> !fir.ptr +! CHECK-NEXT: %[[DIM0:.*]] = fir.load %[[DIM_ADDR]] : !fir.ptr +! CHECK-NEXT: %[[DIM1:.*]] = hlfir.no_reassoc %[[DIM0]] : i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 dim %[[DIM1]] {fastmath = #arith.fastmath} : (!fir.box>, i32) -> !hlfir.expr +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] +! CHECK-NEXT: return +! CHECK-NEXT: } + +! simple 1 argument MAXLOC for character +subroutine maxloc7(a, s) + character(*) :: a(:) + integer :: s(:) + s = MAXLOC(a) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc7( +! CHECK: %[[ARG0:.*]]: !fir.box>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] +! CHECK-NEXT: return +! CHECK-NEXT: } + +! maxloc for character with by-ref DIM argument +subroutine maxloc8(a, s, d) + character(*) :: a(:,:) + integer :: d, s(:) + s = MAXLOC(a, d) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc8( +! CHECK: %[[ARG0:.*]]: !fir.box>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"}, %[[ARG2:.*]]: !fir.ref +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>>, i32) -> !hlfir.expr +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] +! CHECK-NEXT: return +! CHECK-NEXT: } + +! maxloc for character with scalar mask argument +subroutine maxloc9(a, s, m) + character(*) :: a(:) + integer :: s(:) + logical :: m + s = MAXLOC(a, m) +end subroutine +! CHECK-LABEL: func.func @_QPmaxloc9( +! CHECK: %[[ARG0:.*]]: !fir.box>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"}, %[[ARG2:.*]]: !fir.ref> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>>, !fir.ref>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] +! CHECK-NEXT: return +! CHECK-NEXT: } + +subroutine testDynamicallyOptionalMask(array, mask, res) + integer :: array(:), res(:) + logical, allocatable :: mask(:) + res = MAXLOC(array, mask=mask) +end subroutine +! CHECK-LABEL: func.func @_QPtestdynamicallyoptionalmask( +! CHECK-SAME: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "array"} +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref>>>> +! CHECK-SAME: %[[ARG2:.*]]: !fir.box> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-DAG: %[[RES:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-NEXT: %[[MASK_LOAD:.*]] = fir.load %[[MASK]]#1 +! CHECK-NEXT: %[[MASK_ADDR:.*]] = fir.box_addr %[[MASK_LOAD]] +! CHECK-NEXT: %[[MASK_ADDR_INT:.*]] = fir.convert %[[MASK_ADDR]] +! CHECK-NEXT: %[[C0:.*]] = arith.constant 0 : i64 +! CHECK-NEXT: %[[CMP:.*]] = arith.cmpi ne, %[[MASK_ADDR_INT]], %[[C0]] : i64 +! it is a shame there is a second load here. The first is generated for +! PreparedActualArgument::isPresent, the second is for optional handling +! CHECK-NEXT: %[[MASK_LOAD2:.*]] = fir.load %[[MASK]]#1 +! CHECK-NEXT: %[[ABSENT:.*]] = fir.absent !fir.box>>> +! CHECK-NEXT: %[[SELECT:.*]] = arith.select %[[CMP]], %[[MASK_LOAD2]], %[[ABSENT]] +! CHECK-NEXT: %[[MAXLOC:.*]] = hlfir.maxloc %[[ARRAY]]#0 mask %[[SELECT]] +! CHECK-NEXT: hlfir.assign %[[MAXLOC]] to %[[RES]]#0 +! CHECK-NEXT: hlfir.destroy %[[MAXLOC]] +! CHECK-NEXT: return +! CHECK-NEXT: } + +subroutine testAllocatableArray(array, mask, res) + integer, allocatable :: array(:) + integer :: res(:) + logical :: mask(:) + res = MAXLOC(array, mask=mask) +end subroutine +! CHECK-LABEL: func.func @_QPtestallocatablearray( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>> +! CHECK-SAME: %[[ARG1:.*]]: !fir.box>> +! CHECK-SAME: %[[ARG2:.*]]: !fir.box> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-DAG: %[[RES:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-NEXT: %[[LOADED_ARRAY:.*]] = fir.load %[[ARRAY]]#0 +! CHECK-NEXT: %[[MAXLOC:.*]] = hlfir.maxloc %[[LOADED_ARRAY]] mask %[[MASK]]#0 +! CHECK-NEXT: hlfir.assign %[[MAXLOC]] to %[[RES]]#0 +! CHECK-NEXT: hlfir.destroy %[[MAXLOC]] +! CHECK-NEXT: return +! CHECK-NEXT: } + +function testOptionalScalar(array, mask) + integer :: array(:) + logical, optional :: mask + integer :: testOptionalScalar(1) + testOptionalScalar = maxloc(array, mask) +end function +! CHECK-LABEL: func.func @_QPtestoptionalscalar( +! CHECK-SAME: %[[ARRAY_ARG:.*]]: !fir.box> {fir.bindc_name = "array"}, +! CHECK-SAME: %[[MASK_ARG:.*]]: !fir.ref> {fir.bindc_name = "mask", fir.optional}) -> !fir.array<1xi32> +! CHECK: %[[ARRAY_VAR:.*]]:2 = hlfir.declare %[[ARRAY_ARG]] +! CHECK: %[[MASK_VAR:.*]]:2 = hlfir.declare %[[MASK_ARG]] +! CHECK: %[[RET_ALLOC:.*]] = fir.alloca !fir.array<1xi32> {bindc_name = "testoptionalscalar", uniq_name = "_QFtestoptionalscalarEtestoptionalscalar"} +! CHECK: %[[RET_VAR:.*]]:2 = hlfir.declare %[[RET_ALLOC]] +! CHECK: %[[MASK_IS_PRESENT:.*]] = fir.is_present %[[MASK_VAR]]#0 : (!fir.ref>) -> i1 +! CHECK: %[[MASK_BOX:.*]] = fir.embox %[[MASK_VAR]]#1 +! CHECK: %[[ABSENT:.*]] = fir.absent !fir.box> +! CHECK: %[[MASK_SELECT:.*]] = arith.select %[[MASK_IS_PRESENT]], %[[MASK_BOX]], %[[ABSENT]] +! CHECK: %[[RES:.*]] = hlfir.maxloc %[[ARRAY_VAR]]#0 mask %[[MASK_SELECT]] {{.*}}: (!fir.box>, !fir.box>) -> !hlfir.expr<1xi32> +! CHECK: hlfir.assign %[[RES]] to %[[RET_VAR]]#0 +! CHECK: hlfir.destroy %[[RES]] +! CHECK: %[[RET:.*]] = fir.load %[[RET_VAR]]#1 : !fir.ref> +! CHECK: return %[[RET]] : !fir.array<1xi32> +! CHECK: } + +! Test that hlfir.maxloc lowering inherits constant +! character length from the argument, when the length +! is unknown from the Fortran::evaluate expression type. +subroutine test_unknown_char_len_result + character(len=3) :: array(3,3) + integer :: res(2) + res = maxloc(array(:,:)(:)) +end subroutine test_unknown_char_len_result +! CHECK-LABEL: func.func @_QPtest_unknown_char_len_result() { +! CHECK-DAG: %[[C3:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[C3_0:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[C3_1:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[ARRAY_ALLOC:.*]] = fir.alloca !fir.array<3x3x!fir.char<1,3>> +! CHECK-DAG: %[[ARRAY_SHAPE:.*]] = fir.shape %[[C3_0]], %[[C3_1]] : (index, index) -> !fir.shape<2> +! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARRAY_ALLOC]](%[[ARRAY_SHAPE]]) typeparams %[[C3]] +! CHECK-DAG: %[[C2:.*]] = arith.constant 2 : index +! CHECK-DAG: %[[RES_ALLOC:.*]] = fir.alloca !fir.array<2xi32> +! CHECK-DAG: %[[RES_SHAPE:.*]] = fir.shape %[[C2]] : (index) -> !fir.shape<1> +! CHECK-DAG: %[[RES:.*]]:2 = hlfir.declare %[[RES_ALLOC]](%[[RES_SHAPE]]) +! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index +! CHECK-DAG: %[[C1_3:.*]] = arith.constant 1 : index +! CHECK-DAG: %[[C3_4:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[C1_5:.*]] = arith.constant 1 : index +! CHECK-DAG: %[[C3_6:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[SHAPE:.*]] = fir.shape %[[C3_4]], %[[C3_6]] : (index, index) -> !fir.shape<2> +! CHECK-DAG: %[[C1_7:.*]] = arith.constant 1 : index +! CHECK-DAG: %[[C3_8:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[C3_9:.*]] = arith.constant 3 : index +! CHECK-DAG: %[[ARRAY_BOX:.*]] = hlfir.designate %[[ARRAY]]#0 (%[[C1]]:%[[C3_0]]:%[[C1_3]], %[[C1]]:%[[C3_1]]:%[[C1_5]]) substr %[[C1_7]], %[[C3_8]] shape %[[SHAPE]] typeparams %[[C3_9]] +! CHECK: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY_BOX]] {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr<2xi32> +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES]]#0 : !hlfir.expr<2xi32>, !fir.ref> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] +! CHECK-NEXT: return +! CHECK-NEXT: } + + +subroutine scalar_dim1(a, d, m, b, s) + integer :: a(:), d + integer :: s(:) + logical :: m(:), b + s = MAXLOC(a, dim=d, mask=m, kind=2, back=b) +end subroutine +! CHECK-LABEL: func.func @_QPscalar_dim1( +! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "d"}, %[[ARG2:.*]]: !fir.box>> {fir.bindc_name = "m"}, %[[ARG3:.*]]: !fir.ref> {fir.bindc_name = "b"}, %[[ARG4:.*]]: !fir.box> {fir.bindc_name = "s"}) { +! CHECK-NEXT: %[[V0:.*]]:2 = hlfir.declare %[[ARG0]] +! CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %[[ARG3]] +! CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %[[ARG1]] +! CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %[[ARG2]] +! CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %[[ARG4]] +! CHECK-NEXT: %[[V5:.*]] = fir.load %[[V1]]#0 : !fir.ref> +! CHECK-NEXT: %[[V6:.*]] = fir.load %[[V2]]#0 : !fir.ref +! CHECK-NEXT: %[[V7:.*]] = hlfir.maxloc %[[V0]]#0 dim %[[V6]] mask %[[V3]]#0 back %[[V5]] {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>, !fir.logical<4>) -> i16 +! CHECK-NEXT: %[[V8:.*]] = fir.convert %[[V7]] : (i16) -> i32 +! CHECK-NEXT: hlfir.assign %[[V8]] to %[[V4]]#0 : i32, !fir.box> +! CHECK-NEXT: return diff --git a/flang/test/Lower/OpenACC/acc-bounds.f90 b/flang/test/Lower/OpenACC/acc-bounds.f90 index 8db18ab5aa9c4bbb9cbd731abcb77608a94a606e..9e8e54bc2f7fa6159b3057cee534c1c6dabe91fe 100644 --- a/flang/test/Lower/OpenACC/acc-bounds.f90 +++ b/flang/test/Lower/OpenACC/acc-bounds.f90 @@ -116,4 +116,39 @@ contains ! CHECK: %[[PRESENT:.*]] = acc.present varPtr(%[[BOX_ADDR]] : !fir.ref>) bounds(%29, %33, %37) -> !fir.ref> {name = "a"} ! CHECK: acc.kernels dataOperands(%[[PRESENT]] : !fir.ref>) { + subroutine acc_optional_data(a) + real, pointer, optional :: a(:) + !$acc data attach(a) + !$acc end data + end subroutine + +! CHECK-LABEL: func.func @_QMopenacc_boundsPacc_optional_data( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>> {fir.bindc_name = "a", fir.optional}) { +! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QMopenacc_boundsFacc_optional_dataEa"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[ARG0_DECL]]#1 : (!fir.ref>>>) -> i1 +! CHECK: %[[BOX:.*]] = fir.if %[[IS_PRESENT]] -> (!fir.box>>) { +! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0_DECL]]#1 : !fir.ref>>> +! CHECK: fir.result %[[LOAD]] : !fir.box>> +! CHECK: } else { +! CHECK: %[[ABSENT:.*]] = fir.absent !fir.box>> +! CHECK: fir.result %[[ABSENT]] : !fir.box>> +! CHECK: } +! CHECK: %[[RES:.*]]:5 = fir.if %[[IS_PRESENT]] -> (index, index, index, index, index) { +! CHECK: fir.result %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : index, index, index, index, index +! CHECK: } else { +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[CM1:.*]] = arith.constant -1 : index +! CHECK: fir.result %[[C0]], %[[CM1]], %[[C0]], %[[C0]], %[[C0]] : index, index, index, index, index +! CHECK: } +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[RES]]#0 : index) upperbound(%[[RES]]#1 : index) extent(%[[RES]]#2 : index) stride(%[[RES]]#3 : index) startIdx(%[[RES]]#4 : index) {strideInBytes = true} +! CHECK: %[[BOX_ADDR:.*]] = fir.if %[[IS_PRESENT]] -> (!fir.ptr>) { +! CHECK: %[[ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box>>) -> !fir.ptr> +! CHECK: fir.result %[[ADDR]] : !fir.ptr> +! CHECK: } else { +! CHECK: %[[ABSENT:.*]] = fir.absent !fir.ptr> +! CHECK: fir.result %[[ABSENT]] : !fir.ptr> +! CHECK: } +! CHECK: %[[ATTACH:.*]] = acc.attach varPtr(%[[BOX_ADDR]] : !fir.ptr>) bounds(%[[BOUND]]) -> !fir.ptr> {name = "a"} +! CHECK: acc.data dataOperands(%[[ATTACH]] : !fir.ptr>) + end module diff --git a/flang/test/Lower/OpenACC/acc-data.f90 b/flang/test/Lower/OpenACC/acc-data.f90 index d302be85c5df4627b9a6aaf18b0949c732d26ce9..a6572e14707606a7645cd2a529c1834239b05c64 100644 --- a/flang/test/Lower/OpenACC/acc-data.f90 +++ b/flang/test/Lower/OpenACC/acc-data.f90 @@ -198,4 +198,3 @@ subroutine acc_data ! CHECK-NOT: acc.data end subroutine acc_data - diff --git a/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90 b/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90 index d7131296757917fd6170a154853eef3e2bbe2b59..8533106b7ac487110753a08250529fedd570b101 100644 --- a/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90 +++ b/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90 @@ -4,20 +4,20 @@ ! CHECK-LABEL: multiple_private_fix ! CHECK-SAME: %[[GAMA:.*]]: !fir.ref {fir.bindc_name = "gama"} -! CHECK: %[[GAMA_DECL:.*]]:2 = hlfir.declare %[[GAMA]] {uniq_name = "_QFmultiple_private_fixEgama"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFmultiple_private_fixEi"} -! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFmultiple_private_fixEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFmultiple_private_fixEj"} -! CHECK: %[[J_DECL:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFmultiple_private_fixEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFmultiple_private_fixEx"} -! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFmultiple_private_fixEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK-DAG: %[[GAMA_DECL:.*]]:2 = hlfir.declare %[[GAMA]] {uniq_name = "_QFmultiple_private_fixEgama"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK-DAG: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFmultiple_private_fixEi"} +! CHECK-DAG: %[[I_DECL:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFmultiple_private_fixEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK-DAG: %[[VAL_1:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFmultiple_private_fixEj"} +! CHECK-DAG: %[[J_DECL:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFmultiple_private_fixEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK-DAG: %[[VAL_2:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFmultiple_private_fixEx"} +! CHECK-DAG: %[[X_DECL:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFmultiple_private_fixEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: omp.parallel { -! CHECK: %[[PRIV_I:.*]] = fir.alloca i32 {adapt.valuebyref, pinned} -! CHECK: %[[PRIV_I_DECL:.*]]:2 = hlfir.declare %[[PRIV_I]] {uniq_name = "_QFmultiple_private_fixEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: %[[PRIV_J:.*]] = fir.alloca i32 {bindc_name = "j", pinned, uniq_name = "_QFmultiple_private_fixEj"} -! CHECK: %[[PRIV_J_DECL:.*]]:2 = hlfir.declare %[[PRIV_J]] {uniq_name = "_QFmultiple_private_fixEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: %[[PRIV_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned -! CHECK: %[[PRIV_X_DECL:.*]]:2 = hlfir.declare %[[PRIV_X]] {uniq_name = "_QFmultiple_private_fixEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK-DAG: %[[PRIV_I:.*]] = fir.alloca i32 {adapt.valuebyref, pinned} +! CHECK-DAG: %[[PRIV_I_DECL:.*]]:2 = hlfir.declare %[[PRIV_I]] {uniq_name = "_QFmultiple_private_fixEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK-DAG: %[[PRIV_J:.*]] = fir.alloca i32 {bindc_name = "j", pinned, uniq_name = "_QFmultiple_private_fixEj"} +! CHECK-DAG: %[[PRIV_J_DECL:.*]]:2 = hlfir.declare %[[PRIV_J]] {uniq_name = "_QFmultiple_private_fixEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK-DAG: %[[PRIV_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned +! CHECK-DAG: %[[PRIV_X_DECL:.*]]:2 = hlfir.declare %[[PRIV_X]] {uniq_name = "_QFmultiple_private_fixEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: %[[ONE:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_3:.*]] = fir.load %[[GAMA_DECL]]#0 : !fir.ref ! CHECK: %[[VAL_5:.*]] = arith.constant 1 : i32 diff --git a/flang/test/Lower/PowerPC/ppc-vec-convert.f90 b/flang/test/Lower/PowerPC/ppc-vec-convert.f90 index 14e247f83df67a9641d69e9d93c6621a1290bc6d..0f449a86dbe96f9d7858e3f97f5532f9ea133cca 100644 --- a/flang/test/Lower/PowerPC/ppc-vec-convert.f90 +++ b/flang/test/Lower/PowerPC/ppc-vec-convert.f90 @@ -1,4 +1,5 @@ -! RUN: %flang_fc1 -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-LE" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-BE" %s ! REQUIRES: target=powerpc{{.*}} !--------- @@ -1316,10 +1317,11 @@ subroutine vec_cvf_test_r4r8(arg1) ! LLVMIR: %[[arg:.*]] = load <2 x double>, ptr %{{.*}}, align 16 ! LLVMIR: %[[call:.*]] = call contract <4 x float> @llvm.ppc.vsx.xvcvdpsp(<2 x double> %[[arg]]) -! LLVMIR: %[[b:.*]] = bitcast <4 x float> %[[call]] to <16 x i8> -! LLVMIR: %[[sh:.*]] = shufflevector <16 x i8> %[[b]], <16 x i8> %[[b]], <16 x i32> -! LLVMIR: %[[r:.*]] = bitcast <16 x i8> %[[sh]] to <4 x float> -! LLVMIR: store <4 x float> %[[r]], ptr %{{.*}}, align 16 +! LLVMIR-LE: %[[b:.*]] = bitcast <4 x float> %[[call]] to <16 x i8> +! LLVMIR-LE: %[[sh:.*]] = shufflevector <16 x i8> %[[b]], <16 x i8> %[[b]], <16 x i32> +! LLVMIR-LE: %[[r:.*]] = bitcast <16 x i8> %[[sh]] to <4 x float> +! LLVMIR-LE: store <4 x float> %[[r]], ptr %{{.*}}, align 16 +! LLVMIR-BE: store <4 x float> %[[call]], ptr %{{.*}}, align 16 end subroutine vec_cvf_test_r4r8 ! CHECK-LABEL: vec_cvf_test_r8r4 @@ -1329,10 +1331,12 @@ subroutine vec_cvf_test_r8r4(arg1) r = vec_cvf(arg1) ! LLVMIR: %[[arg:.*]] = load <4 x float>, ptr %{{.*}}, align 16 -! LLVMIR: %[[bfi:.*]] = bitcast <4 x float> %[[arg]] to <16 x i8> -! LLVMIR: %[[sh:.*]] = shufflevector <16 x i8> %[[bfi]], <16 x i8> %[[bfi]], <16 x i32> -! LLVMIR: %[[bif:.*]] = bitcast <16 x i8> %[[sh]] to <4 x float> -! LLVMIR: %[[r:.*]] = call contract <2 x double> @llvm.ppc.vsx.xvcvspdp(<4 x float> %[[bif]]) -! LLVMIR: store <2 x double> %[[r]], ptr %{{.*}}, align 16 +! LLVMIR-LE: %[[bfi:.*]] = bitcast <4 x float> %[[arg]] to <16 x i8> +! LLVMIR-LE: %[[sh:.*]] = shufflevector <16 x i8> %[[bfi]], <16 x i8> %[[bfi]], <16 x i32> +! LLVMIR-LE: %[[bif:.*]] = bitcast <16 x i8> %[[sh]] to <4 x float> +! LLVMIR-LE: %[[r:.*]] = call contract <2 x double> @llvm.ppc.vsx.xvcvspdp(<4 x float> %[[bif]]) +! LLVMIR-LE: store <2 x double> %[[r]], ptr %{{.*}}, align 16 +! LLVMIR-BE: %[[r:.*]] = call contract <2 x double> @llvm.ppc.vsx.xvcvspdp(<4 x float> %[[arg]]) +! LLVMIR-BE: store <2 x double> %[[call]], ptr %{{.*}}, align 16 end subroutine vec_cvf_test_r8r4 diff --git a/flang/test/Lower/PowerPC/ppc-vec-extract.f90 b/flang/test/Lower/PowerPC/ppc-vec-extract.f90 index 1930c8b79d837c16a6be427d50ca7f3c7e962ae5..0f279347b6b75cbc0dfb80f00632ea714a9e0213 100644 --- a/flang/test/Lower/PowerPC/ppc-vec-extract.f90 +++ b/flang/test/Lower/PowerPC/ppc-vec-extract.f90 @@ -1,4 +1,5 @@ -! RUN: %flang_fc1 -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-LE" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-BE" %s ! REQUIRES: target=powerpc{{.*}} !------------- @@ -17,7 +18,9 @@ subroutine vec_extract_testf32(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[u:.*]] = urem i8 %[[i1]], 4 -! LLVMIR: %[[r:.*]] = extractelement <4 x float> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i8 3, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <4 x float> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <4 x float> %[[x]], i8 %[[s]] ! LLVMIR: store float %[[r]], ptr %{{[0-9]}}, align 4 r = vec_extract(x, i2) @@ -25,7 +28,9 @@ subroutine vec_extract_testf32(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[u:.*]] = urem i16 %[[i2]], 4 -! LLVMIR: %[[r:.*]] = extractelement <4 x float> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i16 3, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <4 x float> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <4 x float> %[[x]], i16 %[[s]] ! LLVMIR: store float %[[r]], ptr %{{[0-9]}}, align 4 r = vec_extract(x, i4) @@ -33,7 +38,9 @@ subroutine vec_extract_testf32(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[u:.*]] = urem i32 %[[i4]], 4 -! LLVMIR: %[[r:.*]] = extractelement <4 x float> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i32 3, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <4 x float> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <4 x float> %[[x]], i32 %[[s]] ! LLVMIR: store float %[[r]], ptr %{{[0-9]}}, align 4 r = vec_extract(x, i8) @@ -41,7 +48,9 @@ subroutine vec_extract_testf32(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[u:.*]] = urem i64 %[[i8]], 4 -! LLVMIR: %[[r:.*]] = extractelement <4 x float> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i64 3, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <4 x float> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <4 x float> %[[x]], i64 %[[s]] ! LLVMIR: store float %[[r]], ptr %{{[0-9]}}, align 4 end subroutine vec_extract_testf32 @@ -58,7 +67,9 @@ subroutine vec_extract_testf64(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[u:.*]] = urem i8 %[[i1]], 2 -! LLVMIR: %[[r:.*]] = extractelement <2 x double> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i8 1, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <2 x double> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <2 x double> %[[x]], i8 %[[s]] ! LLVMIR: store double %[[r]], ptr %{{[0-9]}}, align 8 r = vec_extract(x, i2) @@ -66,15 +77,20 @@ subroutine vec_extract_testf64(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[u:.*]] = urem i16 %[[i2]], 2 -! LLVMIR: %[[r:.*]] = extractelement <2 x double> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i16 1, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <2 x double> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <2 x double> %[[x]], i16 %[[s]] ! LLVMIR: store double %[[r]], ptr %{{[0-9]}}, align 8 + r = vec_extract(x, i4) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[u:.*]] = urem i32 %[[i4]], 2 -! LLVMIR: %[[r:.*]] = extractelement <2 x double> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i32 1, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <2 x double> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <2 x double> %[[x]], i32 %[[s]] ! LLVMIR: store double %[[r]], ptr %{{[0-9]}}, align 8 r = vec_extract(x, i8) @@ -82,7 +98,9 @@ subroutine vec_extract_testf64(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[u:.*]] = urem i64 %[[i8]], 2 -! LLVMIR: %[[r:.*]] = extractelement <2 x double> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i64 1, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <2 x double> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <2 x double> %[[x]], i64 %[[s]] ! LLVMIR: store double %[[r]], ptr %{{[0-9]}}, align 8 end subroutine vec_extract_testf64 @@ -99,7 +117,9 @@ subroutine vec_extract_testi8(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[u:.*]] = urem i8 %[[i1]], 16 -! LLVMIR: %[[r:.*]] = extractelement <16 x i8> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i8 15, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <16 x i8> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <16 x i8> %[[x]], i8 %[[s]] ! LLVMIR: store i8 %[[r]], ptr %{{[0-9]}}, align 1 r = vec_extract(x, i2) @@ -107,7 +127,9 @@ subroutine vec_extract_testi8(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[u:.*]] = urem i16 %[[i2]], 16 -! LLVMIR: %[[r:.*]] = extractelement <16 x i8> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i16 15, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <16 x i8> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <16 x i8> %[[x]], i16 %[[s]] ! LLVMIR: store i8 %[[r]], ptr %{{[0-9]}}, align 1 r = vec_extract(x, i4) @@ -115,7 +137,9 @@ subroutine vec_extract_testi8(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[u:.*]] = urem i32 %[[i4]], 16 -! LLVMIR: %[[r:.*]] = extractelement <16 x i8> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i32 15, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <16 x i8> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <16 x i8> %[[x]], i32 %[[s]] ! LLVMIR: store i8 %[[r]], ptr %{{[0-9]}}, align 1 r = vec_extract(x, i8) @@ -123,7 +147,9 @@ subroutine vec_extract_testi8(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[u:.*]] = urem i64 %[[i8]], 16 -! LLVMIR: %[[r:.*]] = extractelement <16 x i8> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i64 15, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <16 x i8> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <16 x i8> %[[x]], i64 %[[s]] ! LLVMIR: store i8 %[[r]], ptr %{{[0-9]}}, align 1 end subroutine vec_extract_testi8 @@ -140,7 +166,9 @@ subroutine vec_extract_testi16(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[u:.*]] = urem i8 %[[i1]], 8 -! LLVMIR: %[[r:.*]] = extractelement <8 x i16> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i8 7, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <8 x i16> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <8 x i16> %[[x]], i8 %[[s]] ! LLVMIR: store i16 %[[r]], ptr %{{[0-9]}}, align 2 r = vec_extract(x, i2) @@ -148,7 +176,9 @@ subroutine vec_extract_testi16(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[u:.*]] = urem i16 %[[i2]], 8 -! LLVMIR: %[[r:.*]] = extractelement <8 x i16> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i16 7, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <8 x i16> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <8 x i16> %[[x]], i16 %[[s]] ! LLVMIR: store i16 %[[r]], ptr %{{[0-9]}}, align 2 r = vec_extract(x, i4) @@ -156,7 +186,9 @@ subroutine vec_extract_testi16(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[u:.*]] = urem i32 %[[i4]], 8 -! LLVMIR: %[[r:.*]] = extractelement <8 x i16> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i32 7, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <8 x i16> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <8 x i16> %[[x]], i32 %[[s]] ! LLVMIR: store i16 %[[r]], ptr %{{[0-9]}}, align 2 r = vec_extract(x, i8) @@ -164,7 +196,9 @@ subroutine vec_extract_testi16(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[u:.*]] = urem i64 %[[i8]], 8 -! LLVMIR: %[[r:.*]] = extractelement <8 x i16> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i64 7, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <8 x i16> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <8 x i16> %[[x]], i64 %[[s]] ! LLVMIR: store i16 %[[r]], ptr %{{[0-9]}}, align 2 end subroutine vec_extract_testi16 @@ -181,7 +215,9 @@ subroutine vec_extract_testi32(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[u:.*]] = urem i8 %[[i1]], 4 -! LLVMIR: %[[r:.*]] = extractelement <4 x i32> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i8 3, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <4 x i32> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <4 x i32> %[[x]], i8 %[[s]] ! LLVMIR: store i32 %[[r]], ptr %{{[0-9]}}, align 4 r = vec_extract(x, i2) @@ -189,7 +225,9 @@ subroutine vec_extract_testi32(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[u:.*]] = urem i16 %[[i2]], 4 -! LLVMIR: %[[r:.*]] = extractelement <4 x i32> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i16 3, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <4 x i32> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <4 x i32> %[[x]], i16 %[[s]] ! LLVMIR: store i32 %[[r]], ptr %{{[0-9]}}, align 4 r = vec_extract(x, i4) @@ -197,7 +235,9 @@ subroutine vec_extract_testi32(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[u:.*]] = urem i32 %[[i4]], 4 -! LLVMIR: %[[r:.*]] = extractelement <4 x i32> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i32 3, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <4 x i32> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <4 x i32> %[[x]], i32 %[[s]] ! LLVMIR: store i32 %[[r]], ptr %{{[0-9]}}, align 4 r = vec_extract(x, i8) @@ -205,7 +245,9 @@ subroutine vec_extract_testi32(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[u:.*]] = urem i64 %[[i8]], 4 -! LLVMIR: %[[r:.*]] = extractelement <4 x i32> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i64 3, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <4 x i32> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <4 x i32> %[[x]], i64 %[[s]] ! LLVMIR: store i32 %[[r]], ptr %{{[0-9]}}, align 4 end subroutine vec_extract_testi32 @@ -222,7 +264,9 @@ subroutine vec_extract_testi64(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[u:.*]] = urem i8 %[[i1]], 2 -! LLVMIR: %[[r:.*]] = extractelement <2 x i64> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i8 1, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <2 x i64> %[[x]], i8 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <2 x i64> %[[x]], i8 %[[s]] ! LLVMIR: store i64 %[[r]], ptr %{{[0-9]}}, align 8 r = vec_extract(x, i2) @@ -230,7 +274,9 @@ subroutine vec_extract_testi64(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[u:.*]] = urem i16 %[[i2]], 2 -! LLVMIR: %[[r:.*]] = extractelement <2 x i64> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i16 1, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <2 x i64> %[[x]], i16 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <2 x i64> %[[x]], i16 %[[s]] ! LLVMIR: store i64 %[[r]], ptr %{{[0-9]}}, align 8 r = vec_extract(x, i4) @@ -238,7 +284,9 @@ subroutine vec_extract_testi64(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[u:.*]] = urem i32 %[[i4]], 2 -! LLVMIR: %[[r:.*]] = extractelement <2 x i64> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i32 1, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <2 x i64> %[[x]], i32 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <2 x i64> %[[x]], i32 %[[s]] ! LLVMIR: store i64 %[[r]], ptr %{{[0-9]}}, align 8 r = vec_extract(x, i8) @@ -246,6 +294,8 @@ subroutine vec_extract_testi64(x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[u:.*]] = urem i64 %[[i8]], 2 -! LLVMIR: %[[r:.*]] = extractelement <2 x i64> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[s:.*]] = sub i64 1, %[[u]] +! LLVMIR-LE: %[[r:.*]] = extractelement <2 x i64> %[[x]], i64 %[[u]] +! LLVMIR-BE: %[[r:.*]] = extractelement <2 x i64> %[[x]], i64 %[[s]] ! LLVMIR: store i64 %[[r]], ptr %{{[0-9]}}, align 8 end subroutine vec_extract_testi64 diff --git a/flang/test/Lower/PowerPC/ppc-vec-insert.f90 b/flang/test/Lower/PowerPC/ppc-vec-insert.f90 index 3648be6ac027e3035c196e5b8dda7761116421b1..dd57fcc67be0809abebc6e72c2bd34ba9b2aa026 100644 --- a/flang/test/Lower/PowerPC/ppc-vec-insert.f90 +++ b/flang/test/Lower/PowerPC/ppc-vec-insert.f90 @@ -1,4 +1,5 @@ -! RUN: %flang_fc1 -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-LE" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-BE" %s ! REQUIRES: target=powerpc{{.*}} ! vec_insert @@ -18,7 +19,9 @@ subroutine vec_insert_testf32(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[urem:.*]] = urem i8 %[[i1]], 4 -! LLVMIR: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i8 3, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i8 %[[s]] ! LLVMIR: store <4 x float> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i2) @@ -27,7 +30,9 @@ subroutine vec_insert_testf32(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[urem:.*]] = urem i16 %[[i2]], 4 -! LLVMIR: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i16 3, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i16 %[[s]] ! LLVMIR: store <4 x float> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i4) @@ -36,7 +41,9 @@ subroutine vec_insert_testf32(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[urem:.*]] = urem i32 %[[i4]], 4 -! LLVMIR: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i32 3, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i32 %[[s]] ! LLVMIR: store <4 x float> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i8) @@ -45,7 +52,9 @@ subroutine vec_insert_testf32(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[urem:.*]] = urem i64 %[[i8]], 4 -! LLVMIR: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i64 3, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <4 x float> %[[x]], float %[[v]], i64 %[[s]] ! LLVMIR: store <4 x float> %[[r]], ptr %{{[0-9]}}, align 16 end subroutine vec_insert_testf32 @@ -64,7 +73,9 @@ subroutine vec_insert_testf64(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[urem:.*]] = urem i8 %[[i1]], 2 -! LLVMIR: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i8 1, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i8 %[[s]] ! LLVMIR: store <2 x double> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i2) @@ -73,7 +84,9 @@ subroutine vec_insert_testf64(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[urem:.*]] = urem i16 %[[i2]], 2 -! LLVMIR: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i16 1, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i16 %[[s]] ! LLVMIR: store <2 x double> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i4) @@ -82,7 +95,9 @@ subroutine vec_insert_testf64(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[urem:.*]] = urem i32 %[[i4]], 2 -! LLVMIR: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i32 1, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i32 %[[s]] ! LLVMIR: store <2 x double> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i8) @@ -91,7 +106,9 @@ subroutine vec_insert_testf64(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[urem:.*]] = urem i64 %[[i8]], 2 -! LLVMIR: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i64 1, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <2 x double> %[[x]], double %[[v]], i64 %[[s]] ! LLVMIR: store <2 x double> %[[r]], ptr %{{[0-9]}}, align 16 end subroutine vec_insert_testf64 @@ -110,7 +127,9 @@ subroutine vec_insert_testi8(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[urem:.*]] = urem i8 %[[i1]], 16 -! LLVMIR: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i8 15, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i8 %[[s]] ! LLVMIR: store <16 x i8> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i2) @@ -119,7 +138,9 @@ subroutine vec_insert_testi8(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[urem:.*]] = urem i16 %[[i2]], 16 -! LLVMIR: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i16 15, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i16 %[[s]] ! LLVMIR: store <16 x i8> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i4) @@ -128,7 +149,9 @@ subroutine vec_insert_testi8(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[urem:.*]] = urem i32 %[[i4]], 16 -! LLVMIR: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i32 15, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i32 %[[s]] ! LLVMIR: store <16 x i8> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i8) @@ -137,7 +160,9 @@ subroutine vec_insert_testi8(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[urem:.*]] = urem i64 %[[i8]], 16 -! LLVMIR: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i64 15, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <16 x i8> %[[x]], i8 %[[v]], i64 %[[s]] ! LLVMIR: store <16 x i8> %[[r]], ptr %{{[0-9]}}, align 16 end subroutine vec_insert_testi8 @@ -156,7 +181,9 @@ subroutine vec_insert_testi16(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[urem:.*]] = urem i8 %[[i1]], 8 -! LLVMIR: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i8 7, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i8 %[[s]] ! LLVMIR: store <8 x i16> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i2) @@ -165,7 +192,9 @@ subroutine vec_insert_testi16(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[urem:.*]] = urem i16 %[[i2]], 8 -! LLVMIR: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i16 7, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i16 %[[s]] ! LLVMIR: store <8 x i16> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i4) @@ -174,7 +203,9 @@ subroutine vec_insert_testi16(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[urem:.*]] = urem i32 %[[i4]], 8 -! LLVMIR: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i32 7, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i32 %[[s]] ! LLVMIR: store <8 x i16> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i8) @@ -183,7 +214,9 @@ subroutine vec_insert_testi16(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[urem:.*]] = urem i64 %[[i8]], 8 -! LLVMIR: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i64 7, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <8 x i16> %[[x]], i16 %[[v]], i64 %[[s]] ! LLVMIR: store <8 x i16> %[[r]], ptr %{{[0-9]}}, align 16 end subroutine vec_insert_testi16 @@ -202,7 +235,9 @@ subroutine vec_insert_testi32(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[urem:.*]] = urem i8 %[[i1]], 4 -! LLVMIR: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i8 3, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i8 %[[s]] ! LLVMIR: store <4 x i32> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i2) @@ -211,7 +246,9 @@ subroutine vec_insert_testi32(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[urem:.*]] = urem i16 %[[i2]], 4 -! LLVMIR: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i16 3, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i16 %[[s]] ! LLVMIR: store <4 x i32> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i4) @@ -220,7 +257,9 @@ subroutine vec_insert_testi32(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[urem:.*]] = urem i32 %[[i4]], 4 -! LLVMIR: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i32 3, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i32 %[[s]] ! LLVMIR: store <4 x i32> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i8) @@ -229,7 +268,9 @@ subroutine vec_insert_testi32(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[urem:.*]] = urem i64 %[[i8]], 4 -! LLVMIR: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i64 3, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <4 x i32> %[[x]], i32 %[[v]], i64 %[[s]] ! LLVMIR: store <4 x i32> %[[r]], ptr %{{[0-9]}}, align 16 end subroutine vec_insert_testi32 @@ -248,7 +289,9 @@ subroutine vec_insert_testi64(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i1:.*]] = load i8, ptr %{{[0-9]}}, align 1 ! LLVMIR: %[[urem:.*]] = urem i8 %[[i1]], 2 -! LLVMIR: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i8 1, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i8 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i8 %[[s]] ! LLVMIR: store <2 x i64> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i2) @@ -257,7 +300,9 @@ subroutine vec_insert_testi64(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i2:.*]] = load i16, ptr %{{[0-9]}}, align 2 ! LLVMIR: %[[urem:.*]] = urem i16 %[[i2]], 2 -! LLVMIR: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i16 1, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i16 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i16 %[[s]] ! LLVMIR: store <2 x i64> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i4) @@ -266,7 +311,9 @@ subroutine vec_insert_testi64(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i4:.*]] = load i32, ptr %{{[0-9]}}, align 4 ! LLVMIR: %[[urem:.*]] = urem i32 %[[i4]], 2 -! LLVMIR: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i32 1, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i32 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i32 %[[s]] ! LLVMIR: store <2 x i64> %[[r]], ptr %{{[0-9]}}, align 16 r = vec_insert(v, x, i8) @@ -275,6 +322,8 @@ subroutine vec_insert_testi64(v, x, i1, i2, i4, i8) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 ! LLVMIR: %[[i8:.*]] = load i64, ptr %{{[0-9]}}, align 8 ! LLVMIR: %[[urem:.*]] = urem i64 %[[i8]], 2 -! LLVMIR: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[s:.*]] = sub i64 1, %[[urem]] +! LLVMIR-LE: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i64 %[[urem]] +! LLVMIR-BE: %[[r:.*]] = insertelement <2 x i64> %[[x]], i64 %[[v]], i64 %[[s]] ! LLVMIR: store <2 x i64> %[[r]], ptr %{{[0-9]}}, align 16 end subroutine vec_insert_testi64 diff --git a/flang/test/Lower/PowerPC/ppc-vec-load.f90 b/flang/test/Lower/PowerPC/ppc-vec-load.f90 index 1da6381905142ce944f5da78583ee4444ba16a16..4d51512df0f7b485c919d958be58842633c23b1d 100644 --- a/flang/test/Lower/PowerPC/ppc-vec-load.f90 +++ b/flang/test/Lower/PowerPC/ppc-vec-load.f90 @@ -1,4 +1,5 @@ -! RUN: %flang_fc1 -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-LE" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-BE" %s ! REQUIRES: target=powerpc{{.*}} !---------------------- @@ -294,8 +295,9 @@ subroutine vec_lvsl_testi8s(arg1, arg2, res) ! LLVMIR: %[[rshft:.*]] = ashr i64 %[[lshft]], 56 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i64 %[[rshft]] ! LLVMIR: %[[ld:.*]] = call <16 x i8> @llvm.ppc.altivec.lvsl(ptr %[[addr]]) -! LLVMIR: %[[sv:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> -! LLVMIR: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-LE: %[[sv:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> +! LLVMIR-LE: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-BE: store <16 x i8> %[[ld]], ptr %2, align 16 end subroutine vec_lvsl_testi8s ! CHECK-LABEL: @vec_lvsl_testi16a @@ -311,8 +313,9 @@ subroutine vec_lvsl_testi16a(arg1, arg2, res) ! LLVMIR: %[[rshft:.*]] = ashr i64 %[[lshft]], 56 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i64 %[[rshft]] ! LLVMIR: %[[ld:.*]] = call <16 x i8> @llvm.ppc.altivec.lvsl(ptr %[[addr]]) -! LLVMIR: %[[sv:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> -! LLVMIR: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-LE: %[[sv:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> +! LLVMIR-LE: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-BE: store <16 x i8> %[[ld]], ptr %2, align 16 end subroutine vec_lvsl_testi16a ! CHECK-LABEL: @vec_lvsl_testi32a @@ -328,8 +331,9 @@ subroutine vec_lvsl_testi32a(arg1, arg2, res) ! LLVMIR: %[[rshft:.*]] = ashr i64 %[[lshft]], 56 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i64 %[[rshft]] ! LLVMIR: %[[ld:.*]] = call <16 x i8> @llvm.ppc.altivec.lvsl(ptr %[[addr]]) -! LLVMIR: %[[sv:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> -! LLVMIR: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-LE: %[[sv:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> +! LLVMIR-LE: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-BE: store <16 x i8> %[[ld]], ptr %2, align 16 end subroutine vec_lvsl_testi32a ! CHECK-LABEL: @vec_lvsl_testf32a @@ -344,8 +348,9 @@ subroutine vec_lvsl_testf32a(arg1, arg2, res) ! LLVMIR: %[[rshft:.*]] = ashr i64 %[[lshft]], 56 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i64 %[[rshft]] ! LLVMIR: %[[ld:.*]] = call <16 x i8> @llvm.ppc.altivec.lvsl(ptr %[[addr]]) -! LLVMIR: %[[sv:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> -! LLVMIR: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-LE: %[[sv:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> +! LLVMIR-LE: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-BE: store <16 x i8> %[[ld]], ptr %2, align 16 end subroutine vec_lvsl_testf32a !---------------------- @@ -365,8 +370,9 @@ subroutine vec_lvsr_testi8s(arg1, arg2, res) ! LLVMIR: %[[rshft:.*]] = ashr i64 %[[lshft]], 56 ! LLVMIR: %[[ld:.*]] = getelementptr i8, ptr %1, i64 %[[rshft]] ! LLVMIR: %[[addr:.*]] = call <16 x i8> @llvm.ppc.altivec.lvsr(ptr %[[ld]]) -! LLVMIR: %[[sv:.*]] = shufflevector <16 x i8> %[[addr]], <16 x i8> undef, <16 x i32> -! LLVMIR: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-LE: %[[sv:.*]] = shufflevector <16 x i8> %[[addr]], <16 x i8> undef, <16 x i32> +! LLVMIR-LE: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-BE: store <16 x i8> %[[addr]], ptr %2, align 16 end subroutine vec_lvsr_testi8s ! CHECK-LABEL: @vec_lvsr_testi16a @@ -382,8 +388,9 @@ subroutine vec_lvsr_testi16a(arg1, arg2, res) ! LLVMIR: %[[rshft:.*]] = ashr i64 %[[lshft]], 56 ! LLVMIR: %[[ld:.*]] = getelementptr i8, ptr %1, i64 %[[rshft]] ! LLVMIR: %[[addr:.*]] = call <16 x i8> @llvm.ppc.altivec.lvsr(ptr %[[ld]]) -! LLVMIR: %[[sv:.*]] = shufflevector <16 x i8> %[[addr]], <16 x i8> undef, <16 x i32> -! LLVMIR: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-LE: %[[sv:.*]] = shufflevector <16 x i8> %[[addr]], <16 x i8> undef, <16 x i32> +! LLVMIR-LE: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-BE: store <16 x i8> %[[addr]], ptr %2, align 16 end subroutine vec_lvsr_testi16a ! CHECK-LABEL: @vec_lvsr_testi32a @@ -399,8 +406,9 @@ subroutine vec_lvsr_testi32a(arg1, arg2, res) ! LLVMIR: %[[rshft:.*]] = ashr i64 %[[lshft]], 56 ! LLVMIR: %[[ld:.*]] = getelementptr i8, ptr %1, i64 %[[rshft]] ! LLVMIR: %[[addr:.*]] = call <16 x i8> @llvm.ppc.altivec.lvsr(ptr %[[ld]]) -! LLVMIR: %[[sv:.*]] = shufflevector <16 x i8> %[[addr]], <16 x i8> undef, <16 x i32> -! LLVMIR: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-LE: %[[sv:.*]] = shufflevector <16 x i8> %[[addr]], <16 x i8> undef, <16 x i32> +! LLVMIR-LE: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-BE: store <16 x i8> %[[addr]], ptr %2, align 16 end subroutine vec_lvsr_testi32a ! CHECK-LABEL: @vec_lvsr_testf32a @@ -415,8 +423,9 @@ subroutine vec_lvsr_testf32a(arg1, arg2, res) ! LLVMIR: %[[rshft:.*]] = ashr i64 %[[lshft]], 56 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i64 %[[rshft]] ! LLVMIR: %[[ld:.*]] = call <16 x i8> @llvm.ppc.altivec.lvsr(ptr %[[addr]]) -! LLVMIR: %[[sv:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> -! LLVMIR: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-LE: %[[sv:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> +! LLVMIR-LE: store <16 x i8> %[[sv]], ptr %2, align 16 +! LLVMIR-BE: store <16 x i8> %[[ld]], ptr %2, align 16 end subroutine vec_lvsr_testf32a !---------------------- @@ -708,8 +717,9 @@ subroutine vec_xl_be_testi8a(arg1, arg2, res) ! LLVMIR: %[[arg1:.*]] = load i8, ptr %0, align 1 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i8 %[[arg1]] ! LLVMIR: %[[ld:.*]] = load <16 x i8>, ptr %[[addr]], align 1 -! LLVMIR: %[[shff:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> -! LLVMIR: store <16 x i8> %[[shff]], ptr %2, align 16 +! LLVMIR-LE: %[[shff:.*]] = shufflevector <16 x i8> %[[ld]], <16 x i8> undef, <16 x i32> +! LLVMIR-LE: store <16 x i8> %[[shff]], ptr %2, align 16 +! LLVMIR-BE: store <16 x i8> %[[ld]], ptr %2, align 16 end subroutine vec_xl_be_testi8a ! CHECK-LABEL: @vec_xl_be_testi16a @@ -722,8 +732,9 @@ subroutine vec_xl_be_testi16a(arg1, arg2, res) ! LLVMIR: %[[arg1:.*]] = load i16, ptr %0, align 2 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i16 %[[arg1]] ! LLVMIR: %[[ld:.*]] = load <8 x i16>, ptr %[[addr]], align 1 -! LLVMIR: %[[shff:.*]] = shufflevector <8 x i16> %[[ld]], <8 x i16> undef, <8 x i32> -! LLVMIR: store <8 x i16> %[[shff]], ptr %2, align 16 +! LLVMIR-LE: %[[shff:.*]] = shufflevector <8 x i16> %[[ld]], <8 x i16> undef, <8 x i32> +! LLVMIR-LE: store <8 x i16> %[[shff]], ptr %2, align 16 +! LLVMIR-BE: store <8 x i16> %[[ld]], ptr %2, align 16 end subroutine vec_xl_be_testi16a ! CHECK-LABEL: @vec_xl_be_testi32a @@ -736,8 +747,9 @@ subroutine vec_xl_be_testi32a(arg1, arg2, res) ! LLVMIR: %[[arg1:.*]] = load i32, ptr %0, align 4 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i32 %[[arg1]] ! LLVMIR: %[[ld:.*]] = load <4 x i32>, ptr %[[addr]], align 1 -! LLVMIR: %[[shff:.*]] = shufflevector <4 x i32> %[[ld]], <4 x i32> undef, <4 x i32> -! LLVMIR: store <4 x i32> %[[shff]], ptr %2, align 16 +! LLVMIR-LE: %[[shff:.*]] = shufflevector <4 x i32> %[[ld]], <4 x i32> undef, <4 x i32> +! LLVMIR-LE: store <4 x i32> %[[shff]], ptr %2, align 16 +! LLVMIR-BE: store <4 x i32> %[[ld]], ptr %2, align 16 end subroutine vec_xl_be_testi32a ! CHECK-LABEL: @vec_xl_be_testi64a @@ -750,8 +762,9 @@ subroutine vec_xl_be_testi64a(arg1, arg2, res) ! LLVMIR: %[[arg1:.*]] = load i64, ptr %0, align 8 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i64 %[[arg1]] ! LLVMIR: %[[ld:.*]] = load <2 x i64>, ptr %[[addr]], align 1 -! LLVMIR: %[[shff:.*]] = shufflevector <2 x i64> %[[ld]], <2 x i64> undef, <2 x i32> -! LLVMIR: store <2 x i64> %[[shff]], ptr %2, align 16 +! LLVMIR-LE: %[[shff:.*]] = shufflevector <2 x i64> %[[ld]], <2 x i64> undef, <2 x i32> +! LLVMIR-LE: store <2 x i64> %[[shff]], ptr %2, align 16 +! LLVMIR-BE: store <2 x i64> %[[ld]], ptr %2, align 16 end subroutine vec_xl_be_testi64a ! CHECK-LABEL: @vec_xl_be_testf32a @@ -764,8 +777,9 @@ subroutine vec_xl_be_testf32a(arg1, arg2, res) ! LLVMIR: %[[arg1:.*]] = load i16, ptr %0, align 2 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i16 %[[arg1]] ! LLVMIR: %[[ld:.*]] = load <4 x float>, ptr %[[addr]], align 1 -! LLVMIR: %[[shff:.*]] = shufflevector <4 x float> %[[ld]], <4 x float> undef, <4 x i32> -! LLVMIR: store <4 x float> %[[shff]], ptr %2, align 16 +! LLVMIR-LE: %[[shff:.*]] = shufflevector <4 x float> %[[ld]], <4 x float> undef, <4 x i32> +! LLVMIR-LE: store <4 x float> %[[shff]], ptr %2, align 16 +! LLVMIR-BE: store <4 x float> %[[ld]], ptr %2, align 16 end subroutine vec_xl_be_testf32a ! CHECK-LABEL: @vec_xl_be_testf64a @@ -778,8 +792,9 @@ subroutine vec_xl_be_testf64a(arg1, arg2, res) ! LLVMIR: %[[arg1:.*]] = load i64, ptr %0, align 8 ! LLVMIR: %[[addr:.*]] = getelementptr i8, ptr %1, i64 %[[arg1]] ! LLVMIR: %[[ld:.*]] = load <2 x double>, ptr %[[addr]], align 1 -! LLVMIR: %[[shff:.*]] = shufflevector <2 x double> %[[ld]], <2 x double> undef, <2 x i32> -! LLVMIR: store <2 x double> %[[shff]], ptr %2, align 16 +! LLVMIR-LE: %[[shff:.*]] = shufflevector <2 x double> %[[ld]], <2 x double> undef, <2 x i32> +! LLVMIR-LE: store <2 x double> %[[shff]], ptr %2, align 16 +! LLVMIR-BE: store <2 x double> %[[ld]], ptr %2, align 16 end subroutine vec_xl_be_testf64a !---------------------- diff --git a/flang/test/Lower/PowerPC/ppc-vec-perm.f90 b/flang/test/Lower/PowerPC/ppc-vec-perm.f90 index 99a6295a014943fc563e7fc5493e12b7178c8760..5353e9c10db7dd638b57e886887dc3b662807038 100644 --- a/flang/test/Lower/PowerPC/ppc-vec-perm.f90 +++ b/flang/test/Lower/PowerPC/ppc-vec-perm.f90 @@ -1,4 +1,5 @@ -! RUN: %flang_fc1 -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-LE" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-BE" %s ! REQUIRES: target=powerpc{{.*}} ! CHECK-LABEL: vec_perm_test_i1 @@ -12,8 +13,9 @@ subroutine vec_perm_test_i1(arg1, arg2, arg3) ! LLVMIR: %[[arg3:.*]] = load <16 x i8>, ptr %{{.*}}, align 16 ! LLVMIR: %[[barg1:.*]] = bitcast <16 x i8> %[[arg1]] to <4 x i32> ! LLVMIR: %[[barg2:.*]] = bitcast <16 x i8> %[[arg2]] to <4 x i32> -! LLVMIR: %[[xor:.*]] = xor <16 x i8> %[[arg3]], -! LLVMIR: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-LE: %[[xor:.*]] = xor <16 x i8> %[[arg3]], +! LLVMIR-LE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-BE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg1]], <4 x i32> %[[barg2]], <16 x i8> %[[arg3]]) ! LLVMIR: %[[bcall:.*]] = bitcast <4 x i32> %[[call]] to <16 x i8> ! LLVMIR: store <16 x i8> %[[bcall]], ptr %{{.*}}, align 16 end subroutine vec_perm_test_i1 @@ -29,8 +31,9 @@ subroutine vec_perm_test_i2(arg1, arg2, arg3) ! LLVMIR: %[[arg3:.*]] = load <16 x i8>, ptr %{{.*}}, align 16 ! LLVMIR: %[[barg1:.*]] = bitcast <8 x i16> %[[arg1]] to <4 x i32> ! LLVMIR: %[[barg2:.*]] = bitcast <8 x i16> %[[arg2]] to <4 x i32> -! LLVMIR: %[[xor:.*]] = xor <16 x i8> %[[arg3]], -! LLVMIR: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-LE: %[[xor:.*]] = xor <16 x i8> %[[arg3]], +! LLVMIR-LE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-BE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg1]], <4 x i32> %[[barg2]], <16 x i8> %[[arg3]]) ! LLVMIR: %[[bcall:.*]] = bitcast <4 x i32> %[[call]] to <8 x i16> ! LLVMIR: store <8 x i16> %[[bcall]], ptr %{{.*}}, align 16 end subroutine vec_perm_test_i2 @@ -44,8 +47,9 @@ subroutine vec_perm_test_i4(arg1, arg2, arg3) ! LLVMIR: %[[arg1:.*]] = load <4 x i32>, ptr %{{.*}}, align 16 ! LLVMIR: %[[arg2:.*]] = load <4 x i32>, ptr %{{.*}}, align 16 ! LLVMIR: %[[arg3:.*]] = load <16 x i8>, ptr %{{.*}}, align 16 -! LLVMIR: %[[xor:.*]] = xor <16 x i8> %[[arg3]], -! LLVMIR: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[arg2]], <4 x i32> %[[arg1]], <16 x i8> %[[xor]]) +! LLVMIR-LE: %[[xor:.*]] = xor <16 x i8> %[[arg3]], +! LLVMIR-LE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[arg2]], <4 x i32> %[[arg1]], <16 x i8> %[[xor]]) +! LLVMIR-BE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[arg1]], <4 x i32> %[[arg2]], <16 x i8> %[[arg3]]) ! LLVMIR: store <4 x i32> %[[call]], ptr %{{.*}}, align 16 end subroutine vec_perm_test_i4 @@ -60,8 +64,9 @@ subroutine vec_perm_test_i8(arg1, arg2, arg3) ! LLVMIR: %[[arg3:.*]] = load <16 x i8>, ptr %{{.*}}, align 16 ! LLVMIR: %[[barg1:.*]] = bitcast <2 x i64> %[[arg1]] to <4 x i32> ! LLVMIR: %[[barg2:.*]] = bitcast <2 x i64> %[[arg2]] to <4 x i32> -! LLVMIR: %[[xor:.*]] = xor <16 x i8> %[[arg3]], -! LLVMIR: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-LE: %[[xor:.*]] = xor <16 x i8> %[[arg3]], +! LLVMIR-LE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-BE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg1]], <4 x i32> %[[barg2]], <16 x i8> %[[arg3]]) ! LLVMIR: %[[bcall:.*]] = bitcast <4 x i32> %[[call]] to <2 x i64> ! LLVMIR: store <2 x i64> %[[bcall]], ptr %{{.*}}, align 16 end subroutine vec_perm_test_i8 @@ -77,8 +82,9 @@ subroutine vec_perm_test_u1(arg1, arg2, arg3) ! LLVMIR: %[[arg3:.*]] = load <16 x i8>, ptr %{{.*}}, align 16 ! LLVMIR: %[[barg1:.*]] = bitcast <16 x i8> %[[arg1]] to <4 x i32> ! LLVMIR: %[[barg2:.*]] = bitcast <16 x i8> %[[arg2]] to <4 x i32> -! LLVMIR: %[[xor:.*]] = xor <16 x i8> %[[arg3]], -! LLVMIR: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-LE: %[[xor:.*]] = xor <16 x i8> %[[arg3]], +! LLVMIR-LE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-BE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg1]], <4 x i32> %[[barg2]], <16 x i8> %[[arg3]]) ! LLVMIR: %[[bcall:.*]] = bitcast <4 x i32> %[[call]] to <16 x i8> ! LLVMIR: store <16 x i8> %[[bcall]], ptr %{{.*}}, align 16 end subroutine vec_perm_test_u1 @@ -94,8 +100,9 @@ subroutine vec_perm_test_u2(arg1, arg2, arg3) ! LLVMIR: %[[arg3:.*]] = load <16 x i8>, ptr %{{.*}}, align 16 ! LLVMIR: %[[barg1:.*]] = bitcast <8 x i16> %[[arg1]] to <4 x i32> ! LLVMIR: %[[barg2:.*]] = bitcast <8 x i16> %[[arg2]] to <4 x i32> -! LLVMIR: %[[xor:.*]] = xor <16 x i8> %[[arg3]], -! LLVMIR: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-LE: %[[xor:.*]] = xor <16 x i8> %[[arg3]], +! LLVMIR-LE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-BE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg1]], <4 x i32> %[[barg2]], <16 x i8> %[[arg3]]) ! LLVMIR: %[[bcall:.*]] = bitcast <4 x i32> %[[call]] to <8 x i16> ! LLVMIR: store <8 x i16> %[[bcall]], ptr %{{.*}}, align 16 end subroutine vec_perm_test_u2 @@ -109,8 +116,9 @@ subroutine vec_perm_test_u4(arg1, arg2, arg3) ! LLVMIR: %[[arg1:.*]] = load <4 x i32>, ptr %{{.*}}, align 16 ! LLVMIR: %[[arg2:.*]] = load <4 x i32>, ptr %{{.*}}, align 16 ! LLVMIR: %[[arg3:.*]] = load <16 x i8>, ptr %{{.*}}, align 16 -! LLVMIR: %[[xor:.*]] = xor <16 x i8> %[[arg3]], -! LLVMIR: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[arg2]], <4 x i32> %[[arg1]], <16 x i8> %[[xor]]) +! LLVMIR-LE: %[[xor:.*]] = xor <16 x i8> %[[arg3]], +! LLVMIR-LE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[arg2]], <4 x i32> %[[arg1]], <16 x i8> %[[xor]]) +! LLVMIR-BE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[arg1]], <4 x i32> %[[arg2]], <16 x i8> %[[arg3]]) ! LLVMIR: store <4 x i32> %[[call]], ptr %{{.*}}, align 16 end subroutine vec_perm_test_u4 @@ -125,8 +133,9 @@ subroutine vec_perm_test_u8(arg1, arg2, arg3) ! LLVMIR: %[[arg3:.*]] = load <16 x i8>, ptr %{{.*}}, align 16 ! LLVMIR: %[[barg1:.*]] = bitcast <2 x i64> %[[arg1]] to <4 x i32> ! LLVMIR: %[[barg2:.*]] = bitcast <2 x i64> %[[arg2]] to <4 x i32> -! LLVMIR: %[[xor:.*]] = xor <16 x i8> %[[arg3]], -! LLVMIR: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-LE: %[[xor:.*]] = xor <16 x i8> %[[arg3]], +! LLVMIR-LE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-BE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg1]], <4 x i32> %[[barg2]], <16 x i8> %[[arg3]]) ! LLVMIR: %[[bcall:.*]] = bitcast <4 x i32> %[[call]] to <2 x i64> ! LLVMIR: store <2 x i64> %[[bcall]], ptr %{{.*}}, align 16 end subroutine vec_perm_test_u8 @@ -142,8 +151,9 @@ subroutine vec_perm_test_r4(arg1, arg2, arg3) ! LLVMIR: %[[arg3:.*]] = load <16 x i8>, ptr %{{.*}}, align 16 ! LLVMIR: %[[barg1:.*]] = bitcast <4 x float> %[[arg1]] to <4 x i32> ! LLVMIR: %[[barg2:.*]] = bitcast <4 x float> %[[arg2]] to <4 x i32> -! LLVMIR: %[[xor:.*]] = xor <16 x i8> %[[arg3]], -! LLVMIR: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-LE: %[[xor:.*]] = xor <16 x i8> %[[arg3]], +! LLVMIR-LE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-BE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg1]], <4 x i32> %[[barg2]], <16 x i8> %[[arg3]]) ! LLVMIR: %[[bcall:.*]] = bitcast <4 x i32> %[[call]] to <4 x float> ! LLVMIR: store <4 x float> %[[bcall]], ptr %{{.*}}, align 16 end subroutine vec_perm_test_r4 @@ -159,8 +169,9 @@ subroutine vec_perm_test_r8(arg1, arg2, arg3) ! LLVMIR: %[[arg3:.*]] = load <16 x i8>, ptr %{{.*}}, align 16 ! LLVMIR: %[[barg1:.*]] = bitcast <2 x double> %[[arg1]] to <4 x i32> ! LLVMIR: %[[barg2:.*]] = bitcast <2 x double> %[[arg2]] to <4 x i32> -! LLVMIR: %[[xor:.*]] = xor <16 x i8> %[[arg3]], -! LLVMIR: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-LE: %[[xor:.*]] = xor <16 x i8> %[[arg3]], +! LLVMIR-LE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg2]], <4 x i32> %[[barg1]], <16 x i8> %[[xor]]) +! LLVMIR-BE: %[[call:.*]] = call <4 x i32> @llvm.ppc.altivec.vperm(<4 x i32> %[[barg1]], <4 x i32> %[[barg2]], <16 x i8> %[[arg3]]) ! LLVMIR: %[[bcall:.*]] = bitcast <4 x i32> %[[call]] to <2 x double> ! LLVMIR: store <2 x double> %[[bcall]], ptr %{{.*}}, align 16 end subroutine vec_perm_test_r8 diff --git a/flang/test/Lower/PowerPC/ppc-vec-splat.f90 b/flang/test/Lower/PowerPC/ppc-vec-splat.f90 index e21555781df29a34f1d983b3dbab2fac4939d201..9d4f7e3d98a3ac58c34d3787e11ce76dbace091c 100644 --- a/flang/test/Lower/PowerPC/ppc-vec-splat.f90 +++ b/flang/test/Lower/PowerPC/ppc-vec-splat.f90 @@ -1,4 +1,5 @@ -! RUN: %flang_fc1 -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-LE" %s +! RUN: %flang_fc1 -flang-experimental-hlfir -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefixes="LLVMIR","LLVMIR-BE" %s ! REQUIRES: target=powerpc{{.*}} !---------------- @@ -11,7 +12,8 @@ subroutine vec_splat_testi8i8(x) y = vec_splat(x, 0_1) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i8 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i8 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i8 15 ! LLVMIR: %[[ins:.*]] = insertelement <16 x i8> undef, i8 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <16 x i8> %[[ins]], <16 x i8> undef, <16 x i32> zeroinitializer ! LLVMIR: store <16 x i8> %[[y]], ptr %{{[0-9]}}, align 16 @@ -23,7 +25,8 @@ subroutine vec_splat_testi8i16(x) y = vec_splat(x, 0_2) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i16 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i16 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i16 15 ! LLVMIR: %[[ins:.*]] = insertelement <16 x i8> undef, i8 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <16 x i8> %[[ins]], <16 x i8> undef, <16 x i32> zeroinitializer ! LLVMIR: store <16 x i8> %[[y]], ptr %{{[0-9]}}, align 16 @@ -35,7 +38,8 @@ subroutine vec_splat_testi8i32(x) y = vec_splat(x, 0_4) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i32 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i32 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i32 15 ! LLVMIR: %[[ins:.*]] = insertelement <16 x i8> undef, i8 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <16 x i8> %[[ins]], <16 x i8> undef, <16 x i32> zeroinitializer ! LLVMIR: store <16 x i8> %[[y]], ptr %{{[0-9]}}, align 16 @@ -47,7 +51,8 @@ subroutine vec_splat_testi8i64(x) y = vec_splat(x, 0_8) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i64 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i64 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i64 15 ! LLVMIR: %[[ins:.*]] = insertelement <16 x i8> undef, i8 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <16 x i8> %[[ins]], <16 x i8> undef, <16 x i32> zeroinitializer ! LLVMIR: store <16 x i8> %[[y]], ptr %{{[0-9]}}, align 16 @@ -59,7 +64,8 @@ subroutine vec_splat_testi16i8(x) y = vec_splat(x, 0_1) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i8 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i8 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i8 7 ! LLVMIR: %[[ins:.*]] = insertelement <8 x i16> undef, i16 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <8 x i16> %[[ins]], <8 x i16> undef, <8 x i32> zeroinitializer ! LLVMIR: store <8 x i16> %[[y]], ptr %{{[0-9]}}, align 16 @@ -71,7 +77,8 @@ subroutine vec_splat_testi16i16(x) y = vec_splat(x, 0_2) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i16 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i16 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i16 7 ! LLVMIR: %[[ins:.*]] = insertelement <8 x i16> undef, i16 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <8 x i16> %[[ins]], <8 x i16> undef, <8 x i32> zeroinitializer ! LLVMIR: store <8 x i16> %[[y]], ptr %{{[0-9]}}, align 16 @@ -83,7 +90,8 @@ subroutine vec_splat_testi16i32(x) y = vec_splat(x, 0_4) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i32 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i32 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i32 7 ! LLVMIR: %[[ins:.*]] = insertelement <8 x i16> undef, i16 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <8 x i16> %[[ins]], <8 x i16> undef, <8 x i32> zeroinitializer ! LLVMIR: store <8 x i16> %[[y]], ptr %{{[0-9]}}, align 16 @@ -95,7 +103,8 @@ subroutine vec_splat_testi16i64(x) y = vec_splat(x, 0_8) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i64 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i64 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i64 7 ! LLVMIR: %[[ins:.*]] = insertelement <8 x i16> undef, i16 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <8 x i16> %[[ins]], <8 x i16> undef, <8 x i32> zeroinitializer ! LLVMIR: store <8 x i16> %[[y]], ptr %{{[0-9]}}, align 16 @@ -107,7 +116,8 @@ subroutine vec_splat_testi32i8(x) y = vec_splat(x, 0_1) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i8 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i8 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i8 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x i32> undef, i32 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x i32> %[[ins]], <4 x i32> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x i32> %[[y]], ptr %{{[0-9]}}, align 16 @@ -119,7 +129,8 @@ subroutine vec_splat_testi32i16(x) y = vec_splat(x, 0_2) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i16 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i16 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i16 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x i32> undef, i32 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x i32> %[[ins]], <4 x i32> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x i32> %[[y]], ptr %{{[0-9]}}, align 16 @@ -131,7 +142,8 @@ subroutine vec_splat_testi32i32(x) y = vec_splat(x, 0_4) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i32 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i32 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i32 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x i32> undef, i32 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x i32> %[[ins]], <4 x i32> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x i32> %[[y]], ptr %{{[0-9]}}, align 16 @@ -143,7 +155,8 @@ subroutine vec_splat_testi32i64(x) y = vec_splat(x, 0_8) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i64 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i64 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i64 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x i32> undef, i32 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x i32> %[[ins]], <4 x i32> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x i32> %[[y]], ptr %{{[0-9]}}, align 16 @@ -155,7 +168,8 @@ subroutine vec_splat_testi64i8(x) y = vec_splat(x, 0_1) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i8 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i8 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i8 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x i64> undef, i64 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x i64> %[[ins]], <2 x i64> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x i64> %[[y]], ptr %{{[0-9]}}, align 16 @@ -167,7 +181,8 @@ subroutine vec_splat_testi64i16(x) y = vec_splat(x, 0_2) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i16 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i16 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i16 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x i64> undef, i64 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x i64> %[[ins]], <2 x i64> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x i64> %[[y]], ptr %{{[0-9]}}, align 16 @@ -179,7 +194,8 @@ subroutine vec_splat_testi64i32(x) y = vec_splat(x, 0_4) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i32 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i32 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i32 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x i64> undef, i64 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x i64> %[[ins]], <2 x i64> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x i64> %[[y]], ptr %{{[0-9]}}, align 16 @@ -191,7 +207,8 @@ subroutine vec_splat_testi64i64(x) y = vec_splat(x, 0_8) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i64 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i64 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i64 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x i64> undef, i64 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x i64> %[[ins]], <2 x i64> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x i64> %[[y]], ptr %{{[0-9]}}, align 16 @@ -203,7 +220,8 @@ subroutine vec_splat_testf32i8(x) y = vec_splat(x, 0_1) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x float> %[[x]], i8 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x float> %[[x]], i8 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x float> %[[x]], i8 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x float> undef, float %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x float> %[[ins]], <4 x float> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x float> %[[y]], ptr %{{[0-9]}}, align 16 @@ -215,7 +233,8 @@ subroutine vec_splat_testf32i16(x) y = vec_splat(x, 0_2) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x float> %[[x]], i16 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x float> %[[x]], i16 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x float> %[[x]], i16 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x float> undef, float %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x float> %[[ins]], <4 x float> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x float> %[[y]], ptr %{{[0-9]}}, align 16 @@ -227,7 +246,8 @@ subroutine vec_splat_testf32i32(x) y = vec_splat(x, 0_4) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x float> %[[x]], i32 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x float> %[[x]], i32 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x float> %[[x]], i32 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x float> undef, float %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x float> %[[ins]], <4 x float> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x float> %[[y]], ptr %{{[0-9]}}, align 16 @@ -239,7 +259,8 @@ subroutine vec_splat_testf32i64(x) y = vec_splat(x, 0_8) ! LLVMIR: %[[x:.*]] = load <4 x float>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x float> %[[x]], i64 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x float> %[[x]], i64 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x float> %[[x]], i64 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x float> undef, float %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x float> %[[ins]], <4 x float> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x float> %[[y]], ptr %{{[0-9]}}, align 16 @@ -251,7 +272,8 @@ subroutine vec_splat_testf64i8(x) y = vec_splat(x, 0_1) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x double> %[[x]], i8 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x double> %[[x]], i8 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x double> %[[x]], i8 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x double> undef, double %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x double> %[[ins]], <2 x double> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x double> %[[y]], ptr %{{[0-9]}}, align 16 @@ -263,7 +285,8 @@ subroutine vec_splat_testf64i16(x) y = vec_splat(x, 0_2) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x double> %[[x]], i16 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x double> %[[x]], i16 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x double> %[[x]], i16 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x double> undef, double %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x double> %[[ins]], <2 x double> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x double> %[[y]], ptr %{{[0-9]}}, align 16 @@ -275,7 +298,8 @@ subroutine vec_splat_testf64i32(x) y = vec_splat(x, 0_4) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x double> %[[x]], i32 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x double> %[[x]], i32 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x double> %[[x]], i32 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x double> undef, double %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x double> %[[ins]], <2 x double> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x double> %[[y]], ptr %{{[0-9]}}, align 16 @@ -287,7 +311,8 @@ subroutine vec_splat_testf64i64(x) y = vec_splat(x, 0_8) ! LLVMIR: %[[x:.*]] = load <2 x double>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x double> %[[x]], i64 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x double> %[[x]], i64 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x double> %[[x]], i64 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x double> undef, double %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x double> %[[ins]], <2 x double> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x double> %[[y]], ptr %{{[0-9]}}, align 16 @@ -299,7 +324,8 @@ subroutine vec_splat_testu8i8(x) y = vec_splat(x, 0_1) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i8 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i8 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i8 15 ! LLVMIR: %[[ins:.*]] = insertelement <16 x i8> undef, i8 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <16 x i8> %[[ins]], <16 x i8> undef, <16 x i32> zeroinitializer ! LLVMIR: store <16 x i8> %[[y]], ptr %{{[0-9]}}, align 16 @@ -311,7 +337,8 @@ subroutine vec_splat_testu8i16(x) y = vec_splat(x, 0_2) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i16 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i16 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i16 15 ! LLVMIR: %[[ins:.*]] = insertelement <16 x i8> undef, i8 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <16 x i8> %[[ins]], <16 x i8> undef, <16 x i32> zeroinitializer ! LLVMIR: store <16 x i8> %[[y]], ptr %{{[0-9]}}, align 16 @@ -323,7 +350,8 @@ subroutine vec_splat_testu8i32(x) y = vec_splat(x, 0_4) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i32 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i32 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i32 15 ! LLVMIR: %[[ins:.*]] = insertelement <16 x i8> undef, i8 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <16 x i8> %[[ins]], <16 x i8> undef, <16 x i32> zeroinitializer ! LLVMIR: store <16 x i8> %[[y]], ptr %{{[0-9]}}, align 16 @@ -335,7 +363,8 @@ subroutine vec_splat_testu8i64(x) y = vec_splat(x, 0_8) ! LLVMIR: %[[x:.*]] = load <16 x i8>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i64 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i64 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <16 x i8> %[[x]], i64 15 ! LLVMIR: %[[ins:.*]] = insertelement <16 x i8> undef, i8 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <16 x i8> %[[ins]], <16 x i8> undef, <16 x i32> zeroinitializer ! LLVMIR: store <16 x i8> %[[y]], ptr %{{[0-9]}}, align 16 @@ -347,7 +376,8 @@ subroutine vec_splat_testu16i8(x) y = vec_splat(x, 0_1) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i8 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i8 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i8 7 ! LLVMIR: %[[ins:.*]] = insertelement <8 x i16> undef, i16 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <8 x i16> %[[ins]], <8 x i16> undef, <8 x i32> zeroinitializer ! LLVMIR: store <8 x i16> %[[y]], ptr %{{[0-9]}}, align 16 @@ -359,7 +389,8 @@ subroutine vec_splat_testu16i16(x) y = vec_splat(x, 0_2) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i16 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i16 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i16 7 ! LLVMIR: %[[ins:.*]] = insertelement <8 x i16> undef, i16 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <8 x i16> %[[ins]], <8 x i16> undef, <8 x i32> zeroinitializer ! LLVMIR: store <8 x i16> %[[y]], ptr %{{[0-9]}}, align 16 @@ -371,7 +402,8 @@ subroutine vec_splat_testu16i32(x) y = vec_splat(x, 0_4) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i32 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i32 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i32 7 ! LLVMIR: %[[ins:.*]] = insertelement <8 x i16> undef, i16 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <8 x i16> %[[ins]], <8 x i16> undef, <8 x i32> zeroinitializer ! LLVMIR: store <8 x i16> %[[y]], ptr %{{[0-9]}}, align 16 @@ -383,7 +415,8 @@ subroutine vec_splat_testu16i64(x) y = vec_splat(x, 0_8) ! LLVMIR: %[[x:.*]] = load <8 x i16>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i64 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i64 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <8 x i16> %[[x]], i64 7 ! LLVMIR: %[[ins:.*]] = insertelement <8 x i16> undef, i16 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <8 x i16> %[[ins]], <8 x i16> undef, <8 x i32> zeroinitializer ! LLVMIR: store <8 x i16> %[[y]], ptr %{{[0-9]}}, align 16 @@ -395,7 +428,8 @@ subroutine vec_splat_testu32i8(x) y = vec_splat(x, 0_1) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i8 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i8 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i8 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x i32> undef, i32 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x i32> %[[ins]], <4 x i32> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x i32> %[[y]], ptr %{{[0-9]}}, align 16 @@ -407,7 +441,8 @@ subroutine vec_splat_testu32i16(x) y = vec_splat(x, 0_2) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i16 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i16 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i16 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x i32> undef, i32 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x i32> %[[ins]], <4 x i32> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x i32> %[[y]], ptr %{{[0-9]}}, align 16 @@ -419,7 +454,8 @@ subroutine vec_splat_testu32i32(x) y = vec_splat(x, 0_4) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i32 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i32 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i32 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x i32> undef, i32 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x i32> %[[ins]], <4 x i32> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x i32> %[[y]], ptr %{{[0-9]}}, align 16 @@ -431,7 +467,8 @@ subroutine vec_splat_testu32i64(x) y = vec_splat(x, 0_8) ! LLVMIR: %[[x:.*]] = load <4 x i32>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i64 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i64 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <4 x i32> %[[x]], i64 3 ! LLVMIR: %[[ins:.*]] = insertelement <4 x i32> undef, i32 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <4 x i32> %[[ins]], <4 x i32> undef, <4 x i32> zeroinitializer ! LLVMIR: store <4 x i32> %[[y]], ptr %{{[0-9]}}, align 16 @@ -443,7 +480,8 @@ subroutine vec_splat_testu64i8(x) y = vec_splat(x, 0_1) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i8 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i8 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i8 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x i64> undef, i64 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x i64> %[[ins]], <2 x i64> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x i64> %[[y]], ptr %{{[0-9]}}, align 16 @@ -455,7 +493,8 @@ subroutine vec_splat_testu64i16(x) y = vec_splat(x, 0_2) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i16 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i16 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i16 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x i64> undef, i64 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x i64> %[[ins]], <2 x i64> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x i64> %[[y]], ptr %{{[0-9]}}, align 16 @@ -467,7 +506,8 @@ subroutine vec_splat_testu64i32(x) y = vec_splat(x, 0_4) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i32 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i32 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i32 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x i64> undef, i64 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x i64> %[[ins]], <2 x i64> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x i64> %[[y]], ptr %{{[0-9]}}, align 16 @@ -479,7 +519,8 @@ subroutine vec_splat_testu64i64(x) y = vec_splat(x, 0_8) ! LLVMIR: %[[x:.*]] = load <2 x i64>, ptr %{{[0-9]}}, align 16 -! LLVMIR: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i64 0 +! LLVMIR-LE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i64 0 +! LLVMIR-BE: %[[ele:.*]] = extractelement <2 x i64> %[[x]], i64 1 ! LLVMIR: %[[ins:.*]] = insertelement <2 x i64> undef, i64 %[[ele]], i32 0 ! LLVMIR: %[[y:.*]] = shufflevector <2 x i64> %[[ins]], <2 x i64> undef, <2 x i32> zeroinitializer ! LLVMIR: store <2 x i64> %[[y]], ptr %{{[0-9]}}, align 16 diff --git a/flang/test/Lower/namelist.f90 b/flang/test/Lower/namelist.f90 index bba7a0ea19774d2f31b017b6ce68913286456c2e..9fdd8a2c8f61314789879f3ff0d8c1cdbd10d28d 100644 --- a/flang/test/Lower/namelist.f90 +++ b/flang/test/Lower/namelist.f90 @@ -1,88 +1,144 @@ -! RUN: bbc -emit-fir -hlfir=false -o - %s | FileCheck %s +! RUN: bbc -emit-fir -o - %s | FileCheck %s -! CHECK-LABEL: func @_QQmain +! CHECK-LABEL: c.func @_QQmain program p - ! CHECK-DAG: [[ccc:%[0-9]+]] = fir.alloca !fir.array<4x!fir.char<1,3>> {bindc_name = "ccc", uniq_name = "_QFEccc"} - ! CHECK-DAG: [[jjj:%[0-9]+]] = fir.alloca i32 {bindc_name = "jjj", uniq_name = "_QFEjjj"} + ! CHECK: %[[V_1:[0-9]+]] = fir.alloca !fir.box>>> + ! CHECK: %[[V_2:[0-9]+]] = fir.alloca !fir.box> + ! CHECK: %[[V_3:[0-9]+]] = fir.alloca !fir.box>>> + ! CHECK: %[[V_4:[0-9]+]] = fir.alloca !fir.box> + ! CHECK: %[[V_5:[0-9]+]] = fir.alloca !fir.array<4x!fir.char<1,3>> {bindc_name = "ccc", uniq_name = "_QFEccc"} + ! CHECK: %[[V_6:[0-9]+]] = fir.shape %c4{{.*}} : (index) -> !fir.shape<1> + ! CHECK: %[[V_7:[0-9]+]] = fir.declare %[[V_5]](%[[V_6]]) typeparams %c3{{.*}} {uniq_name = "_QFEccc"} : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref>> + ! CHECK: %[[V_8:[0-9]+]] = fir.alloca i32 {bindc_name = "jjj", uniq_name = "_QFEjjj"} + ! CHECK: %[[V_9:[0-9]+]] = fir.declare %[[V_8]] {uniq_name = "_QFEjjj"} : (!fir.ref) -> !fir.ref + ! CHECK: fir.store %c17{{.*}} to %[[V_9]] : !fir.ref character*3 ccc(4) namelist /nnn/ jjj, ccc jjj = 17 ccc = ["aa ", "bb ", "cc ", "dd "] - ! CHECK: [[cookie:%[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput - ! CHECK: fir.alloca !fir.array<2xtuple, !fir.ref>>> - ! CHECK: fir.undefined - ! CHECK: fir.address_of - ! CHECK: fir.insert_value - ! CHECK: fir.embox [[jjj]] - ! CHECK: fir.insert_value - ! CHECK: fir.address_of - ! CHECK: fir.insert_value - ! CHECK: fir.embox [[ccc]] - ! CHECK: fir.insert_value - ! CHECK: fir.alloca tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> - ! CHECK: fir.address_of - ! CHECK-COUNT-4: fir.insert_value - ! CHECK: fir.call @_FortranAioOutputNamelist([[cookie]] - ! CHECK: fir.call @_FortranAioEndIoStatement([[cookie]] + + ! CHECK: %[[V_23:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput + ! CHECK: %[[V_24:[0-9]+]] = fir.alloca !fir.array<2xtuple, !fir.ref>>> + ! CHECK: %[[V_25:[0-9]+]] = fir.undefined !fir.array<2xtuple, !fir.ref>>> + ! CHECK: %[[V_26:[0-9]+]] = fir.address_of(@_QQclX6A6A6A00) : !fir.ref> + ! CHECK: %[[V_27:[0-9]+]] = fir.convert %[[V_26]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[V_28:[0-9]+]] = fir.insert_value %[[V_25]], %[[V_27]], [0 : index, 0 : index] : (!fir.array<2xtuple, !fir.ref>>>, !fir.ref) -> !fir.array<2xtuple, !fir.ref>>> + ! CHECK: %[[V_29:[0-9]+]] = fir.embox %[[V_9]] : (!fir.ref) -> !fir.box> + ! CHECK: fir.store %[[V_29]] to %[[V_4]] : !fir.ref>> + ! CHECK: %[[V_30:[0-9]+]] = fir.convert %[[V_4]] : (!fir.ref>>) -> !fir.ref> + ! CHECK: %[[V_31:[0-9]+]] = fir.insert_value %[[V_28]], %[[V_30]], [0 : index, 1 : index] : (!fir.array<2xtuple, !fir.ref>>>, !fir.ref>) -> !fir.array<2xtuple, !fir.ref>>> + ! CHECK: %[[V_32:[0-9]+]] = fir.address_of(@_QQclX63636300) : !fir.ref> + ! CHECK: %[[V_33:[0-9]+]] = fir.convert %[[V_32]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[V_34:[0-9]+]] = fir.insert_value %[[V_31]], %[[V_33]], [1 : index, 0 : index] : (!fir.array<2xtuple, !fir.ref>>>, !fir.ref) -> !fir.array<2xtuple, !fir.ref>>> + ! CHECK: %[[V_35:[0-9]+]] = fir.embox %[[V_7]](%[[V_6]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>>> + ! CHECK: fir.store %[[V_35]] to %[[V_3]] : !fir.ref>>>> + ! CHECK: %[[V_36:[0-9]+]] = fir.convert %[[V_3]] : (!fir.ref>>>>) -> !fir.ref> + ! CHECK: %[[V_37:[0-9]+]] = fir.insert_value %[[V_34]], %[[V_36]], [1 : index, 1 : index] : (!fir.array<2xtuple, !fir.ref>>>, !fir.ref>) -> !fir.array<2xtuple, !fir.ref>>> + ! CHECK: fir.store %[[V_37]] to %[[V_24]] : !fir.ref, !fir.ref>>>> + ! CHECK: %[[V_38:[0-9]+]] = fir.alloca tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_39:[0-9]+]] = fir.undefined tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_40:[0-9]+]] = fir.address_of(@_QQclX6E6E6E00) : !fir.ref> + ! CHECK: %[[V_41:[0-9]+]] = fir.convert %[[V_40]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[V_42:[0-9]+]] = fir.insert_value %[[V_39]], %[[V_41]], [0 : index] : (tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref>, !fir.ref) -> tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_43:[0-9]+]] = fir.insert_value %[[V_42]], %c2{{.*}}, [1 : index] : (tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref>, i64) -> tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_44:[0-9]+]] = fir.insert_value %[[V_43]], %[[V_24]], [2 : index] : (tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref>, !fir.ref, !fir.ref>>>>) -> tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_45:[0-9]+]] = fir.address_of(@default.nonTbpDefinedIoTable) : !fir.ref, !fir.ref, i32, i1>>>, i1>> + ! CHECK: %[[V_46:[0-9]+]] = fir.convert %[[V_45]] : (!fir.ref, !fir.ref, i32, i1>>>, i1>>) -> !fir.ref + ! CHECK: %[[V_47:[0-9]+]] = fir.insert_value %[[V_44]], %[[V_46]], [3 : index] : (tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref>, !fir.ref) -> tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: fir.store %[[V_47]] to %[[V_38]] : !fir.ref, i64, !fir.ref, !fir.ref>>>>, !fir.ref>> + ! CHECK: %[[V_48:[0-9]+]] = fir.convert %[[V_38]] : (!fir.ref, i64, !fir.ref, !fir.ref>>>>, !fir.ref>>) -> !fir.ref> + ! CHECK: %[[V_49:[0-9]+]] = fir.call @_FortranAioOutputNamelist(%[[V_23]], %[[V_48]]) fastmath : (!fir.ref, !fir.ref>) -> i1 + ! CHECK: %[[V_50:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_23]]) fastmath : (!fir.ref) -> i32 write(*, nnn) jjj = 27 - ! CHECK: fir.coordinate_of ccc(4) = "zz " - ! CHECK: [[cookie:%[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput - ! CHECK: fir.alloca !fir.array<2xtuple, !fir.ref>>> - ! CHECK: fir.undefined - ! CHECK: fir.address_of - ! CHECK: fir.insert_value - ! CHECK: fir.embox [[jjj]] - ! CHECK: fir.insert_value - ! CHECK: fir.address_of - ! CHECK: fir.insert_value - ! CHECK: fir.embox [[ccc]] - ! CHECK: fir.insert_value - ! CHECK: fir.alloca tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> - ! CHECK: fir.address_of - ! CHECK-COUNT-4: fir.insert_value - ! CHECK: fir.call @_FortranAioOutputNamelist([[cookie]] - ! CHECK: fir.call @_FortranAioEndIoStatement([[cookie]] + ! CHECK: %[[V_58:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput + ! CHECK: %[[V_59:[0-9]+]] = fir.alloca !fir.array<2xtuple, !fir.ref>>> + ! CHECK: fir.store %[[V_29]] to %[[V_2]] : !fir.ref>> + ! CHECK: %[[V_60:[0-9]+]] = fir.convert %[[V_2]] : (!fir.ref>>) -> !fir.ref> + ! CHECK: %[[V_61:[0-9]+]] = fir.insert_value %[[V_28]], %[[V_60]], [0 : index, 1 : index] : (!fir.array<2xtuple, !fir.ref>>>, !fir.ref>) -> !fir.array<2xtuple, !fir.ref>>> + ! CHECK: %[[V_62:[0-9]+]] = fir.insert_value %[[V_61]], %[[V_33]], [1 : index, 0 : index] : (!fir.array<2xtuple, !fir.ref>>>, !fir.ref) -> !fir.array<2xtuple, !fir.ref>>> + ! CHECK: fir.store %[[V_35]] to %[[V_1]] : !fir.ref>>>> + ! CHECK: %[[V_63:[0-9]+]] = fir.convert %[[V_1]] : (!fir.ref>>>>) -> !fir.ref> + ! CHECK: %[[V_64:[0-9]+]] = fir.insert_value %[[V_62]], %[[V_63]], [1 : index, 1 : index] : (!fir.array<2xtuple, !fir.ref>>>, !fir.ref>) -> !fir.array<2xtuple, !fir.ref>>> + ! CHECK: fir.store %[[V_64]] to %[[V_59]] : !fir.ref, !fir.ref>>>> + ! CHECK: %[[V_65:[0-9]+]] = fir.alloca tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_66:[0-9]+]] = fir.insert_value %[[V_43]], %[[V_59]], [2 : index] : (tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref>, !fir.ref, !fir.ref>>>>) -> tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_67:[0-9]+]] = fir.insert_value %[[V_66]], %[[V_46]], [3 : index] : (tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref>, !fir.ref) -> tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: fir.store %[[V_67]] to %[[V_65]] : !fir.ref, i64, !fir.ref, !fir.ref>>>>, !fir.ref>> + ! CHECK: %[[V_68:[0-9]+]] = fir.convert %[[V_65]] : (!fir.ref, i64, !fir.ref, !fir.ref>>>>, !fir.ref>>) -> !fir.ref> + ! CHECK: %[[V_69:[0-9]+]] = fir.call @_FortranAioOutputNamelist(%[[V_58]], %[[V_68]]) fastmath : (!fir.ref, !fir.ref>) -> i1 + ! CHECK: %[[V_70:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_58]]) fastmath : (!fir.ref) -> i32 write(*, nnn) + + call rename end -! CHECK-LABEL: sss +! CHECK-LABEL: c.func @_QPsss subroutine sss + ! CHECK: %[[V_0:[0-9]+]] = fir.alloca !fir.box>> + ! CHECK: %[[V_1:[0-9]+]] = fir.alloca !fir.array<3xi32> {bindc_name = "xxx", uniq_name = "_QFsssExxx"} + ! CHECK: %[[V_2:[0-9]+]] = fir.shape_shift %c11{{.*}}, %c3{{.*}} : (index, index) -> !fir.shapeshift<1> + ! CHECK: %[[V_3:[0-9]+]] = fir.declare %[[V_1]](%[[V_2]]) {uniq_name = "_QFsssExxx"} : (!fir.ref>, !fir.shapeshift<1>) -> !fir.ref> integer xxx(11:13) + + ! CHECK: %[[V_7:[0-9]+]] = fir.call @_FortranAioBeginExternalListInput + ! CHECK: %[[V_8:[0-9]+]] = fir.alloca !fir.array<1xtuple, !fir.ref>>> + ! CHECK: %[[V_9:[0-9]+]] = fir.undefined !fir.array<1xtuple, !fir.ref>>> + ! CHECK: %[[V_10:[0-9]+]] = fir.address_of(@_QQclX78787800) : !fir.ref> + ! CHECK: %[[V_11:[0-9]+]] = fir.convert %[[V_10]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[V_12:[0-9]+]] = fir.insert_value %[[V_9]], %[[V_11]], [0 : index, 0 : index] : (!fir.array<1xtuple, !fir.ref>>>, !fir.ref) -> !fir.array<1xtuple, !fir.ref>>> + ! CHECK: %[[V_13:[0-9]+]] = fir.embox %[[V_3]](%[[V_2]]) : (!fir.ref>, !fir.shapeshift<1>) -> !fir.box>> + ! CHECK: fir.store %[[V_13]] to %[[V_0]] : !fir.ref>>> + ! CHECK: %[[V_14:[0-9]+]] = fir.convert %[[V_0]] : (!fir.ref>>>) -> !fir.ref> + ! CHECK: %[[V_15:[0-9]+]] = fir.insert_value %[[V_12]], %[[V_14]], [0 : index, 1 : index] : (!fir.array<1xtuple, !fir.ref>>>, !fir.ref>) -> !fir.array<1xtuple, !fir.ref>>> + ! CHECK: fir.store %[[V_15]] to %[[V_8]] : !fir.ref, !fir.ref>>>> + ! CHECK: %[[V_16:[0-9]+]] = fir.alloca tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_17:[0-9]+]] = fir.undefined tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_18:[0-9]+]] = fir.address_of(@_QQclX72727200) : !fir.ref> + ! CHECK: %[[V_19:[0-9]+]] = fir.convert %[[V_18]] : (!fir.ref>) -> !fir.ref + ! CHECK: %[[V_20:[0-9]+]] = fir.insert_value %[[V_17]], %[[V_19]], [0 : index] : (tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref>, !fir.ref) -> tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_21:[0-9]+]] = fir.insert_value %[[V_20]], %c1{{.*}}, [1 : index] : (tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref>, i64) -> tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_22:[0-9]+]] = fir.insert_value %[[V_21]], %[[V_8]], [2 : index] : (tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref>, !fir.ref, !fir.ref>>>>) -> tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: %[[V_23:[0-9]+]] = fir.address_of(@default.nonTbpDefinedIoTable) : !fir.ref, !fir.ref, i32, i1>>>, i1>> + ! CHECK: %[[V_24:[0-9]+]] = fir.convert %[[V_23]] : (!fir.ref, !fir.ref, i32, i1>>>, i1>>) -> !fir.ref + ! CHECK: %[[V_25:[0-9]+]] = fir.insert_value %[[V_22]], %[[V_24]], [3 : index] : (tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref>, !fir.ref) -> tuple, i64, !fir.ref, !fir.ref>>>>, !fir.ref> + ! CHECK: fir.store %[[V_25]] to %[[V_16]] : !fir.ref, i64, !fir.ref, !fir.ref>>>>, !fir.ref>> + ! CHECK: %[[V_26:[0-9]+]] = fir.convert %[[V_16]] : (!fir.ref, i64, !fir.ref, !fir.ref>>>>, !fir.ref>>) -> !fir.ref> + ! CHECK: %[[V_27:[0-9]+]] = fir.call @_FortranAioInputNamelist(%[[V_7]], %[[V_26]]) fastmath : (!fir.ref, !fir.ref>) -> i1 + ! CHECK: %[[V_28:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_7]]) fastmath : (!fir.ref) -> i32 namelist /rrr/ xxx - ! CHECK: [[xxx:%[0-9]+]] = fir.alloca {{.*}} = "xxx" - ! CHECK: [[cookie:%[0-9]+]] = fir.call @_FortranAioBeginExternalListInput - ! CHECK: alloca - ! CHECK: undefined - ! CHECK: fir.address_of{{.*}}787878 - ! CHECK: fir.insert_value - ! CHECK: fir.shape_shift %c11 - ! CHECK: fir.embox [[xxx]] - ! CHECK: fir.insert_value - ! CHECK: fir.alloca - ! CHECK: fir.undefined - ! CHECK: fir.address_of{{.*}}727272 - ! CHECK-COUNT-3: fir.insert_value - ! CHECK: fir.call @_FortranAioInputNamelist([[cookie]] - ! CHECK: fir.call @_FortranAioEndIoStatement([[cookie]] read(*, rrr) end -! CHECK-LABEL: global_pointer +! CHECK-LABEL: c.func @_QPglobal_pointer subroutine global_pointer real,pointer,save::ptrarray(:) - ! CHECK: %[[a0:.*]] = fir.address_of + ! CHECK: %[[V_4:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput + ! CHECK: %[[V_5:[0-9]+]] = fir.address_of(@_QFglobal_pointerNmygroup) : !fir.ref, i64, !fir.ref, !fir.ref>>>>, !fir.ref>> + ! CHECK: %[[V_6:[0-9]+]] = fir.convert %[[V_5]] : (!fir.ref, i64, !fir.ref, !fir.ref>>>>, !fir.ref>>) -> !fir.ref> + ! CHECK: %[[V_7:[0-9]+]] = fir.call @_FortranAioOutputNamelist(%[[V_4]], %[[V_6]]) fastmath : (!fir.ref, !fir.ref>) -> i1 + ! CHECK: %[[V_8:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_4]]) fastmath : (!fir.ref) -> i32 namelist/mygroup/ptrarray - ! CHECK: %[[a1:.*]] = fir.convert %[[a0]] - ! CHECK: %[[a2:.*]] = fir.call @_FortranAioBeginExternalListOutput({{.*}}, %[[a1]], {{.*}}) {{.*}}: (i32, !fir.ref, i32) -> !fir.ref - ! CHECK: %[[a3:.*]] = fir.address_of - ! CHECK: %[[a4:.*]] = fir.convert %[[a3]] - ! CHECK: %[[a5:.*]] = fir.call @_FortranAioOutputNamelist(%[[a2]], %[[a4]]) - ! CHECK: %[[a6:.*]] = fir.call @_FortranAioEndIoStatement(%[[a2]]) write(10, nml=mygroup) end - ! CHECK-DAG: fir.global linkonce @_QQclX6A6A6A00 constant : !fir.char<1,4> - ! CHECK-DAG: fir.global linkonce @_QQclX63636300 constant : !fir.char<1,4> - ! CHECK-DAG: fir.global linkonce @_QQclX6E6E6E00 constant : !fir.char<1,4> +module mmm + real rrr + namelist /aaa/ rrr +end + +! CHECK-LABEL: c.func @_QPrename +subroutine rename + use mmm, bbb => aaa + rrr = 3. + ! CHECK: %[[V_4:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput + ! CHECK: %[[V_5:[0-9]+]] = fir.address_of(@_QMmmmNaaa) : !fir.ref, i64, !fir.ref, !fir.ref>>>>, !fir.ref>> + ! CHECK: %[[V_6:[0-9]+]] = fir.convert %[[V_5]] : (!fir.ref, i64, !fir.ref, !fir.ref>>>>, !fir.ref>>) -> !fir.ref> + ! CHECK: %[[V_7:[0-9]+]] = fir.call @_FortranAioOutputNamelist(%[[V_4]], %[[V_6]]) fastmath : (!fir.ref, !fir.ref>) -> i1 + ! CHECK: %[[V_8:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_4]]) fastmath : (!fir.ref) -> i32 + write(*,bbb) +end + +! CHECK-NOT: bbb +! CHECK: fir.string_lit "aaa\00"(4) : !fir.char<1,4> diff --git a/flang/test/Parser/OpenMP/threadprivate-blank-common-block.f90 b/flang/test/Parser/OpenMP/threadprivate-blank-common-block.f90 new file mode 100644 index 0000000000000000000000000000000000000000..6317258e6ec8d58503e8313af1902a7ad97c3be2 --- /dev/null +++ b/flang/test/Parser/OpenMP/threadprivate-blank-common-block.f90 @@ -0,0 +1,9 @@ +! RUN: not %flang_fc1 -fsyntax-only %s -fopenmp 2>&1 | FileCheck %s +! From Standard: A blank common block cannot appear in a threadprivate directive. + +program main + integer :: a + common//a + !CHECK: error: expected one of '$@ABCDEFGHIJKLMNOPQRSTUVWXYZ_' + !$omp threadprivate(//) + end diff --git a/flang/test/Transforms/simplifyintrinsics.fir b/flang/test/Transforms/simplifyintrinsics.fir index 39483a9cc18fe84a4041a97cfd2e6913a10293cf..0bd6ac7c436ff2b9f351a2ffadf287526fe25b7b 100644 --- a/flang/test/Transforms/simplifyintrinsics.fir +++ b/flang/test/Transforms/simplifyintrinsics.fir @@ -2348,3 +2348,249 @@ func.func @_QPtestminloc_doesntwork1d_unknownmask(%arg0: !fir.ref : (!fir.ref>, !fir.box, !fir.box) -> () // CHECK: fir.call @_FortranAMinlocInteger4({{.*}}) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> none // CHECK-NOT: fir.call @_FortranAMinlocInteger4x1_i32_contract_simplified({{.*}}) fastmath : (!fir.ref>, !fir.box, !fir.box) -> () + +// ----- +// Check Maxloc simplifies similarly to minloc +func.func @_QPtestmaxloc_works1d(%arg0: !fir.ref> {fir.bindc_name = "a"}, %arg1: !fir.ref>> {fir.bindc_name = "b"}) -> !fir.array<1xi32> { + %0 = fir.alloca !fir.box>> + %c10 = arith.constant 10 : index + %c10_0 = arith.constant 10 : index + %c1 = arith.constant 1 : index + %1 = fir.alloca !fir.array<1xi32> {bindc_name = "testmaxloc_works1d", uniq_name = "_QFtestmaxloc_works1dEtestmaxloc_works1d"} + %2 = fir.shape %c1 : (index) -> !fir.shape<1> + %3 = fir.array_load %1(%2) : (!fir.ref>, !fir.shape<1>) -> !fir.array<1xi32> + %4 = fir.shape %c10 : (index) -> !fir.shape<1> + %5 = fir.embox %arg0(%4) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + %6 = fir.shape %c10_0 : (index) -> !fir.shape<1> + %7 = fir.embox %arg1(%6) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> + %c4 = arith.constant 4 : index + %false = arith.constant false + %8 = fir.zero_bits !fir.heap> + %c0 = arith.constant 0 : index + %9 = fir.shape %c0 : (index) -> !fir.shape<1> + %10 = fir.embox %8(%9) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> + fir.store %10 to %0 : !fir.ref>>> + %11 = fir.address_of(@_QQclXea5bcf7f706678e1796661f8916f3379) : !fir.ref> + %c5_i32 = arith.constant 5 : i32 + %12 = fir.convert %0 : (!fir.ref>>>) -> !fir.ref> + %13 = fir.convert %5 : (!fir.box>) -> !fir.box + %14 = fir.convert %c4 : (index) -> i32 + %15 = fir.convert %11 : (!fir.ref>) -> !fir.ref + %16 = fir.convert %7 : (!fir.box>>) -> !fir.box + %17 = fir.call @_FortranAMaxlocInteger4(%12, %13, %14, %15, %c5_i32, %16, %false) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> none + %18 = fir.load %0 : !fir.ref>>> + %c0_1 = arith.constant 0 : index + %19:3 = fir.box_dims %18, %c0_1 : (!fir.box>>, index) -> (index, index, index) + %20 = fir.box_addr %18 : (!fir.box>>) -> !fir.heap> + %21 = fir.shape_shift %19#0, %19#1 : (index, index) -> !fir.shapeshift<1> + %22 = fir.array_load %20(%21) : (!fir.heap>, !fir.shapeshift<1>) -> !fir.array + %c1_2 = arith.constant 1 : index + %c0_3 = arith.constant 0 : index + %23 = arith.subi %c1, %c1_2 : index + %24 = fir.do_loop %arg2 = %c0_3 to %23 step %c1_2 unordered iter_args(%arg3 = %3) -> (!fir.array<1xi32>) { + %26 = fir.array_fetch %22, %arg2 : (!fir.array, index) -> i32 + %27 = fir.array_update %arg3, %26, %arg2 : (!fir.array<1xi32>, i32, index) -> !fir.array<1xi32> + fir.result %27 : !fir.array<1xi32> + } + fir.array_merge_store %3, %24 to %1 : !fir.array<1xi32>, !fir.array<1xi32>, !fir.ref> + fir.freemem %20 : !fir.heap> + %25 = fir.load %1 : !fir.ref> + return %25 : !fir.array<1xi32> +} + +// CHECK-LABEL: func.func @_QPtestmaxloc_works1d( +// CHECK-SAME: %[[INARR:.*]]: !fir.ref> {fir.bindc_name = "a"}, +// CHECK-SAME: %[[MASK:.*]]: !fir.ref>> {fir.bindc_name = "b"}) -> !fir.array<1xi32> { +// CHECK: %[[OUTARR:.*]] = fir.alloca !fir.box>> +// CHECK: %[[SIZE10_0:.*]] = arith.constant 10 : index +// CHECK: %[[SIZE10_1:.*]] = arith.constant 10 : index +// CHECK: %[[INARR_SHAPE:.*]] = fir.shape %[[SIZE10_0]] : (index) -> !fir.shape<1> +// CHECK: %[[BOX_INARR:.*]] = fir.embox %[[INARR]](%[[INARR_SHAPE]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +// CHECK: %[[MASK_SHAPE:.*]] = fir.shape %[[SIZE10_1]] : (index) -> !fir.shape<1> +// CHECK: %[[BOX_MASK:.*]] = fir.embox %[[MASK]](%[[MASK_SHAPE]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> +// CHECK: %[[REF_BOX_OUTARR_NONE:.*]] = fir.convert %[[OUTARR]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[BOX_INARR_NONE:.*]] = fir.convert %[[BOX_INARR]] : (!fir.box>) -> !fir.box +// CHECK: %[[BOX_MASK_NONE:.*]] = fir.convert %[[BOX_MASK]] : (!fir.box>>) -> !fir.box +// CHECK: fir.call @_FortranAMaxlocInteger4x1_Logical4x1_i32_contract_simplified(%[[REF_BOX_OUTARR_NONE]], %[[BOX_INARR_NONE]], %[[BOX_MASK_NONE]]) fastmath : (!fir.ref>, !fir.box, !fir.box) -> () + +// CHECK-LABEL: func.func private @_FortranAMaxlocInteger4x1_Logical4x1_i32_contract_simplified( +// CHECK-SAME: %[[REF_BOX_OUTARR_NONE:.*]]: !fir.ref>, +// CHECK-SAME: %[[BOX_INARR_NONE:.*]]: !fir.box, +// CHECK-SAME: %[[BOX_MASK_NONE:.*]]: !fir.box) attributes {llvm.linkage = #llvm.linkage} { +// CHECK: %[[FLAG_ALLOC:.*]] = fir.alloca i32 +// CHECK: %[[INIT_OUT_IDX:.*]] = arith.constant 0 : i32 +// CHECK: %[[OUTARR_SIZE:.*]] = arith.constant 1 : index +// CHECK: %[[OUTARR:.*]] = fir.allocmem !fir.array<1xi32> +// CHECK: %[[OUTARR_SHAPE:.*]] = fir.shape %[[OUTARR_SIZE]] : (index) -> !fir.shape<1> +// CHECK: %[[BOX_OUTARR:.*]] = fir.embox %[[OUTARR]](%[[OUTARR_SHAPE]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK: %[[OUTARR_IDX0:.*]] = arith.constant 0 : index +// CHECK: %[[OUTARR_ITEM0:.*]] = fir.coordinate_of %[[BOX_OUTARR]], %[[OUTARR_IDX0]] : (!fir.box>>, index) -> !fir.ref +// CHECK: fir.store %[[INIT_OUT_IDX]] to %[[OUTARR_ITEM0]] : !fir.ref +// CHECK: %[[CINDEX_0:.*]] = arith.constant 0 : index +// CHECK: %[[BOX_INARR:.*]] = fir.convert %[[BOX_INARR_NONE]] : (!fir.box) -> !fir.box> +// CHECK: %[[FLAG_SET:.*]] = arith.constant 1 : i32 +// CHECK: %[[FLAG_EMPTY:.*]] = arith.constant 0 : i32 +// CHECK: fir.store %[[FLAG_EMPTY]] to %[[FLAG_ALLOC]] : !fir.ref +// CHECK: %[[BOX_MASK:.*]] = fir.convert %[[BOX_MASK_NONE]] : (!fir.box) -> !fir.box>> +// CHECK: %[[MAX:.*]] = arith.constant -2147483648 : i32 +// CHECK: %[[CINDEX_1:.*]] = arith.constant 1 : index +// CHECK: %[[DIM_INDEX0:.*]] = arith.constant 0 : index +// CHECK: %[[DIMS:.*]]:3 = fir.box_dims %[[BOX_INARR]], %[[DIM_INDEX0]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[EXTENT:.*]] = arith.subi %[[DIMS]]#1, %[[CINDEX_1]] : index +// CHECK: %[[DOLOOP:.*]] = fir.do_loop %[[ITER:.*]] = %[[CINDEX_0]] to %[[EXTENT]] step %[[CINDEX_1]] iter_args(%[[MIN:.*]] = %[[MAX]]) -> (i32) { +// CHECK: %[[MASK_ITEM:.*]] = fir.coordinate_of %[[BOX_MASK]], %[[ITER]] : (!fir.box>>, index) -> !fir.ref> +// CHECK: %[[MASK_ITEMVAL:.*]] = fir.load %[[MASK_ITEM]] : !fir.ref> +// CHECK: %[[MASK_IF_ITEM:.*]] = fir.convert %[[MASK_ITEMVAL]] : (!fir.logical<4>) -> i1 +// CHECK: %[[IF_MASK:.*]] = fir.if %[[MASK_IF_ITEM]] -> (i32) { +// CHECK: fir.store %[[FLAG_SET]] to %[[FLAG_ALLOC]] : !fir.ref +// CHECK: %[[INARR_ITEM:.*]] = fir.coordinate_of %[[BOX_INARR]], %[[ITER]] : (!fir.box>, index) -> !fir.ref +// CHECK: %[[INARR_ITEMVAL:.*]] = fir.load %[[INARR_ITEM]] : !fir.ref +// CHECK: %[[NEW_MIN:.*]] = arith.cmpi sgt, %[[INARR_ITEMVAL]], %[[MIN]] : i32 +// CHECK: %[[IF_NEW_MIN:.*]] = fir.if %[[NEW_MIN]] -> (i32) { +// CHECK: %[[ONE:.*]] = arith.constant 1 : i32 +// CHECK: %[[OUTARR_IDX:.*]] = arith.constant 0 : index +// CHECK: %[[OUTARR_ITEM:.*]] = fir.coordinate_of %[[BOX_OUTARR]], %[[OUTARR_IDX]] : (!fir.box>>, index) -> !fir.ref +// CHECK: %[[ITER_I32:.*]] = fir.convert %[[ITER]] : (index) -> i32 +// CHECK: %[[FORTRAN_IDX:.*]] = arith.addi %[[ITER_I32]], %[[ONE]] : i32 +// CHECK: fir.store %[[FORTRAN_IDX]] to %[[OUTARR_ITEM]] : !fir.ref +// CHECK: fir.result %[[INARR_ITEMVAL]] : i32 +// CHECK: } else { +// CHECK: fir.result %[[MIN]] : i32 +// CHECK: } +// CHECK: fir.result %[[IF_NEW_MIN:.*]] : i32 +// CHECK: } else { +// CHECK: fir.result %[[MIN]] : i32 +// CHECK: } +// CHECK: fir.result %[[IF_MASK:.*]] : i32 +// CHECK: } +// CHECK: %[[FLAG_VAL:.*]] = fir.load %[[FLAG_ALLOC]] : !fir.ref +// CHECK: %[[FLAG_WAS_SET:.*]] = arith.cmpi eq, %[[FLAG_VAL]], %[[FLAG_SET]] : i32 +// CHECK: fir.if %[[FLAG_WAS_SET]] { +// CHECK: %[[TEST_MAX:.*]] = arith.constant -2147483648 : i32 +// CHECK: %[[INIT_NOT_CHANGED:.*]] = arith.cmpi eq, %[[TEST_MAX]], %[[DO_LOOP:.*]] : i32 +// CHECK: fir.if %[[INIT_NOT_CHANGED]] { +// CHECK: %[[FLAG_OUTARR_IDX:.*]] = arith.constant 0 : index +// CHECK: %[[FLAG_OUTARR_ITEM:.*]] = fir.coordinate_of %[[BOX_OUTARR]], %[[FLAG_OUTARR_IDX]] : (!fir.box>>, index) -> !fir.ref +// CHECK: fir.store %[[FLAG_SET]] to %[[FLAG_OUTARR_ITEM]] : !fir.ref +// CHECK: } +// CHECK: } +// CHECK: %[[REF_BOX_OUTARR:.*]] = fir.convert %[[REF_BOX_OUTARR_NONE]] : (!fir.ref>) -> !fir.ref>>> +// CHECK: fir.store %[[BOX_OUTARR]] to %[[REF_BOX_OUTARR]] : !fir.ref>>> +// CHECK: return +// CHECK: } + +// ----- +// Check Maxloc simplifies correctly for 1D case with scalar mask and f64 input + +func.func @_QPtestmaxloc_works1d_scalarmask_f64(%arg0: !fir.ref> {fir.bindc_name = "a"}, %arg1: !fir.ref> {fir.bindc_name = "b"}) -> !fir.array<1xi32> { + %0 = fir.alloca !fir.box>> + %c10 = arith.constant 10 : index + %c1 = arith.constant 1 : index + %1 = fir.alloca !fir.array<1xi32> {bindc_name = "testmaxloc_works1d_scalarmask_f64", uniq_name = "_QFtestmaxloc_works1d_scalarmask_f64Etestminloc_works1d_scalarmask_f64"} + %2 = fir.shape %c1 : (index) -> !fir.shape<1> + %3 = fir.array_load %1(%2) : (!fir.ref>, !fir.shape<1>) -> !fir.array<1xi32> + %4 = fir.shape %c10 : (index) -> !fir.shape<1> + %5 = fir.embox %arg0(%4) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + %6 = fir.embox %arg1 : (!fir.ref>) -> !fir.box> + %c4 = arith.constant 4 : index + %false = arith.constant false + %7 = fir.zero_bits !fir.heap> + %c0 = arith.constant 0 : index + %8 = fir.shape %c0 : (index) -> !fir.shape<1> + %9 = fir.embox %7(%8) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> + fir.store %9 to %0 : !fir.ref>>> + %10 = fir.address_of(@_QQclX66951c28c5b8bab5cdb25c1ac762b978) : !fir.ref> + %c6_i32 = arith.constant 6 : i32 + %11 = fir.convert %0 : (!fir.ref>>>) -> !fir.ref> + %12 = fir.convert %5 : (!fir.box>) -> !fir.box + %13 = fir.convert %c4 : (index) -> i32 + %14 = fir.convert %10 : (!fir.ref>) -> !fir.ref + %15 = fir.convert %6 : (!fir.box>) -> !fir.box + %16 = fir.call @_FortranAMaxlocReal8(%11, %12, %13, %14, %c6_i32, %15, %false) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> none + %17 = fir.load %0 : !fir.ref>>> + %c0_0 = arith.constant 0 : index + %18:3 = fir.box_dims %17, %c0_0 : (!fir.box>>, index) -> (index, index, index) + %19 = fir.box_addr %17 : (!fir.box>>) -> !fir.heap> + %20 = fir.shape_shift %18#0, %18#1 : (index, index) -> !fir.shapeshift<1> + %21 = fir.array_load %19(%20) : (!fir.heap>, !fir.shapeshift<1>) -> !fir.array + %c1_1 = arith.constant 1 : index + %c0_2 = arith.constant 0 : index + %22 = arith.subi %c1, %c1_1 : index + %23 = fir.do_loop %arg2 = %c0_2 to %22 step %c1_1 unordered iter_args(%arg3 = %3) -> (!fir.array<1xi32>) { + %25 = fir.array_fetch %21, %arg2 : (!fir.array, index) -> i32 + %26 = fir.array_update %arg3, %25, %arg2 : (!fir.array<1xi32>, i32, index) -> !fir.array<1xi32> + fir.result %26 : !fir.array<1xi32> + } + fir.array_merge_store %3, %23 to %1 : !fir.array<1xi32>, !fir.array<1xi32>, !fir.ref> + fir.freemem %19 : !fir.heap> + %24 = fir.load %1 : !fir.ref> + return %24 : !fir.array<1xi32> +} + +// CHECK-LABEL: func.func @_QPtestmaxloc_works1d_scalarmask_f64( +// CHECK-SAME: %[[INARR:.*]]: !fir.ref> {fir.bindc_name = "a"}, +// CHECK-SAME: %[[MASK:.*]]: !fir.ref> {fir.bindc_name = "b"}) -> !fir.array<1xi32> { +// CHECK: fir.call @_FortranAMaxlocReal8x1_Logical4x0_i32_contract_simplified({{.*}}, {{.*}}, {{.*}}) fastmath : (!fir.ref>, !fir.box, !fir.box) -> () + +// CHECK-LABEL: func.func private @_FortranAMaxlocReal8x1_Logical4x0_i32_contract_simplified( +// CHECK-SAME: %[[REF_BOX_OUTARR_NONE:.*]]: !fir.ref>, +// CHECK-SAME: %[[BOX_INARR_NONE:.*]]: !fir.box, +// CHECK-SAME: %[[BOX_MASK_NONE:.*]]: !fir.box) attributes {llvm.linkage = #llvm.linkage} { +// CHECK: %[[FLAG_ALLOC:.*]] = fir.alloca i32 +// CHECK: %[[INIT_OUT_IDX:.*]] = arith.constant 0 : i32 +// CHECK: %[[OUTARR_SIZE:.*]] = arith.constant 1 : index +// CHECK: %[[OUTARR:.*]] = fir.allocmem !fir.array<1xi32> +// CHECK: %[[OUTARR_SHAPE:.*]] = fir.shape %[[OUTARR_SIZE]] : (index) -> !fir.shape<1> +// CHECK: %[[BOX_OUTARR:.*]] = fir.embox %[[OUTARR]](%[[OUTARR_SHAPE]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK: %[[OUTARR_IDX0:.*]] = arith.constant 0 : index +// CHECK: %[[OUTARR_ITEM0:.*]] = fir.coordinate_of %[[BOX_OUTARR]], %[[OUTARR_IDX0]] : (!fir.box>>, index) -> !fir.ref +// CHECK: fir.store %[[INIT_OUT_IDX]] to %[[OUTARR_ITEM0]] : !fir.ref +// CHECK: %[[BOX_MASK:.*]] = fir.convert %[[BOX_MASK_NONE]] : (!fir.box) -> !fir.box> +// CHECK: %[[MASK_IDX0:.*]] = arith.constant 0 : index +// CHECK: %[[MASK_ITEM:.*]] = fir.coordinate_of %[[BOX_MASK]], %[[MASK_IDX0]] : (!fir.box>, index) -> !fir.ref +// CHECK: %[[MASK:.*]] = fir.load %[[MASK_ITEM]] : !fir.ref +// CHECK: %[[INIT_RES:.*]] = fir.if %[[MASK]] -> (f64) { +// CHECK: %[[C_INDEX0:.*]] = arith.constant 0 : index +// CHECK: %[[BOX_INARR:.*]] = fir.convert %[[BOX_INARR_NONE]] : (!fir.box) -> !fir.box> +// CHECK: %[[FLAG_SET:.*]] = arith.constant 1 : i32 +// CHECK: %[[FLAG_EMPTY:.*]] = arith.constant 0 : i32 +// CHECK: fir.store %[[FLAG_EMPTY]] to %[[FLAG_ALLOC]] : !fir.ref +// CHECK: %[[MAX:.*]] = arith.constant -1.7976931348623157E+308 : f64 +// CHECK: %[[C_INDEX1:.*]] = arith.constant 1 : index +// CHECK: %[[DIM_INDEX:.*]] = arith.constant 0 : index +// CHECK: %[[DIMS:.*]]:3 = fir.box_dims %[[BOX_INARR]], %[[DIM_INDEX]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[EXTENT:.*]] = arith.subi %[[DIMS]]#1, %[[C_INDEX1]] : index +// CHECK: %[[DOLOOP:.*]] = fir.do_loop %[[ITER:.*]] = %[[C_INDEX0]] to %[[EXTENT]] step %[[C_INDEX1]] iter_args(%[[MIN:.*]] = %[[MAX]]) -> (f64) { +// CHECK: %[[INARR_ITEM:.*]] = fir.coordinate_of %[[BOX_INARR]], %[[ITER]] : (!fir.box>, index) -> !fir.ref +// CHECK: %[[INARR_ITEMVAL:.*]] = fir.load %[[INARR_ITEM]] : !fir.ref +// CHECK: %[[NEW_MIN:.*]] = arith.cmpf ogt, %[[INARR_ITEMVAL]], %[[MIN]] fastmath<{{.*}}> : f64 +// CHECK: %[[IF_NEW_MIN:.*]] = fir.if %[[NEW_MIN]] -> (f64) { +// CHECK: %[[ONE:.*]] = arith.constant 1 : i32 +// CHECK: %[[OUTARR_IDX:.*]] = arith.constant 0 : index +// CHECK: %[[OUTARR_ITEM:.*]] = fir.coordinate_of %[[BOX_OUTARR]], %[[OUTARR_IDX]] : (!fir.box>>, index) -> !fir.ref +// CHECK: %[[ITER_I32:.*]] = fir.convert %[[ITER]] : (index) -> i32 +// CHECK: %[[FORTRAN_IDX:.*]] = arith.addi %[[ITER_I32]], %[[ONE]] : i32 +// CHECK: fir.store %[[FORTRAN_IDX]] to %[[OUTARR_ITEM]] : !fir.ref +// CHECK: fir.result %[[INARR_ITEMVAL]] : f64 +// CHECK: } else { +// CHECK: fir.result %[[MIN]] : f64 +// CHECK: } +// CHECK: fir.result %[[IF_NEW_MIN:.*]] : f64 +// CHECK: } +// CHECK: } +// CHECK: %[[FLAG_CHECK:.*]] = arith.constant 1 : i32 +// CHECK: %[[FLAG_VAL:.*]] = fir.load %[[FLAG_ALLOC]] : !fir.ref +// CHECK: %[[FLAG_WAS_SET:.*]] = arith.cmpi eq, %[[FLAG_VAL]], %[[FLAG_CHECK]] : i32 +// CHECK: fir.if %[[FLAG_WAS_SET]] { +// CHECK: %[[TEST_MAX:.*]] = arith.constant -1.7976931348623157E+308 : f64 +// CHECK: %[[INIT_NOT_CHANGED:.*]] = arith.cmpf oeq, %[[TEST_MAX]], %[[INIT_RES:.*]] fastmath<{{.*}}> : f64 +// CHECK: fir.if %[[INIT_NOT_CHANGED]] { +// CHECK: %[[FLAG_OUTARR_IDX:.*]] = arith.constant 0 : index +// CHECK: %[[FLAG_OUTARR_ITEM:.*]] = fir.coordinate_of %[[BOX_OUTARR]], %[[FLAG_OUTARR_IDX]] : (!fir.box>>, index) -> !fir.ref +// CHECK: fir.store %[[FLAG_CHECK]] to %[[FLAG_OUTARR_ITEM]] : !fir.ref +// CHECK: } +// CHECK: } +// CHECK: %[[REF_BOX_OUTARR:.*]] = fir.convert %[[VAL_0]] : (!fir.ref>) -> !fir.ref>>> +// CHECK: fir.store %[[BOX_OUTARR]] to %[[REF_BOX_OUTARR]] : !fir.ref>>> +// CHECK: return +// CHECK: } diff --git a/flang/tools/flang-driver/driver.cpp b/flang/tools/flang-driver/driver.cpp index 99fa66b0dc8e266a84fac7227fbf6b104b65ab24..c4e56a862c861359311a035e8d71342df1d7d5bd 100644 --- a/flang/tools/flang-driver/driver.cpp +++ b/flang/tools/flang-driver/driver.cpp @@ -99,13 +99,13 @@ int main(int argc, const char **argv) { auto firstArg = std::find_if(args.begin() + 1, args.end(), [](const char *a) { return a != nullptr; }); if (firstArg != args.end()) { - if (llvm::StringRef(args[1]).startswith("-cc1")) { + if (llvm::StringRef(args[1]).starts_with("-cc1")) { llvm::errs() << "error: unknown integrated tool '" << args[1] << "'. " << "Valid tools include '-fc1'.\n"; return 1; } // Call flang-new frontend - if (llvm::StringRef(args[1]).startswith("-fc1")) { + if (llvm::StringRef(args[1]).starts_with("-fc1")) { return executeFC1Tool(args); } } diff --git a/flang/unittests/Frontend/CompilerInstanceTest.cpp b/flang/unittests/Frontend/CompilerInstanceTest.cpp index 6dbbf9b4e1bbd3cbb96117bc456b42352c52560c..35f1ec1748a3f69fd6e67ab613d59650a716805e 100644 --- a/flang/unittests/Frontend/CompilerInstanceTest.cpp +++ b/flang/unittests/Frontend/CompilerInstanceTest.cpp @@ -55,7 +55,7 @@ TEST(CompilerInstance, SanityCheckForFileManager) { llvm::ArrayRef fileContent = sf->content(); EXPECT_FALSE(fileContent.size() == 0); EXPECT_TRUE( - llvm::StringRef(fileContent.data()).startswith("InputSourceFile")); + llvm::StringRef(fileContent.data()).starts_with("InputSourceFile")); // 4. Delete the test file ec = llvm::sys::fs::remove(inputFile); diff --git a/flang/unittests/Frontend/FrontendActionTest.cpp b/flang/unittests/Frontend/FrontendActionTest.cpp index d57154cb1001c7295e2b45f2283e8929b62d8c2a..6ec15832d96d3cb11aec687c8cc5a30d93ece45e 100644 --- a/flang/unittests/Frontend/FrontendActionTest.cpp +++ b/flang/unittests/Frontend/FrontendActionTest.cpp @@ -112,7 +112,7 @@ TEST_F(FrontendActionTest, TestInputOutput) { EXPECT_TRUE(success); EXPECT_TRUE(!outputFileBuffer.empty()); EXPECT_TRUE(llvm::StringRef(outputFileBuffer.data()) - .startswith("End Program arithmetic")); + .starts_with("End Program arithmetic")); } TEST_F(FrontendActionTest, PrintPreprocessedInput) { @@ -143,7 +143,7 @@ TEST_F(FrontendActionTest, PrintPreprocessedInput) { EXPECT_TRUE(success); EXPECT_TRUE(!outputFileBuffer.empty()); EXPECT_TRUE( - llvm::StringRef(outputFileBuffer.data()).startswith("program b\n")); + llvm::StringRef(outputFileBuffer.data()).starts_with("program b\n")); } TEST_F(FrontendActionTest, ParseSyntaxOnly) { diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake index 6cae0859149d54c1298a16164461af6e7d304a86..51d484b875aeff42a8eb36e671555a01c1d90f74 100644 --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -18,62 +18,81 @@ function(get_object_files_for_test result skipped_entrypoints_list) set(checked_list "") set(unchecked_list "${ARGN}") list(REMOVE_DUPLICATES unchecked_list) - list(LENGTH unchecked_list length) - while(length) - set(indirect_list "") + foreach(dep IN LISTS unchecked_list) + if (NOT TARGET ${dep}) + # Skip tests with undefined dependencies. + list(APPEND skipped_list ${dep}) + continue() + endif() + get_target_property(aliased_target ${dep} "ALIASED_TARGET") + if(aliased_target) + # If the target is just an alias, switch to the real target. + set(dep ${aliased_target}) + endif() - foreach(dep IN LISTS unchecked_list) - if (NOT TARGET ${dep}) - # Skip tests with undefined dependencies. - list(APPEND skipped_list ${dep}) - continue() - endif() - get_target_property(dep_type ${dep} "TARGET_TYPE") - if(NOT dep_type) - # Skip tests with no object dependencies. - continue() - endif() + get_target_property(dep_type ${dep} "TARGET_TYPE") + if(NOT dep_type) + # Skip tests with no object dependencies. + continue() + endif() + + get_target_property(dep_checked ${dep} "CHECK_OBJ_FOR_TESTS") + + if(dep_checked) + # Target full dependency has already been checked. Just use the results. + get_target_property(dep_obj ${dep} "OBJECT_FILES_FOR_TESTS") + get_target_property(dep_skip ${dep} "SKIPPED_LIST_FOR_TESTS") + else() + # Target full dependency hasn't been checked. Recursively check its DEPS. + set(dep_obj "${dep}") + set(dep_skip "") + + get_target_property(indirect_deps ${dep} "DEPS") + get_object_files_for_test(dep_obj dep_skip ${indirect_deps}) if(${dep_type} STREQUAL ${OBJECT_LIBRARY_TARGET_TYPE}) get_target_property(dep_object_files ${dep} "OBJECT_FILES") if(dep_object_files) - list(APPEND object_files ${dep_object_files}) + list(APPEND dep_obj ${dep_object_files}) endif() elseif(${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE}) get_target_property(is_skipped ${dep} "SKIPPED") if(is_skipped) - list(APPEND skipped_list ${dep}) - continue() + list(APPEND dep_skip ${dep}) + list(REMOVE_ITEM dep_obj ${dep}) endif() get_target_property(object_file_raw ${dep} "OBJECT_FILE_RAW") if(object_file_raw) - list(APPEND object_files ${object_file_raw}) + list(APPEND dep_obj ${object_file_raw}) endif() elseif(${dep_type} STREQUAL ${ENTRYPOINT_OBJ_VENDOR_TARGET_TYPE}) # Skip tests for externally implemented entrypoints. - list(APPEND skipped_list ${dep}) - continue() + list(APPEND dep_skip ${dep}) + list(REMOVE_ITEM dep_obj ${dep}) endif() - get_target_property(indirect_deps ${dep} "DEPS") - list(APPEND indirect_list "${indirect_deps}") - endforeach(dep) + set_target_properties(${dep} PROPERTIES + OBJECT_FILES_FOR_TESTS "${dep_obj}" + SKIPPED_LIST_FOR_TESTS "${dep_skip}" + CHECK_OBJ_FOR_TESTS "YES" + ) + + endif() + + list(APPEND object_files ${dep_obj}) + list(APPEND skipped_list ${dep_skip}) - # Only add new indirect dependencies to check. - list(APPEND checked_list "${unchecked_list}") - list(REMOVE_DUPLICATES indirect_list) - list(REMOVE_ITEM indirect_list checked_list) - set(unchecked_list "${indirect_list}") - list(LENGTH unchecked_list length) - endwhile() + endforeach(dep) list(REMOVE_DUPLICATES object_files) set(${result} ${object_files} PARENT_SCOPE) list(REMOVE_DUPLICATES skipped_list) set(${skipped_entrypoints_list} ${skipped_list} PARENT_SCOPE) + endfunction(get_object_files_for_test) + # Rule to add a libc unittest. # Usage # add_libc_unittest( diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td index 726e58f376eaa766e30e7b2ced0f37300c947c75..85f6b59264eb06d29254135dff4571acaf205927 100644 --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -205,7 +205,12 @@ def SysSelectAPI : PublicAPI<"sys/select.h"> { } def SysSocketAPI : PublicAPI<"sys/socket.h"> { - let Types = ["struct sockaddr", "sa_family_t"]; + let Types = [ + "sa_family_t", + "socklen_t", + "struct sockaddr", + "struct sockaddr_un", + ]; } def SysResourceAPI : PublicAPI<"sys/resource.h"> { diff --git a/libc/config/linux/app.h b/libc/config/linux/app.h index 0d2f9475c10db64c04a1b54b07a0d337e7328426..548c141fd70535da99cc8d28636fc8a5df1b67fd 100644 --- a/libc/config/linux/app.h +++ b/libc/config/linux/app.h @@ -49,11 +49,21 @@ typedef uintptr_t ArgcType; typedef uintptr_t ArgVEntryType; typedef uintptr_t EnvironType; -typedef uintptr_t AuxEntryType; #else #error "argc and argv types are not defined for the target platform." #endif +// Linux manpage on `proc(5)` says that the aux vector is an array of +// unsigned long pairs. +// (see: https://man7.org/linux/man-pages/man5/proc.5.html) +using AuxEntryType = unsigned long; +// Using the naming convention from `proc(5)`. +// TODO: Would be nice to use the aux entry structure from elf.h when available. +struct AuxEntry { + AuxEntryType id; + AuxEntryType value; +}; + struct Args { ArgcType argc; @@ -78,6 +88,9 @@ struct AppProperties { // Environment data. EnvironType *env_ptr; + + // Auxiliary vector data. + AuxEntry *auxv_ptr; }; extern AppProperties app; diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 13b81d3b7ca702c7d4f0b4be523de6403fe32a2c..1c93063e25e90c08c64857824e6333ec43c6016c 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -153,9 +153,6 @@ set(TARGET_LIBC_ENTRYPOINTS # sys/sendfile entrypoints libc.src.sys.sendfile.sendfile - # sys/socket.h entrypoints - libc.src.sys.socket.socket - # sys/stat.h entrypoints libc.src.sys.stat.chmod libc.src.sys.stat.fchmod @@ -557,6 +554,10 @@ if(LLVM_LIBC_FULL_BUILD) # sys/select.h entrypoints libc.src.sys.select.select + + # sys/socket.h entrypoints + libc.src.sys.socket.socket + libc.src.sys.socket.bind ) endif() diff --git a/libc/fuzzing/stdio/printf_float_conv_fuzz.cpp b/libc/fuzzing/stdio/printf_float_conv_fuzz.cpp index 798e1a3866fddf39249659af34e39945601a0ea7..eefe78c2920d3fafd575304339e1ad73bb2ec6cf 100644 --- a/libc/fuzzing/stdio/printf_float_conv_fuzz.cpp +++ b/libc/fuzzing/stdio/printf_float_conv_fuzz.cpp @@ -90,7 +90,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { int prec = 0; int width = 0; - LIBC_NAMESPACE::fputil::FPBits::UIntType raw_num = 0; + LIBC_NAMESPACE::fputil::FPBits::StorageType raw_num = 0; // Copy as many bytes of data as will fit into num, prec, and with. Any extras // are ignored. diff --git a/libc/fuzzing/stdlib/strtofloat_fuzz.cpp b/libc/fuzzing/stdlib/strtofloat_fuzz.cpp index f6cc8abedf4645217e33ffb9131078eb9975bfc2..ea2f492f57ae76d8fc93c1a04017a56af54bbdc1 100644 --- a/libc/fuzzing/stdlib/strtofloat_fuzz.cpp +++ b/libc/fuzzing/stdlib/strtofloat_fuzz.cpp @@ -33,7 +33,7 @@ template inline constexpr int effective_precision(int exponent) { // This is intended to be 0 when the exponent is the lowest normal and // increase as the exponent's magnitude increases. const int bits_below_normal = - (-exponent) - (FloatProperties::EXPONENT_BIAS - 1); + (-exponent) - (FloatProperties::EXP_BIAS - 1); // The precision should be the normal, full precision, minus the bits lost // by this being a subnormal, minus one for the implicit leading one. diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index 429c0f1f12866a8988f469b32b30dc126cbf2ed3..59c6c4a9bb4200045aff79905a8f6bc9eaf1094a 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -417,8 +417,10 @@ add_gen_header( DEPENDS .llvm_libc_common_h .llvm-libc-macros.sys_socket_macros - .llvm-libc-types.struct_sockaddr .llvm-libc-types.sa_family_t + .llvm-libc-types.socklen_t + .llvm-libc-types.struct_sockaddr + .llvm-libc-types.struct_sockaddr_un ) add_gen_header( diff --git a/libc/include/llvm-libc-macros/linux/fcntl-macros.h b/libc/include/llvm-libc-macros/linux/fcntl-macros.h index cdd1cf22d7b69cbdc0d128d86651feef4278c7db..495c5ec780edb0ee76bd735b74120011c4e25f3a 100644 --- a/libc/include/llvm-libc-macros/linux/fcntl-macros.h +++ b/libc/include/llvm-libc-macros/linux/fcntl-macros.h @@ -46,31 +46,6 @@ #define O_RDWR 00000002 #define O_WRONLY 00000001 -// File mode flags -#define S_IRWXU 0700 -#define S_IRUSR 0400 -#define S_IWUSR 0200 -#define S_IXUSR 0100 -#define S_IRWXG 070 -#define S_IRGRP 040 -#define S_IWGRP 020 -#define S_IXGRP 010 -#define S_IRWXO 07 -#define S_IROTH 04 -#define S_IWOTH 02 -#define S_IXOTH 01 -#define S_ISUID 04000 -#define S_ISGID 02000 - -// File type flags -#define S_IFMT 0170000 -#define S_IFDIR 0040000 -#define S_IFCHR 0020000 -#define S_IFBLK 0060000 -#define S_IFREG 0100000 -#define S_FIFO 0010000 -#define S_IFLNK 0120000 - // Special directory FD to indicate that the path argument to // openat is relative to the current directory. #define AT_FDCWD -100 diff --git a/libc/include/llvm-libc-macros/linux/sys-stat-macros.h b/libc/include/llvm-libc-macros/linux/sys-stat-macros.h index 3be743328a26bb71315161e9732f0365c26a0f80..48606cfa08ce935f685eb09177a06a891c1bf887 100644 --- a/libc/include/llvm-libc-macros/linux/sys-stat-macros.h +++ b/libc/include/llvm-libc-macros/linux/sys-stat-macros.h @@ -10,7 +10,7 @@ #define __LLVM_LIBC_MACROS_LINUX_SYS_STAT_MACROS_H // Definitions from linux/stat.h -#define S_IFMT 00170000 +#define S_IFMT 0170000 #define S_IFSOCK 0140000 #define S_IFLNK 0120000 #define S_IFREG 0100000 diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index 225ad780c4d01f2412b806aca38a5e5e5a5c271f..500900ffa0bbb05ed2a6aa12cd66d861771af09b 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -89,6 +89,8 @@ add_header(__getoptargv_t HDR __getoptargv_t.h) add_header(wchar_t HDR wchar_t.h) add_header(wint_t HDR wint_t.h) add_header(sa_family_t HDR sa_family_t.h) +add_header(socklen_t HDR socklen_t.h) +add_header(struct_sockaddr_un HDR struct_sockaddr_un.h) add_header(struct_sockaddr HDR struct_sockaddr.h) add_header(rpc_opcodes_t HDR rpc_opcodes_t.h) add_header(ACTION HDR ACTION.h) diff --git a/libc/include/llvm-libc-types/socklen_t.h b/libc/include/llvm-libc-types/socklen_t.h new file mode 100644 index 0000000000000000000000000000000000000000..3134a53390e71ed420de55e6cdf87b47c2156cac --- /dev/null +++ b/libc/include/llvm-libc-types/socklen_t.h @@ -0,0 +1,18 @@ +//===-- Definition of socklen_t type ------------------------------------===// +// +// 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_LIBC_TYPES_SOCKLEN_T_H__ +#define __LLVM_LIBC_TYPES_SOCKLEN_T_H__ + +// The posix standard only says of socklen_t that it must be an integer type of +// width of at least 32 bits. The long type is defined as being at least 32 +// bits, so an unsigned long should be fine. + +typedef unsigned long socklen_t; + +#endif // __LLVM_LIBC_TYPES_SOCKLEN_T_H__ diff --git a/libc/include/llvm-libc-types/struct_sockaddr.h b/libc/include/llvm-libc-types/struct_sockaddr.h index 1ef907904ca3ec182ce2cec3bbceccdbae16c18c..9a6214c7d3e6b9b837e3a434d706a339dd38dea9 100644 --- a/libc/include/llvm-libc-types/struct_sockaddr.h +++ b/libc/include/llvm-libc-types/struct_sockaddr.h @@ -1,4 +1,4 @@ -//===-- Definition of struct stat -----------------------------------------===// +//===-- Definition of struct sockaddr -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __LLVM_LIBC_TYPES_STRUCT_STAT_H__ -#define __LLVM_LIBC_TYPES_STRUCT_STAT_H__ +#ifndef __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_H__ +#define __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_H__ #include @@ -15,7 +15,7 @@ struct sockaddr { sa_family_t sa_family; // sa_data is a variable length array. It is provided with a length of one // here as a placeholder. - char sa_data[1]; + char sa_data[]; }; -#endif // __LLVM_LIBC_TYPES_STRUCT_STAT_H__ +#endif // __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_H__ diff --git a/libc/include/llvm-libc-types/struct_sockaddr_un.h b/libc/include/llvm-libc-types/struct_sockaddr_un.h new file mode 100644 index 0000000000000000000000000000000000000000..9c3efea279256ec2927de18cba579bf94abdf843 --- /dev/null +++ b/libc/include/llvm-libc-types/struct_sockaddr_un.h @@ -0,0 +1,22 @@ +//===-- Definition of struct sockaddr_un ----------------------------------===// +// +// 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_LIBC_TYPES_STRUCT_SOCKADDR_UN_H__ +#define __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_UN_H__ + +#include + +// This is the sockaddr specialization for AF_UNIX or AF_LOCAL sockets, as +// defined by posix. + +struct sockaddr_un { + sa_family_t sun_family; /* AF_UNIX */ + char sun_path[108]; /* Pathname */ +}; + +#endif // __LLVM_LIBC_TYPES_STRUCT_SOCKADDR_UN_H__ diff --git a/libc/spec/posix.td b/libc/spec/posix.td index c7acf6d25a2d8739b8e639d1fcd149497c37990c..7e1cf892135acf99c3f305736310e41c5e149350 100644 --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -81,9 +81,14 @@ def RestrictedFdSetPtr : RestrictedPtrType; def GetoptArgvT : NamedType<"__getoptargv_t">; +def SAFamilyType : NamedType<"sa_family_t">; +def SocklenType : NamedType<"socklen_t">; + def StructSockAddr : NamedType<"struct sockaddr">; def StructSockAddrPtr : PtrType; -def SAFamilyType : NamedType<"sa_family_t">; +def ConstStructSockAddrPtr : ConstType; + +def StructSockAddrUn : NamedType<"struct sockaddr_un">; def POSIX : StandardSpec<"POSIX"> { PtrType CharPtr = PtrType; @@ -1400,7 +1405,10 @@ def POSIX : StandardSpec<"POSIX"> { Macro<"SOCK_PACKET">, ], // Macros [ - StructSockAddr, SAFamilyType, + SAFamilyType, + StructSockAddr, + StructSockAddrUn, + SocklenType, ], // Types [], // Enumerations [ @@ -1409,6 +1417,11 @@ def POSIX : StandardSpec<"POSIX"> { RetValSpec, [ArgSpec, ArgSpec, ArgSpec] >, + FunctionSpec< + "bind", + RetValSpec, + [ArgSpec, ArgSpec, ArgSpec] + >, ] // Functions >; diff --git a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h index 60252fe9cb877ab4f14d238ae3227992d822a793..65bbe6b099dd003b3635435721b9c0574e829974 100644 --- a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h +++ b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h @@ -53,13 +53,13 @@ LIBC_INLINE T remquo(T x, T y, int &q) { NormalFloat normalx(xbits), normaly(ybits); int exp = normalx.exponent - normaly.exponent; - typename NormalFloat::UIntType mx = normalx.mantissa, - my = normaly.mantissa; + typename NormalFloat::StorageType mx = normalx.mantissa, + my = normaly.mantissa; q = 0; while (exp >= 0) { unsigned shift_count = 0; - typename NormalFloat::UIntType n = mx; + typename NormalFloat::StorageType n = mx; for (shift_count = 0; n < my; n <<= 1, ++shift_count) ; diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h index 65c53921181a73a6a783d01d37faa73916640d4b..7f5dd0fca58d4ff88a03b7032f0378aac8c749a5 100644 --- a/libc/src/__support/FPUtil/FPBits.h +++ b/libc/src/__support/FPUtil/FPBits.h @@ -20,14 +20,6 @@ namespace LIBC_NAMESPACE { namespace fputil { -template struct MantissaWidth { - static constexpr unsigned VALUE = FloatProperties::MANTISSA_WIDTH; -}; - -template struct ExponentWidth { - static constexpr unsigned VALUE = FloatProperties::EXPONENT_WIDTH; -}; - // A generic class to represent single precision, double precision, and quad // precision IEEE 754 floating point formats. // On most platforms, the 'float' type corresponds to single precision floating @@ -36,80 +28,83 @@ template struct ExponentWidth { // floating numbers. On x86 platforms however, the 'long double' type maps to // an x87 floating point format. This format is an IEEE 754 extension format. // It is handled as an explicit specialization of this class. -template struct FPBits { +template struct FPBits : private FloatProperties { static_assert(cpp::is_floating_point_v, "FPBits instantiated with invalid type."); + using typename FloatProperties::StorageType; + using FloatProperties::TOTAL_LEN; + using FloatProperties::EXP_MANT_MASK; + using FloatProperties::EXP_MASK; + using FloatProperties::EXP_BIAS; + using FloatProperties::EXP_LEN; + using FloatProperties::FRACTION_MASK; + using FloatProperties::FRACTION_LEN; + using FloatProperties::QUIET_NAN_MASK; + using FloatProperties::SIGN_MASK; // Reinterpreting bits as an integer value and interpreting the bits of an // integer value as a floating point value is used in tests. So, a convenient // type is provided for such reinterpretations. - using FloatProp = FloatProperties; - using UIntType = typename FloatProp::UIntType; - - UIntType bits; + StorageType bits; - LIBC_INLINE constexpr void set_mantissa(UIntType mantVal) { - mantVal &= (FloatProp::MANTISSA_MASK); - bits &= ~(FloatProp::MANTISSA_MASK); + LIBC_INLINE constexpr void set_mantissa(StorageType mantVal) { + mantVal &= FRACTION_MASK; + bits &= ~FRACTION_MASK; bits |= mantVal; } - LIBC_INLINE constexpr UIntType get_mantissa() const { - return bits & FloatProp::MANTISSA_MASK; + LIBC_INLINE constexpr StorageType get_mantissa() const { + return bits & FRACTION_MASK; } - LIBC_INLINE constexpr void set_biased_exponent(UIntType expVal) { - expVal = (expVal << (FloatProp::MANTISSA_WIDTH)) & FloatProp::EXPONENT_MASK; - bits &= ~(FloatProp::EXPONENT_MASK); + LIBC_INLINE constexpr void set_biased_exponent(StorageType expVal) { + expVal = (expVal << FRACTION_LEN) & EXP_MASK; + bits &= ~EXP_MASK; bits |= expVal; } LIBC_INLINE constexpr uint16_t get_biased_exponent() const { - return uint16_t((bits & FloatProp::EXPONENT_MASK) >> - (FloatProp::MANTISSA_WIDTH)); + return uint16_t((bits & EXP_MASK) >> FRACTION_LEN); } // The function return mantissa with the implicit bit set iff the current // value is a valid normal number. - LIBC_INLINE constexpr UIntType get_explicit_mantissa() { + LIBC_INLINE constexpr StorageType get_explicit_mantissa() { return ((get_biased_exponent() > 0 && !is_inf_or_nan()) - ? (FloatProp::MANTISSA_MASK + 1) + ? (FRACTION_MASK + 1) : 0) | - (FloatProp::MANTISSA_MASK & bits); + (FRACTION_MASK & bits); } LIBC_INLINE constexpr void set_sign(bool signVal) { - bits |= FloatProp::SIGN_MASK; + bits |= SIGN_MASK; if (!signVal) - bits -= FloatProp::SIGN_MASK; + bits -= SIGN_MASK; } LIBC_INLINE constexpr bool get_sign() const { - return (bits & FloatProp::SIGN_MASK) != 0; + return (bits & SIGN_MASK) != 0; } - static_assert(sizeof(T) == sizeof(UIntType), + static_assert(sizeof(T) == sizeof(StorageType), "Data type and integral representation have different sizes."); - static constexpr int EXPONENT_BIAS = (1 << (ExponentWidth::VALUE - 1)) - 1; - static constexpr int MAX_EXPONENT = (1 << ExponentWidth::VALUE) - 1; + static constexpr int MAX_EXPONENT = (1 << EXP_LEN) - 1; - static constexpr UIntType MIN_SUBNORMAL = UIntType(1); - static constexpr UIntType MAX_SUBNORMAL = - (UIntType(1) << MantissaWidth::VALUE) - 1; - static constexpr UIntType MIN_NORMAL = - (UIntType(1) << MantissaWidth::VALUE); - static constexpr UIntType MAX_NORMAL = - ((UIntType(MAX_EXPONENT) - 1) << MantissaWidth::VALUE) | MAX_SUBNORMAL; + static constexpr StorageType MIN_SUBNORMAL = StorageType(1); + static constexpr StorageType MAX_SUBNORMAL = FRACTION_MASK; + static constexpr StorageType MIN_NORMAL = (StorageType(1) << FRACTION_LEN); + static constexpr StorageType MAX_NORMAL = + ((StorageType(MAX_EXPONENT) - 1) << FRACTION_LEN) | MAX_SUBNORMAL; // We don't want accidental type promotions/conversions, so we require exact // type match. template , int> = 0> LIBC_INLINE constexpr explicit FPBits(XType x) - : bits(cpp::bit_cast(x)) {} + : bits(cpp::bit_cast(x)) {} template , int> = 0> + cpp::enable_if_t, int> = 0> LIBC_INLINE constexpr explicit FPBits(XType x) : bits(x) {} LIBC_INLINE constexpr FPBits() : bits(0) {} @@ -117,15 +112,15 @@ template struct FPBits { LIBC_INLINE constexpr T get_val() const { return cpp::bit_cast(bits); } LIBC_INLINE constexpr void set_val(T value) { - bits = cpp::bit_cast(value); + bits = cpp::bit_cast(value); } LIBC_INLINE constexpr explicit operator T() const { return get_val(); } - LIBC_INLINE constexpr UIntType uintval() const { return bits; } + LIBC_INLINE constexpr StorageType uintval() const { return bits; } LIBC_INLINE constexpr int get_exponent() const { - return int(get_biased_exponent()) - EXPONENT_BIAS; + return int(get_biased_exponent()) - EXP_BIAS; } // If the number is subnormal, the exponent is treated as if it were the @@ -139,9 +134,9 @@ template struct FPBits { if (is_zero()) { return 0; } else if (biased_exp == 0) { - return 1 - EXPONENT_BIAS; + return 1 - EXP_BIAS; } else { - return biased_exp - EXPONENT_BIAS; + return biased_exp - EXP_BIAS; } } @@ -151,32 +146,29 @@ template struct FPBits { } LIBC_INLINE constexpr bool is_inf() const { - return (bits & FloatProp::EXP_MANT_MASK) == FloatProp::EXPONENT_MASK; + return (bits & EXP_MANT_MASK) == EXP_MASK; } LIBC_INLINE constexpr bool is_nan() const { - return (bits & FloatProp::EXP_MANT_MASK) > FloatProp::EXPONENT_MASK; + return (bits & EXP_MANT_MASK) > EXP_MASK; } LIBC_INLINE constexpr bool is_quiet_nan() const { - return (bits & FloatProp::EXP_MANT_MASK) == - (FloatProp::EXPONENT_MASK | FloatProp::QUIET_NAN_MASK); + return (bits & EXP_MANT_MASK) == (EXP_MASK | QUIET_NAN_MASK); } LIBC_INLINE constexpr bool is_inf_or_nan() const { - return (bits & FloatProp::EXPONENT_MASK) == FloatProp::EXPONENT_MASK; + return (bits & EXP_MASK) == EXP_MASK; } LIBC_INLINE static constexpr T zero(bool sign = false) { - return FPBits(sign ? FloatProp::SIGN_MASK : UIntType(0)).get_val(); + return FPBits(sign ? SIGN_MASK : StorageType(0)).get_val(); } LIBC_INLINE static constexpr T neg_zero() { return zero(true); } LIBC_INLINE static constexpr T inf(bool sign = false) { - return FPBits((sign ? FloatProp::SIGN_MASK : UIntType(0)) | - FloatProp::EXPONENT_MASK) - .get_val(); + return FPBits((sign ? SIGN_MASK : StorageType(0)) | EXP_MASK).get_val(); } LIBC_INLINE static constexpr T neg_inf() { return inf(true); } @@ -197,14 +189,14 @@ template struct FPBits { return FPBits(MAX_SUBNORMAL).get_val(); } - LIBC_INLINE static constexpr T build_nan(UIntType v) { + LIBC_INLINE static constexpr T build_nan(StorageType v) { FPBits bits(inf()); bits.set_mantissa(v); return T(bits); } - LIBC_INLINE static constexpr T build_quiet_nan(UIntType v) { - return build_nan(FloatProp::QUIET_NAN_MASK | v); + LIBC_INLINE static constexpr T build_quiet_nan(StorageType v) { + return build_nan(QUIET_NAN_MASK | v); } // The function convert integer number and unbiased exponent to proper float @@ -217,10 +209,11 @@ template struct FPBits { // 3) The function did not check exponent high limit. // 4) "number" zero value is not processed correctly. // 5) Number is unsigned, so the result can be only positive. - LIBC_INLINE static constexpr FPBits make_value(UIntType number, int ep) { + LIBC_INLINE static constexpr FPBits make_value(StorageType number, + int ep) { FPBits result; // offset: +1 for sign, but -1 for implicit first bit - int lz = cpp::countl_zero(number) - FloatProp::EXPONENT_WIDTH; + int lz = cpp::countl_zero(number) - EXP_LEN; number <<= lz; ep -= lz; @@ -235,7 +228,7 @@ template struct FPBits { } LIBC_INLINE static constexpr FPBits - create_value(bool sign, UIntType biased_exp, UIntType mantissa) { + create_value(bool sign, StorageType biased_exp, StorageType mantissa) { FPBits result; result.set_sign(sign); result.set_biased_exponent(biased_exp); diff --git a/libc/src/__support/FPUtil/FloatProperties.h b/libc/src/__support/FPUtil/FloatProperties.h index 3f7dbdc5af34254e76b6ce0ff064997bc797fbd7..896c29919e2f77fe743f6216fb0bd740de7cb620 100644 --- a/libc/src/__support/FPUtil/FloatProperties.h +++ b/libc/src/__support/FPUtil/FloatProperties.h @@ -41,42 +41,42 @@ enum class FPEncoding { template struct FPBaseProperties {}; template <> struct FPBaseProperties { - using UIntType = uint16_t; - LIBC_INLINE_VAR static constexpr int TOTAL_BITS = 16; - LIBC_INLINE_VAR static constexpr int SIG_BITS = 10; - LIBC_INLINE_VAR static constexpr int EXP_BITS = 5; + using StorageType = uint16_t; + LIBC_INLINE_VAR static constexpr int TOTAL_LEN = 16; + LIBC_INLINE_VAR static constexpr int SIG_LEN = 10; + LIBC_INLINE_VAR static constexpr int EXP_LEN = 5; LIBC_INLINE_VAR static constexpr auto ENCODING = FPEncoding::IEEE754; }; template <> struct FPBaseProperties { - using UIntType = uint32_t; - LIBC_INLINE_VAR static constexpr int TOTAL_BITS = 32; - LIBC_INLINE_VAR static constexpr int SIG_BITS = 23; - LIBC_INLINE_VAR static constexpr int EXP_BITS = 8; + using StorageType = uint32_t; + LIBC_INLINE_VAR static constexpr int TOTAL_LEN = 32; + LIBC_INLINE_VAR static constexpr int SIG_LEN = 23; + LIBC_INLINE_VAR static constexpr int EXP_LEN = 8; LIBC_INLINE_VAR static constexpr auto ENCODING = FPEncoding::IEEE754; }; template <> struct FPBaseProperties { - using UIntType = uint64_t; - LIBC_INLINE_VAR static constexpr int TOTAL_BITS = 64; - LIBC_INLINE_VAR static constexpr int SIG_BITS = 52; - LIBC_INLINE_VAR static constexpr int EXP_BITS = 11; + using StorageType = uint64_t; + LIBC_INLINE_VAR static constexpr int TOTAL_LEN = 64; + LIBC_INLINE_VAR static constexpr int SIG_LEN = 52; + LIBC_INLINE_VAR static constexpr int EXP_LEN = 11; LIBC_INLINE_VAR static constexpr auto ENCODING = FPEncoding::IEEE754; }; template <> struct FPBaseProperties { - using UIntType = UInt128; - LIBC_INLINE_VAR static constexpr int TOTAL_BITS = 128; - LIBC_INLINE_VAR static constexpr int SIG_BITS = 112; - LIBC_INLINE_VAR static constexpr int EXP_BITS = 15; + using StorageType = UInt128; + LIBC_INLINE_VAR static constexpr int TOTAL_LEN = 128; + LIBC_INLINE_VAR static constexpr int SIG_LEN = 112; + LIBC_INLINE_VAR static constexpr int EXP_LEN = 15; LIBC_INLINE_VAR static constexpr auto ENCODING = FPEncoding::IEEE754; }; template <> struct FPBaseProperties { - using UIntType = UInt128; - LIBC_INLINE_VAR static constexpr int TOTAL_BITS = 80; - LIBC_INLINE_VAR static constexpr int SIG_BITS = 64; - LIBC_INLINE_VAR static constexpr int EXP_BITS = 15; + using StorageType = UInt128; + LIBC_INLINE_VAR static constexpr int TOTAL_LEN = 80; + LIBC_INLINE_VAR static constexpr int SIG_LEN = 64; + LIBC_INLINE_VAR static constexpr int EXP_LEN = 15; LIBC_INLINE_VAR static constexpr auto ENCODING = FPEncoding::X86_ExtendedPrecision; }; @@ -87,92 +87,88 @@ template struct FPProperties : public internal::FPBaseProperties { private: using UP = internal::FPBaseProperties; - // The number of bits to represent sign. For documentation purpose, always 1. - LIBC_INLINE_VAR static constexpr int SIGN_BITS = 1; - using UP::EXP_BITS; // The number of bits for the *exponent* part - using UP::SIG_BITS; // The number of bits for the *significand* part - using UP::TOTAL_BITS; // For convenience, the sum of `SIG_BITS`, `EXP_BITS`, - // and `SIGN_BITS`. - static_assert(SIGN_BITS + EXP_BITS + SIG_BITS == TOTAL_BITS); public: + // The number of bits to represent sign. For documentation purpose, always 1. + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1; + using UP::EXP_LEN; // The number of bits for the *exponent* part + using UP::SIG_LEN; // The number of bits for the *significand* part + using UP::TOTAL_LEN; // For convenience, the sum of `SIG_LEN`, `EXP_LEN`, + // and `SIGN_LEN`. + static_assert(SIGN_LEN + EXP_LEN + SIG_LEN == TOTAL_LEN); + // An unsigned integer that is wide enough to contain all of the floating // point bits. - using UIntType = typename UP::UIntType; + using StorageType = typename UP::StorageType; - // The number of bits in UIntType. - LIBC_INLINE_VAR static constexpr int UINTTYPE_BITS = - sizeof(UIntType) * CHAR_BIT; - static_assert(UINTTYPE_BITS >= TOTAL_BITS); + // The number of bits in StorageType. + LIBC_INLINE_VAR static constexpr int STORAGE_LEN = + sizeof(StorageType) * CHAR_BIT; + static_assert(STORAGE_LEN >= TOTAL_LEN); -private: // The exponent bias. Always positive. LIBC_INLINE_VAR static constexpr int32_t EXP_BIAS = - (1U << (EXP_BITS - 1U)) - 1U; + (1U << (EXP_LEN - 1U)) - 1U; static_assert(EXP_BIAS > 0); +private: // The shift amount to get the *significand* part to the least significant // bit. Always `0` but kept for consistency. LIBC_INLINE_VAR static constexpr int SIG_MASK_SHIFT = 0; // The shift amount to get the *exponent* part to the least significant bit. - LIBC_INLINE_VAR static constexpr int EXP_MASK_SHIFT = SIG_BITS; + LIBC_INLINE_VAR static constexpr int EXP_MASK_SHIFT = SIG_LEN; // The shift amount to get the *sign* part to the least significant bit. - LIBC_INLINE_VAR static constexpr int SIGN_MASK_SHIFT = SIG_BITS + EXP_BITS; + LIBC_INLINE_VAR static constexpr int SIGN_MASK_SHIFT = SIG_LEN + EXP_LEN; // The bit pattern that keeps only the *significand* part. - LIBC_INLINE_VAR static constexpr UIntType SIG_MASK = - mask_trailing_ones() << SIG_MASK_SHIFT; - // The bit pattern that keeps only the *exponent* part. - LIBC_INLINE_VAR static constexpr UIntType EXP_MASK = - mask_trailing_ones() << EXP_MASK_SHIFT; + LIBC_INLINE_VAR static constexpr StorageType SIG_MASK = + mask_trailing_ones() << SIG_MASK_SHIFT; public: + // The bit pattern that keeps only the *exponent* part. + LIBC_INLINE_VAR static constexpr StorageType EXP_MASK = + mask_trailing_ones() << EXP_MASK_SHIFT; // The bit pattern that keeps only the *sign* part. - LIBC_INLINE_VAR static constexpr UIntType SIGN_MASK = - mask_trailing_ones() << SIGN_MASK_SHIFT; + LIBC_INLINE_VAR static constexpr StorageType SIGN_MASK = + mask_trailing_ones() << SIGN_MASK_SHIFT; // The bit pattern that keeps only the *sign + exponent + significand* part. - LIBC_INLINE_VAR static constexpr UIntType FP_MASK = - mask_trailing_ones(); + LIBC_INLINE_VAR static constexpr StorageType FP_MASK = + mask_trailing_ones(); static_assert((SIG_MASK & EXP_MASK & SIGN_MASK) == 0, "masks disjoint"); static_assert((SIG_MASK | EXP_MASK | SIGN_MASK) == FP_MASK, "masks cover"); private: - LIBC_INLINE static constexpr UIntType bit_at(int position) { - return UIntType(1) << position; + LIBC_INLINE static constexpr StorageType bit_at(int position) { + return StorageType(1) << position; } - LIBC_INLINE_VAR static constexpr UIntType QNAN_MASK = + LIBC_INLINE_VAR static constexpr StorageType QNAN_MASK = UP::ENCODING == internal::FPEncoding::X86_ExtendedPrecision - ? bit_at(SIG_BITS - 1) | bit_at(SIG_BITS - 2) // 0b1100... - : bit_at(SIG_BITS - 1); // 0b1000... + ? bit_at(SIG_LEN - 1) | bit_at(SIG_LEN - 2) // 0b1100... + : bit_at(SIG_LEN - 1); // 0b1000... - LIBC_INLINE_VAR static constexpr UIntType SNAN_MASK = + LIBC_INLINE_VAR static constexpr StorageType SNAN_MASK = UP::ENCODING == internal::FPEncoding::X86_ExtendedPrecision - ? bit_at(SIG_BITS - 1) | bit_at(SIG_BITS - 3) // 0b1010... - : bit_at(SIG_BITS - 2); // 0b0100... - - // The number of bits after the decimal dot when the number if in normal form. - LIBC_INLINE_VAR static constexpr int FRACTION_BITS = - UP::ENCODING == internal::FPEncoding::X86_ExtendedPrecision ? SIG_BITS - 1 - : SIG_BITS; + ? bit_at(SIG_LEN - 1) | bit_at(SIG_LEN - 3) // 0b1010... + : bit_at(SIG_LEN - 2); // 0b0100... public: - LIBC_INLINE_VAR static constexpr uint32_t BIT_WIDTH = TOTAL_BITS; - LIBC_INLINE_VAR static constexpr uint32_t MANTISSA_WIDTH = FRACTION_BITS; + // The number of bits after the decimal dot when the number is in normal form. + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = + UP::ENCODING == internal::FPEncoding::X86_ExtendedPrecision ? SIG_LEN - 1 + : SIG_LEN; LIBC_INLINE_VAR static constexpr uint32_t MANTISSA_PRECISION = - MANTISSA_WIDTH + 1; - LIBC_INLINE_VAR static constexpr UIntType MANTISSA_MASK = - mask_trailing_ones(); - LIBC_INLINE_VAR static constexpr uint32_t EXPONENT_WIDTH = EXP_BITS; - LIBC_INLINE_VAR static constexpr int32_t EXPONENT_BIAS = EXP_BIAS; - LIBC_INLINE_VAR static constexpr UIntType EXPONENT_MASK = EXP_MASK; - LIBC_INLINE_VAR static constexpr UIntType EXP_MANT_MASK = EXP_MASK | SIG_MASK; + FRACTION_LEN + 1; + LIBC_INLINE_VAR static constexpr StorageType FRACTION_MASK = + mask_trailing_ones(); + LIBC_INLINE_VAR static constexpr StorageType EXP_MANT_MASK = + EXP_MASK | SIG_MASK; // If a number x is a NAN, then it is a quiet NAN if: // QuietNaNMask & bits(x) != 0 // Else, it is a signalling NAN. - static constexpr UIntType QUIET_NAN_MASK = QNAN_MASK; + static constexpr StorageType QUIET_NAN_MASK = QNAN_MASK; }; //----------------------------------------------------------------------------- diff --git a/libc/src/__support/FPUtil/Hypot.h b/libc/src/__support/FPUtil/Hypot.h index 42d9e1b3f8cec5c96458ec1822da1fe3a830ae71..1f1cf31c8017911e60f25106f04898168a733d7d 100644 --- a/libc/src/__support/FPUtil/Hypot.h +++ b/libc/src/__support/FPUtil/Hypot.h @@ -105,8 +105,8 @@ template <> struct DoubleLength { template , int> = 0> LIBC_INLINE T hypot(T x, T y) { using FPBits_t = FPBits; - using UIntType = typename FPBits::UIntType; - using DUIntType = typename DoubleLength::Type; + using StorageType = typename FPBits::StorageType; + using DStorageType = typename DoubleLength::Type; FPBits_t x_bits(x), y_bits(y); @@ -124,13 +124,13 @@ LIBC_INLINE T hypot(T x, T y) { uint16_t y_exp = y_bits.get_biased_exponent(); uint16_t exp_diff = (x_exp > y_exp) ? (x_exp - y_exp) : (y_exp - x_exp); - if ((exp_diff >= MantissaWidth::VALUE + 2) || (x == 0) || (y == 0)) { + if ((exp_diff >= FPBits_t::FRACTION_LEN + 2) || (x == 0) || (y == 0)) { return abs(x) + abs(y); } uint16_t a_exp, b_exp, out_exp; - UIntType a_mant, b_mant; - DUIntType a_mant_sq, b_mant_sq; + StorageType a_mant, b_mant; + DStorageType a_mant_sq, b_mant_sq; bool sticky_bits; if (abs(x) >= abs(y)) { @@ -148,17 +148,17 @@ LIBC_INLINE T hypot(T x, T y) { out_exp = a_exp; // Add an extra bit to simplify the final rounding bit computation. - constexpr UIntType ONE = UIntType(1) << (MantissaWidth::VALUE + 1); + constexpr StorageType ONE = StorageType(1) << (FPBits_t::FRACTION_LEN + 1); a_mant <<= 1; b_mant <<= 1; - UIntType leading_one; + StorageType leading_one; int y_mant_width; if (a_exp != 0) { leading_one = ONE; a_mant |= ONE; - y_mant_width = MantissaWidth::VALUE + 1; + y_mant_width = FPBits_t::FRACTION_LEN + 1; } else { leading_one = internal::find_leading_one(a_mant, y_mant_width); a_exp = 1; @@ -170,8 +170,8 @@ LIBC_INLINE T hypot(T x, T y) { b_exp = 1; } - a_mant_sq = static_cast(a_mant) * a_mant; - b_mant_sq = static_cast(b_mant) * b_mant; + a_mant_sq = static_cast(a_mant) * a_mant; + b_mant_sq = static_cast(b_mant) * b_mant; // At this point, a_exp >= b_exp > a_exp - 25, so in order to line up aSqMant // and bSqMant, we need to shift bSqMant to the right by (a_exp - b_exp) bits. @@ -180,12 +180,12 @@ LIBC_INLINE T hypot(T x, T y) { // difference between a and b. uint16_t shift_length = static_cast(2 * (a_exp - b_exp)); sticky_bits = - ((b_mant_sq & ((DUIntType(1) << shift_length) - DUIntType(1))) != - DUIntType(0)); + ((b_mant_sq & ((DStorageType(1) << shift_length) - DStorageType(1))) != + DStorageType(0)); b_mant_sq >>= shift_length; - DUIntType sum = a_mant_sq + b_mant_sq; - if (sum >= (DUIntType(1) << (2 * y_mant_width + 2))) { + DStorageType sum = a_mant_sq + b_mant_sq; + if (sum >= (DStorageType(1) << (2 * y_mant_width + 2))) { // a^2 + b^2 >= 4* leading_one^2, so we will need an extra bit to the left. if (leading_one == ONE) { // For normal result, we discard the last 2 bits of the sum and increase @@ -207,22 +207,22 @@ LIBC_INLINE T hypot(T x, T y) { } } - UIntType y_new = leading_one; - UIntType r = static_cast(sum >> y_mant_width) - leading_one; - UIntType tail_bits = static_cast(sum) & (leading_one - 1); + StorageType y_new = leading_one; + StorageType r = static_cast(sum >> y_mant_width) - leading_one; + StorageType tail_bits = static_cast(sum) & (leading_one - 1); - for (UIntType current_bit = leading_one >> 1; current_bit; + for (StorageType current_bit = leading_one >> 1; current_bit; current_bit >>= 1) { r = (r << 1) + ((tail_bits & current_bit) ? 1 : 0); - UIntType tmp = (y_new << 1) + current_bit; // 2*y_new(n - 1) + 2^(-n) + StorageType tmp = (y_new << 1) + current_bit; // 2*y_new(n - 1) + 2^(-n) if (r >= tmp) { r -= tmp; y_new += current_bit; } } - bool round_bit = y_new & UIntType(1); - bool lsb = y_new & UIntType(2); + bool round_bit = y_new & StorageType(1); + bool lsb = y_new & StorageType(2); if (y_new >= ONE) { y_new -= ONE; @@ -258,7 +258,7 @@ LIBC_INLINE T hypot(T x, T y) { } } - y_new |= static_cast(out_exp) << MantissaWidth::VALUE; + y_new |= static_cast(out_exp) << FPBits_t::FRACTION_LEN; return cpp::bit_cast(y_new); } diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h index 08adb074b121fa1564abb04a0f99b54cc137b5f5..4a475d1e09c499f250ea2d7cc9f4e60afc3936dc 100644 --- a/libc/src/__support/FPUtil/ManipulationFunctions.h +++ b/libc/src/__support/FPUtil/ManipulationFunctions.h @@ -130,7 +130,7 @@ LIBC_INLINE T ldexp(T x, int exp) { // early. Because the result of the ldexp operation can be a subnormal number, // we need to accommodate the (mantissaWidht + 1) worth of shift in // calculating the limit. - int exp_limit = FPBits::MAX_EXPONENT + MantissaWidth::VALUE + 1; + int exp_limit = FPBits::MAX_EXPONENT + FPBits::FRACTION_LEN + 1; if (exp > exp_limit) return bits.get_sign() ? T(FPBits::neg_inf()) : T(FPBits::inf()); @@ -164,8 +164,8 @@ LIBC_INLINE T nextafter(T from, U to) { if (static_cast(from) == to) return static_cast(to); - using UIntType = typename FPBits::UIntType; - UIntType int_val = from_bits.uintval(); + using StorageType = typename FPBits::StorageType; + StorageType int_val = from_bits.uintval(); if (from != FPBits::zero()) { if ((static_cast(from) < to) == (from > FPBits::zero())) { ++int_val; @@ -178,10 +178,10 @@ LIBC_INLINE T nextafter(T from, U to) { int_val |= FloatProperties::SIGN_MASK; } - UIntType exponent_bits = int_val & FloatProperties::EXPONENT_MASK; - if (exponent_bits == UIntType(0)) + StorageType exponent_bits = int_val & FloatProperties::EXP_MASK; + if (exponent_bits == StorageType(0)) raise_except_if_required(FE_UNDERFLOW | FE_INEXACT); - else if (exponent_bits == FloatProperties::EXPONENT_MASK) + else if (exponent_bits == FloatProperties::EXP_MASK) raise_except_if_required(FE_OVERFLOW | FE_INEXACT); return cpp::bit_cast(int_val); diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h index 8c4b24803bec1d31d61dc5229adb70adf0250008..64c44e0b3a0c44c768e8afd37de86c1be99e04cb 100644 --- a/libc/src/__support/FPUtil/NearestIntegerOperations.h +++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h @@ -36,7 +36,7 @@ LIBC_INLINE T trunc(T x) { // If the exponent is greater than the most negative mantissa // exponent, then x is already an integer. - if (exponent >= static_cast(MantissaWidth::VALUE)) + if (exponent >= static_cast(FPBits::FRACTION_LEN)) return x; // If the exponent is such that abs(x) is less than 1, then return 0. @@ -47,7 +47,7 @@ LIBC_INLINE T trunc(T x) { return T(0.0); } - int trim_size = MantissaWidth::VALUE - exponent; + int trim_size = FPBits::FRACTION_LEN - exponent; bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size); return T(bits); } @@ -65,7 +65,7 @@ LIBC_INLINE T ceil(T x) { // If the exponent is greater than the most negative mantissa // exponent, then x is already an integer. - if (exponent >= static_cast(MantissaWidth::VALUE)) + if (exponent >= static_cast(FPBits::FRACTION_LEN)) return x; if (exponent <= -1) { @@ -75,7 +75,7 @@ LIBC_INLINE T ceil(T x) { return T(1.0); } - uint32_t trim_size = MantissaWidth::VALUE - exponent; + uint32_t trim_size = FPBits::FRACTION_LEN - exponent; bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size); T trunc_value = T(bits); @@ -102,7 +102,7 @@ LIBC_INLINE T floor(T x) { template , int> = 0> LIBC_INLINE T round(T x) { - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; FPBits bits(x); // If x is infinity NaN or zero, return it. @@ -114,7 +114,7 @@ LIBC_INLINE T round(T x) { // If the exponent is greater than the most negative mantissa // exponent, then x is already an integer. - if (exponent >= static_cast(MantissaWidth::VALUE)) + if (exponent >= static_cast(FPBits::FRACTION_LEN)) return x; if (exponent == -1) { @@ -133,9 +133,9 @@ LIBC_INLINE T round(T x) { return T(0.0); } - uint32_t trim_size = MantissaWidth::VALUE - exponent; + uint32_t trim_size = FPBits::FRACTION_LEN - exponent; bool half_bit_set = - bool(bits.get_mantissa() & (UIntType(1) << (trim_size - 1))); + bool(bits.get_mantissa() & (StorageType(1) << (trim_size - 1))); bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size); T trunc_value = T(bits); @@ -154,7 +154,7 @@ LIBC_INLINE T round(T x) { template , int> = 0> LIBC_INLINE T round_using_current_rounding_mode(T x) { - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; FPBits bits(x); // If x is infinity NaN or zero, return it. @@ -167,7 +167,7 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) { // If the exponent is greater than the most negative mantissa // exponent, then x is already an integer. - if (exponent >= static_cast(MantissaWidth::VALUE)) + if (exponent >= static_cast(FPBits::FRACTION_LEN)) return x; if (exponent <= -1) { @@ -188,7 +188,7 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) { } } - uint32_t trim_size = MantissaWidth::VALUE - exponent; + uint32_t trim_size = FPBits::FRACTION_LEN - exponent; FPBits new_bits = bits; new_bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size); T trunc_value = T(new_bits); @@ -197,12 +197,14 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) { if (trunc_value == x) return x; - UIntType trim_value = bits.get_mantissa() & ((UIntType(1) << trim_size) - 1); - UIntType half_value = (UIntType(1) << (trim_size - 1)); + StorageType trim_value = + bits.get_mantissa() & ((StorageType(1) << trim_size) - 1); + StorageType half_value = (StorageType(1) << (trim_size - 1)); // If exponent is 0, trimSize will be equal to the mantissa width, and // truncIsOdd` will not be correct. So, we handle it as a special case // below. - UIntType trunc_is_odd = new_bits.get_mantissa() & (UIntType(1) << trim_size); + StorageType trunc_is_odd = + new_bits.get_mantissa() & (StorageType(1) << trim_size); switch (rounding_mode) { case FE_DOWNWARD: diff --git a/libc/src/__support/FPUtil/NormalFloat.h b/libc/src/__support/FPUtil/NormalFloat.h index d3236316a87995165f6aa2ad1e03e561b5c936bf..e70c89a7dbe15aa3c79c5439055e1985c9b0df30 100644 --- a/libc/src/__support/FPUtil/NormalFloat.h +++ b/libc/src/__support/FPUtil/NormalFloat.h @@ -31,21 +31,22 @@ template struct NormalFloat { cpp::is_floating_point_v, "NormalFloat template parameter has to be a floating point type."); - using UIntType = typename FPBits::UIntType; - static constexpr UIntType ONE = (UIntType(1) << MantissaWidth::VALUE); + using StorageType = typename FPBits::StorageType; + static constexpr StorageType ONE = + (StorageType(1) << FPBits::FRACTION_LEN); // Unbiased exponent value. int32_t exponent; - UIntType mantissa; - // We want |UIntType| to have atleast one bit more than the actual mantissa + StorageType mantissa; + // We want |StorageType| to have atleast one bit more than the actual mantissa // bit width to accommodate the implicit 1 value. - static_assert(sizeof(UIntType) * 8 >= MantissaWidth::VALUE + 1, + static_assert(sizeof(StorageType) * 8 >= FPBits::FRACTION_LEN + 1, "Bad type for mantissa in NormalFloat."); bool sign; - LIBC_INLINE NormalFloat(int32_t e, UIntType m, bool s) + LIBC_INLINE NormalFloat(int32_t e, StorageType m, bool s) : exponent(e), mantissa(m), sign(s) { if (mantissa >= ONE) return; @@ -90,9 +91,9 @@ template struct NormalFloat { } LIBC_INLINE operator T() const { - int biased_exponent = exponent + FPBits::EXPONENT_BIAS; + int biased_exponent = exponent + FPBits::EXP_BIAS; // Max exponent is of the form 0xFF...E. That is why -2 and not -1. - constexpr int MAX_EXPONENT_VALUE = (1 << ExponentWidth::VALUE) - 2; + constexpr int MAX_EXPONENT_VALUE = (1 << FPBits::EXP_LEN) - 2; if (biased_exponent > MAX_EXPONENT_VALUE) { return sign ? T(FPBits::neg_inf()) : T(FPBits::inf()); } @@ -100,20 +101,20 @@ template struct NormalFloat { FPBits result(T(0.0)); result.set_sign(sign); - constexpr int SUBNORMAL_EXPONENT = -FPBits::EXPONENT_BIAS + 1; + constexpr int SUBNORMAL_EXPONENT = -FPBits::EXP_BIAS + 1; if (exponent < SUBNORMAL_EXPONENT) { unsigned shift = SUBNORMAL_EXPONENT - exponent; // Since exponent > subnormalExponent, shift is strictly greater than // zero. - if (shift <= MantissaWidth::VALUE + 1) { + if (shift <= FPBits::FRACTION_LEN + 1) { // Generate a subnormal number. Might lead to loss of precision. // We round to nearest and round halfway cases to even. - const UIntType shift_out_mask = (UIntType(1) << shift) - 1; - const UIntType shift_out_value = mantissa & shift_out_mask; - const UIntType halfway_value = UIntType(1) << (shift - 1); + const StorageType shift_out_mask = (StorageType(1) << shift) - 1; + const StorageType shift_out_value = mantissa & shift_out_mask; + const StorageType halfway_value = StorageType(1) << (shift - 1); result.set_biased_exponent(0); result.set_mantissa(mantissa >> shift); - UIntType new_mantissa = result.get_mantissa(); + StorageType new_mantissa = result.get_mantissa(); if (shift_out_value > halfway_value) { new_mantissa += 1; } else if (shift_out_value == halfway_value) { @@ -133,7 +134,7 @@ template struct NormalFloat { } } - result.set_biased_exponent(exponent + FPBits::EXPONENT_BIAS); + result.set_biased_exponent(exponent + FPBits::EXP_BIAS); result.set_mantissa(mantissa); return T(result); } @@ -153,17 +154,17 @@ private: // Normalize subnormal numbers. if (bits.get_biased_exponent() == 0) { unsigned shift = evaluate_normalization_shift(bits.get_mantissa()); - mantissa = UIntType(bits.get_mantissa()) << shift; - exponent = 1 - FPBits::EXPONENT_BIAS - shift; + mantissa = StorageType(bits.get_mantissa()) << shift; + exponent = 1 - FPBits::EXP_BIAS - shift; } else { - exponent = bits.get_biased_exponent() - FPBits::EXPONENT_BIAS; + exponent = bits.get_biased_exponent() - FPBits::EXP_BIAS; mantissa = ONE | bits.get_mantissa(); } } - LIBC_INLINE unsigned evaluate_normalization_shift(UIntType m) { + LIBC_INLINE unsigned evaluate_normalization_shift(StorageType m) { unsigned shift = 0; - for (; (ONE & m) == 0 && (shift < MantissaWidth::VALUE); + for (; (ONE & m) == 0 && (shift < FPBits::FRACTION_LEN); m <<= 1, ++shift) ; return shift; @@ -208,29 +209,29 @@ NormalFloat::init_from_bits(FPBits bits) { } template <> LIBC_INLINE NormalFloat::operator long double() const { - int biased_exponent = exponent + FPBits::EXPONENT_BIAS; + using LDBits = FPBits; + int biased_exponent = exponent + LDBits::EXP_BIAS; // Max exponent is of the form 0xFF...E. That is why -2 and not -1. - constexpr int MAX_EXPONENT_VALUE = - (1 << ExponentWidth::VALUE) - 2; + constexpr int MAX_EXPONENT_VALUE = (1 << LDBits::EXP_LEN) - 2; if (biased_exponent > MAX_EXPONENT_VALUE) { - return sign ? FPBits::neg_inf() : FPBits::inf(); + return sign ? LDBits::neg_inf() : LDBits::inf(); } FPBits result(0.0l); result.set_sign(sign); - constexpr int SUBNORMAL_EXPONENT = -FPBits::EXPONENT_BIAS + 1; + constexpr int SUBNORMAL_EXPONENT = -LDBits::EXP_BIAS + 1; if (exponent < SUBNORMAL_EXPONENT) { unsigned shift = SUBNORMAL_EXPONENT - exponent; - if (shift <= MantissaWidth::VALUE + 1) { + if (shift <= LDBits::FRACTION_LEN + 1) { // Generate a subnormal number. Might lead to loss of precision. // We round to nearest and round halfway cases to even. - const UIntType shift_out_mask = (UIntType(1) << shift) - 1; - const UIntType shift_out_value = mantissa & shift_out_mask; - const UIntType halfway_value = UIntType(1) << (shift - 1); + const StorageType shift_out_mask = (StorageType(1) << shift) - 1; + const StorageType shift_out_value = mantissa & shift_out_mask; + const StorageType halfway_value = StorageType(1) << (shift - 1); result.set_biased_exponent(0); result.set_mantissa(mantissa >> shift); - UIntType new_mantissa = result.get_mantissa(); + StorageType new_mantissa = result.get_mantissa(); if (shift_out_value > halfway_value) { new_mantissa += 1; } else if (shift_out_value == halfway_value) { diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h index 5f0d8f49ccf64dc2911ec75f5b1962993170ea2e..f8056fecb8ecc14735c9e7855ed975ac4aab34ab 100644 --- a/libc/src/__support/FPUtil/dyadic_float.h +++ b/libc/src/__support/FPUtil/dyadic_float.h @@ -42,10 +42,10 @@ template struct DyadicFloat { template , int> = 0> DyadicFloat(T x) { - static_assert(FloatProperties::MANTISSA_WIDTH < Bits); + static_assert(FloatProperties::FRACTION_LEN < Bits); FPBits x_bits(x); sign = x_bits.get_sign(); - exponent = x_bits.get_exponent() - FloatProperties::MANTISSA_WIDTH; + exponent = x_bits.get_exponent() - FloatProperties::FRACTION_LEN; mantissa = MantissaType(x_bits.get_explicit_mantissa()); normalize(); } @@ -86,7 +86,7 @@ template struct DyadicFloat { // TODO(lntue): Test or add specialization for x86 long double. template && - (FloatProperties::MANTISSA_WIDTH < Bits), + (FloatProperties::FRACTION_LEN < Bits), void>> explicit operator T() const { // TODO(lntue): Do we need to treat signed zeros properly? @@ -95,10 +95,10 @@ template struct DyadicFloat { // Assume that it is normalized, and output is also normal. constexpr uint32_t PRECISION = FloatProperties::MANTISSA_PRECISION; - using output_bits_t = typename FPBits::UIntType; + using output_bits_t = typename FPBits::StorageType; - int exp_hi = exponent + static_cast((Bits - 1) + - FloatProperties::EXPONENT_BIAS); + int exp_hi = + exponent + static_cast((Bits - 1) + FloatProperties::EXP_BIAS); bool denorm = false; uint32_t shift = Bits - PRECISION; @@ -107,7 +107,7 @@ template struct DyadicFloat { denorm = true; shift = (Bits - PRECISION) + static_cast(1 - exp_hi); - exp_hi = FloatProperties::EXPONENT_BIAS; + exp_hi = FloatProperties::EXP_BIAS; } int exp_lo = exp_hi - static_cast(PRECISION) - 1; @@ -116,7 +116,7 @@ template struct DyadicFloat { T d_hi = FPBits::create_value(sign, exp_hi, static_cast(m_hi) & - FloatProperties::MANTISSA_MASK) + FloatProperties::FRACTION_MASK) .get_val(); const MantissaType round_mask = MantissaType(1) << (shift - 1); @@ -130,14 +130,14 @@ template struct DyadicFloat { if (LIBC_UNLIKELY(exp_lo <= 0)) { // d_lo is denormal, but the output is normal. int scale_up_exponent = 2 * PRECISION; - T scale_up_factor = - FPBits::create_value( - sign, FloatProperties::EXPONENT_BIAS + scale_up_exponent, - output_bits_t(0)) - .get_val(); + T scale_up_factor = FPBits::create_value(sign, + FloatProperties::EXP_BIAS + + scale_up_exponent, + output_bits_t(0)) + .get_val(); T scale_down_factor = FPBits::create_value( - sign, FloatProperties::EXPONENT_BIAS - scale_up_exponent, + sign, FloatProperties::EXP_BIAS - scale_up_exponent, output_bits_t(0)) .get_val(); @@ -157,7 +157,7 @@ template struct DyadicFloat { if (LIBC_UNLIKELY(denorm)) { // Output is denormal, simply clear the exponent field. output_bits_t clear_exp = output_bits_t(exp_hi) - << FloatProperties::MANTISSA_WIDTH; + << FloatProperties::FRACTION_LEN; output_bits_t r_bits = FPBits(r).uintval() - clear_exp; return FPBits(r_bits).get_val(); } diff --git a/libc/src/__support/FPUtil/except_value_utils.h b/libc/src/__support/FPUtil/except_value_utils.h index 7560e59792e46eeea44ab9634fad0f334688431f..89849540315f64d626185ff2e520322ae83888c5 100644 --- a/libc/src/__support/FPUtil/except_value_utils.h +++ b/libc/src/__support/FPUtil/except_value_utils.h @@ -26,7 +26,7 @@ namespace fputil { // // Define list of exceptional inputs and outputs: // static constexpr int N = ...; // Number of exceptional values. -// static constexpr fputil::ExceptValues Excepts { +// static constexpr fputil::ExceptValues Excepts { // // }; // @@ -37,22 +37,22 @@ namespace fputil { template struct ExceptValues { static_assert(cpp::is_floating_point_v, "Must be a floating point type."); - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; struct Mapping { - UIntType input; - UIntType rnd_towardzero_result; - UIntType rnd_upward_offset; - UIntType rnd_downward_offset; - UIntType rnd_tonearest_offset; + StorageType input; + StorageType rnd_towardzero_result; + StorageType rnd_upward_offset; + StorageType rnd_downward_offset; + StorageType rnd_tonearest_offset; }; Mapping values[N]; - LIBC_INLINE constexpr cpp::optional lookup(UIntType x_bits) const { + LIBC_INLINE constexpr cpp::optional lookup(StorageType x_bits) const { for (size_t i = 0; i < N; ++i) { if (LIBC_UNLIKELY(x_bits == values[i].input)) { - UIntType out_bits = values[i].rnd_towardzero_result; + StorageType out_bits = values[i].rnd_towardzero_result; switch (fputil::quick_get_round()) { case FE_UPWARD: out_bits += values[i].rnd_upward_offset; @@ -70,11 +70,11 @@ template struct ExceptValues { return cpp::nullopt; } - LIBC_INLINE constexpr cpp::optional lookup_odd(UIntType x_abs, + LIBC_INLINE constexpr cpp::optional lookup_odd(StorageType x_abs, bool sign) const { for (size_t i = 0; i < N; ++i) { if (LIBC_UNLIKELY(x_abs == values[i].input)) { - UIntType out_bits = values[i].rnd_towardzero_result; + StorageType out_bits = values[i].rnd_towardzero_result; switch (fputil::quick_get_round()) { case FE_UPWARD: out_bits += sign ? values[i].rnd_downward_offset diff --git a/libc/src/__support/FPUtil/fpbits_str.h b/libc/src/__support/FPUtil/fpbits_str.h index 5d0bb6cf1ac4d96ce4202317e3b95dcbc1d0d3fd..bab3d5f97a6b35149aecfc4d6c43748589cb6587 100644 --- a/libc/src/__support/FPUtil/fpbits_str.h +++ b/libc/src/__support/FPUtil/fpbits_str.h @@ -35,7 +35,7 @@ using ZeroPaddedHexFmt = IntegerToString< // 3. The exponent is always 16 bits wide irrespective of the type of the // floating encoding. template LIBC_INLINE cpp::string str(fputil::FPBits x) { - using UIntType = typename fputil::FPBits::UIntType; + using StorageType = typename fputil::FPBits::StorageType; if (x.is_nan()) return "(NaN)"; @@ -46,7 +46,7 @@ template LIBC_INLINE cpp::string str(fputil::FPBits x) { cpp::string s; - const details::ZeroPaddedHexFmt bits(x.bits); + const details::ZeroPaddedHexFmt bits(x.bits); s += bits.view(); s += " = (S: "; @@ -56,14 +56,13 @@ template LIBC_INLINE cpp::string str(fputil::FPBits x) { const details::ZeroPaddedHexFmt exponent(x.get_biased_exponent()); s += exponent.view(); - if constexpr (cpp::is_same_v && - fputil::FloatProperties::MANTISSA_WIDTH == 63) { + if constexpr (fputil::get_fp_type() == fputil::FPType::X86_Binary80) { s += ", I: "; s += sign_char(x.get_implicit_bit()); } s += ", M: "; - const details::ZeroPaddedHexFmt mantissa(x.get_mantissa()); + const details::ZeroPaddedHexFmt mantissa(x.get_mantissa()); s += mantissa.view(); s += ')'; diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h index 61a1401c30e827c63882c7f3fdf0ceec2a593124..0180cd56ddef0899358f301f74ab2bfdf5e914ff 100644 --- a/libc/src/__support/FPUtil/generic/FMA.h +++ b/libc/src/__support/FPUtil/generic/FMA.h @@ -159,11 +159,10 @@ template <> LIBC_INLINE double fma(double x, double y, double z) { UInt128 prod_mant = x_mant * y_mant << 10; int prod_lsb_exp = - x_exp + y_exp - - (FPBits::EXPONENT_BIAS + 2 * MantissaWidth::VALUE + 10); + x_exp + y_exp - (FPBits::EXP_BIAS + 2 * FPBits::FRACTION_LEN + 10); z_mant <<= 64; - int z_lsb_exp = z_exp - (MantissaWidth::VALUE + 64); + int z_lsb_exp = z_exp - (FPBits::FRACTION_LEN + 64); bool round_bit = false; bool sticky_bits = false; bool z_shifted = false; @@ -269,8 +268,8 @@ template <> LIBC_INLINE double fma(double x, double y, double z) { } // Remove hidden bit and append the exponent field and sign bit. - result = (result & FloatProp::MANTISSA_MASK) | - (static_cast(r_exp) << FloatProp::MANTISSA_WIDTH); + result = (result & FloatProp::FRACTION_MASK) | + (static_cast(r_exp) << FloatProp::FRACTION_LEN); if (prod_sign) { result |= FloatProp::SIGN_MASK; } diff --git a/libc/src/__support/FPUtil/generic/FMod.h b/libc/src/__support/FPUtil/generic/FMod.h index 7502660c88a133da54b71fc870c62318c6f36374..d12be7bb14d07a0530b81c45759f331ad2558599 100644 --- a/libc/src/__support/FPUtil/generic/FMod.h +++ b/libc/src/__support/FPUtil/generic/FMod.h @@ -167,11 +167,13 @@ template struct FModFastMathWrapper { template class FModDivisionSimpleHelper { private: - using intU_t = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; public: - LIBC_INLINE constexpr static intU_t - execute(int exp_diff, int sides_zeroes_count, intU_t m_x, intU_t m_y) { + LIBC_INLINE constexpr static StorageType execute(int exp_diff, + int sides_zeroes_count, + StorageType m_x, + StorageType m_y) { while (exp_diff > sides_zeroes_count) { exp_diff -= sides_zeroes_count; m_x <<= sides_zeroes_count; @@ -186,23 +188,25 @@ public: template class FModDivisionInvMultHelper { private: using FPB = FPBits; - using intU_t = typename FPB::UIntType; + using StorageType = typename FPB::StorageType; public: - LIBC_INLINE constexpr static intU_t - execute(int exp_diff, int sides_zeroes_count, intU_t m_x, intU_t m_y) { + LIBC_INLINE constexpr static StorageType execute(int exp_diff, + int sides_zeroes_count, + StorageType m_x, + StorageType m_y) { if (exp_diff > sides_zeroes_count) { - intU_t inv_hy = (cpp::numeric_limits::max() / m_y); + StorageType inv_hy = (cpp::numeric_limits::max() / m_y); while (exp_diff > sides_zeroes_count) { exp_diff -= sides_zeroes_count; - intU_t hd = - (m_x * inv_hy) >> (FPB::FloatProp::BIT_WIDTH - sides_zeroes_count); + StorageType hd = + (m_x * inv_hy) >> (FPB::TOTAL_LEN - sides_zeroes_count); m_x <<= sides_zeroes_count; m_x -= hd * m_y; while (LIBC_UNLIKELY(m_x > m_y)) m_x -= m_y; } - intU_t hd = (m_x * inv_hy) >> (FPB::FloatProp::BIT_WIDTH - exp_diff); + StorageType hd = (m_x * inv_hy) >> (FPB::TOTAL_LEN - exp_diff); m_x <<= exp_diff; m_x -= hd * m_y; while (LIBC_UNLIKELY(m_x > m_y)) @@ -223,7 +227,7 @@ class FMod { private: using FPB = FPBits; - using intU_t = typename FPB::UIntType; + using StorageType = typename FPB::StorageType; LIBC_INLINE static constexpr FPB eval_internal(FPB sx, FPB sy) { @@ -236,12 +240,12 @@ private: int e_x = sx.get_biased_exponent(); int e_y = sy.get_biased_exponent(); - // Most common case where |y| is "very normal" and |x/y| < 2^EXPONENT_WIDTH - if (LIBC_LIKELY(e_y > int(FPB::FloatProp::MANTISSA_WIDTH) && - e_x - e_y <= int(FPB::FloatProp::EXPONENT_WIDTH))) { - intU_t m_x = sx.get_explicit_mantissa(); - intU_t m_y = sy.get_explicit_mantissa(); - intU_t d = (e_x == e_y) ? (m_x - m_y) : (m_x << (e_x - e_y)) % m_y; + // Most common case where |y| is "very normal" and |x/y| < 2^EXP_LEN + if (LIBC_LIKELY(e_y > int(FPB::FRACTION_LEN) && + e_x - e_y <= int(FPB::EXP_LEN))) { + StorageType m_x = sx.get_explicit_mantissa(); + StorageType m_y = sy.get_explicit_mantissa(); + StorageType d = (e_x == e_y) ? (m_x - m_y) : (m_x << (e_x - e_y)) % m_y; if (d == 0) return FPB(FPB::zero()); // iy - 1 because of "zero power" for number with power 1 @@ -255,11 +259,11 @@ private: } // Note that hx is not subnormal by conditions above. - intU_t m_x = sx.get_explicit_mantissa(); + StorageType m_x = sx.get_explicit_mantissa(); e_x--; - intU_t m_y = sy.get_explicit_mantissa(); - int lead_zeros_m_y = FPB::FloatProp::EXPONENT_WIDTH; + StorageType m_y = sy.get_explicit_mantissa(); + int lead_zeros_m_y = FPB::EXP_LEN; if (LIBC_LIKELY(e_y > 0)) { e_y--; } else { @@ -282,9 +286,7 @@ private: { // Shift hx left until the end or n = 0 - int left_shift = exp_diff < int(FPB::FloatProp::EXPONENT_WIDTH) - ? exp_diff - : FPB::FloatProp::EXPONENT_WIDTH; + int left_shift = exp_diff < int(FPB::EXP_LEN) ? exp_diff : FPB::EXP_LEN; m_x <<= left_shift; exp_diff -= left_shift; } diff --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h index 5bde9589fdc012c5686656f21d3d7c515f2b5a5a..7d56462a16856410e9f066b19534d086e0dbf9df 100644 --- a/libc/src/__support/FPUtil/generic/sqrt.h +++ b/libc/src/__support/FPUtil/generic/sqrt.h @@ -35,9 +35,9 @@ template <> struct SpecialLongDouble { template LIBC_INLINE void normalize(int &exponent, - typename FPBits::UIntType &mantissa) { + typename FPBits::StorageType &mantissa) { const int shift = cpp::countl_zero(mantissa) - - (8 * sizeof(mantissa) - 1 - MantissaWidth::VALUE); + (8 * sizeof(mantissa) - 1 - FPBits::FRACTION_LEN); exponent -= shift; mantissa <<= shift; } @@ -71,8 +71,8 @@ LIBC_INLINE cpp::enable_if_t, T> sqrt(T x) { return x86::sqrt(x); } else { // IEEE floating points formats. - using UIntType = typename FPBits::UIntType; - constexpr UIntType ONE = UIntType(1) << MantissaWidth::VALUE; + using StorageType = typename FPBits::StorageType; + constexpr StorageType ONE = StorageType(1) << FPBits::FRACTION_LEN; FPBits bits(x); @@ -94,7 +94,7 @@ LIBC_INLINE cpp::enable_if_t, T> sqrt(T x) { return FPBits::build_quiet_nan(ONE >> 1); } else { int x_exp = bits.get_exponent(); - UIntType x_mant = bits.get_mantissa(); + StorageType x_mant = bits.get_mantissa(); // Step 1a: Normalize denormal input and append hidden bit to the mantissa if (bits.get_biased_exponent() == 0) { @@ -122,12 +122,12 @@ LIBC_INLINE cpp::enable_if_t, T> sqrt(T x) { // So the nth digit y_n of the mantissa of sqrt(x) can be found by: // y_n = 1 if 2*r(n-1) >= 2*y(n - 1) + 2^(-n-1) // 0 otherwise. - UIntType y = ONE; - UIntType r = x_mant - ONE; + StorageType y = ONE; + StorageType r = x_mant - ONE; - for (UIntType current_bit = ONE >> 1; current_bit; current_bit >>= 1) { + for (StorageType current_bit = ONE >> 1; current_bit; current_bit >>= 1) { r <<= 1; - UIntType tmp = (y << 1) + current_bit; // 2*y(n - 1) + 2^(-n-1) + StorageType tmp = (y << 1) + current_bit; // 2*y(n - 1) + 2^(-n-1) if (r >= tmp) { r -= tmp; y += current_bit; @@ -138,16 +138,17 @@ LIBC_INLINE cpp::enable_if_t, T> sqrt(T x) { bool lsb = static_cast(y & 1); // Least significant bit bool rb = false; // Round bit r <<= 2; - UIntType tmp = (y << 2) + 1; + StorageType tmp = (y << 2) + 1; if (r >= tmp) { r -= tmp; rb = true; } // Remove hidden bit and append the exponent field. - x_exp = ((x_exp >> 1) + FPBits::EXPONENT_BIAS); + x_exp = ((x_exp >> 1) + FPBits::EXP_BIAS); - y = (y - ONE) | (static_cast(x_exp) << MantissaWidth::VALUE); + y = (y - ONE) | + (static_cast(x_exp) << FPBits::FRACTION_LEN); switch (quick_get_round()) { case FE_TONEAREST: diff --git a/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h b/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h index 2f25be54e0bc3626085687fac6b3ae50e1942eb5..257c02e17d0045cc24e900462dd6ad113a99e059 100644 --- a/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h +++ b/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h @@ -23,7 +23,7 @@ namespace x86 { LIBC_INLINE void normalize(int &exponent, UInt128 &mantissa) { const unsigned int shift = static_cast( cpp::countl_zero(static_cast(mantissa)) - - (8 * sizeof(uint64_t) - 1 - MantissaWidth::VALUE)); + (8 * sizeof(uint64_t) - 1 - FPBits::FRACTION_LEN)); exponent -= shift; mantissa <<= shift; } @@ -36,16 +36,16 @@ LIBC_INLINE long double sqrt(long double x); // Shift-and-add algorithm. #if defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80) LIBC_INLINE long double sqrt(long double x) { - using UIntType = typename FPBits::UIntType; - constexpr UIntType ONE = UIntType(1) - << int(MantissaWidth::VALUE); + using LDBits = FPBits; + using StorageType = typename LDBits::StorageType; + constexpr StorageType ONE = StorageType(1) << int(LDBits::FRACTION_LEN); FPBits bits(x); if (bits.is_inf_or_nan()) { if (bits.get_sign() && (bits.get_mantissa() == 0)) { // sqrt(-Inf) = NaN - return FPBits::build_quiet_nan(ONE >> 1); + return LDBits::build_quiet_nan(ONE >> 1); } else { // sqrt(NaN) = NaN // sqrt(+Inf) = +Inf @@ -57,10 +57,10 @@ LIBC_INLINE long double sqrt(long double x) { return x; } else if (bits.get_sign()) { // sqrt( negative numbers ) = NaN - return FPBits::build_quiet_nan(ONE >> 1); + return LDBits::build_quiet_nan(ONE >> 1); } else { int x_exp = bits.get_explicit_exponent(); - UIntType x_mant = bits.get_mantissa(); + StorageType x_mant = bits.get_mantissa(); // Step 1a: Normalize denormal input if (bits.get_implicit_bit()) { @@ -87,12 +87,12 @@ LIBC_INLINE long double sqrt(long double x) { // So the nth digit y_n of the mantissa of sqrt(x) can be found by: // y_n = 1 if 2*r(n-1) >= 2*y(n - 1) + 2^(-n-1) // 0 otherwise. - UIntType y = ONE; - UIntType r = x_mant - ONE; + StorageType y = ONE; + StorageType r = x_mant - ONE; - for (UIntType current_bit = ONE >> 1; current_bit; current_bit >>= 1) { + for (StorageType current_bit = ONE >> 1; current_bit; current_bit >>= 1) { r <<= 1; - UIntType tmp = (y << 1) + current_bit; // 2*y(n - 1) + 2^(-n-1) + StorageType tmp = (y << 1) + current_bit; // 2*y(n - 1) + 2^(-n-1) if (r >= tmp) { r -= tmp; y += current_bit; @@ -103,16 +103,15 @@ LIBC_INLINE long double sqrt(long double x) { bool lsb = static_cast(y & 1); // Least significant bit bool rb = false; // Round bit r <<= 2; - UIntType tmp = (y << 2) + 1; + StorageType tmp = (y << 2) + 1; if (r >= tmp) { r -= tmp; rb = true; } // Append the exponent field. - x_exp = ((x_exp >> 1) + FPBits::EXPONENT_BIAS); - y |= (static_cast(x_exp) - << (MantissaWidth::VALUE + 1)); + x_exp = ((x_exp >> 1) + LDBits::EXP_BIAS); + y |= (static_cast(x_exp) << (LDBits::FRACTION_LEN + 1)); switch (quick_get_round()) { case FE_TONEAREST: diff --git a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h index f1ef928f2308194321eb5913e8e0eba32aeccb72..89c47063ebac4d6cd5615b84624422ad775f336d 100644 --- a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h +++ b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h @@ -26,74 +26,74 @@ namespace LIBC_NAMESPACE { namespace fputil { -template <> struct FPBits { - using UIntType = UInt128; +template <> struct FPBits : private FloatProperties { + using typename FloatProperties::StorageType; + using FloatProperties::TOTAL_LEN; + using FloatProperties::EXP_MANT_MASK; + using FloatProperties::EXP_MASK; + using FloatProperties::EXP_BIAS; + using FloatProperties::EXP_LEN; + using FloatProperties::FRACTION_MASK; + using FloatProperties::FRACTION_LEN; + using FloatProperties::QUIET_NAN_MASK; + using FloatProperties::SIGN_MASK; - static constexpr int EXPONENT_BIAS = 0x3FFF; static constexpr int MAX_EXPONENT = 0x7FFF; - static constexpr UIntType MIN_SUBNORMAL = UIntType(1); + static constexpr StorageType MIN_SUBNORMAL = StorageType(1); // Subnormal numbers include the implicit bit in x86 long double formats. - static constexpr UIntType MAX_SUBNORMAL = - (UIntType(1) << (MantissaWidth::VALUE)) - 1; - static constexpr UIntType MIN_NORMAL = - (UIntType(3) << MantissaWidth::VALUE); - static constexpr UIntType MAX_NORMAL = - (UIntType(MAX_EXPONENT - 1) << (MantissaWidth::VALUE + 1)) | - (UIntType(1) << MantissaWidth::VALUE) | MAX_SUBNORMAL; - - using FloatProp = FloatProperties; - - UIntType bits; - - LIBC_INLINE constexpr void set_mantissa(UIntType mantVal) { - mantVal &= (FloatProp::MANTISSA_MASK); - bits &= ~(FloatProp::MANTISSA_MASK); + static constexpr StorageType MAX_SUBNORMAL = + (StorageType(1) << FRACTION_LEN) - 1; + static constexpr StorageType MIN_NORMAL = (StorageType(3) << FRACTION_LEN); + static constexpr StorageType MAX_NORMAL = + (StorageType(MAX_EXPONENT - 1) << (FRACTION_LEN + 1)) | + (StorageType(1) << FRACTION_LEN) | MAX_SUBNORMAL; + + StorageType bits; + + LIBC_INLINE constexpr void set_mantissa(StorageType mantVal) { + mantVal &= FRACTION_MASK; + bits &= ~FRACTION_MASK; bits |= mantVal; } - LIBC_INLINE constexpr UIntType get_mantissa() const { - return bits & FloatProp::MANTISSA_MASK; + LIBC_INLINE constexpr StorageType get_mantissa() const { + return bits & FRACTION_MASK; } - LIBC_INLINE constexpr UIntType get_explicit_mantissa() const { + LIBC_INLINE constexpr StorageType get_explicit_mantissa() const { // The x86 80 bit float represents the leading digit of the mantissa // explicitly. This is the mask for that bit. - constexpr UIntType EXPLICIT_BIT_MASK = - (UIntType(1) << FloatProp::MANTISSA_WIDTH); - return bits & (FloatProp::MANTISSA_MASK | EXPLICIT_BIT_MASK); + constexpr StorageType EXPLICIT_BIT_MASK = StorageType(1) << FRACTION_LEN; + return bits & (FRACTION_MASK | EXPLICIT_BIT_MASK); } - LIBC_INLINE constexpr void set_biased_exponent(UIntType expVal) { - expVal = - (expVal << (FloatProp::BIT_WIDTH - 1 - FloatProp::EXPONENT_WIDTH)) & - FloatProp::EXPONENT_MASK; - bits &= ~(FloatProp::EXPONENT_MASK); + LIBC_INLINE constexpr void set_biased_exponent(StorageType expVal) { + expVal = (expVal << (TOTAL_LEN - 1 - EXP_LEN)) & EXP_MASK; + bits &= ~EXP_MASK; bits |= expVal; } LIBC_INLINE constexpr uint16_t get_biased_exponent() const { - return uint16_t((bits & FloatProp::EXPONENT_MASK) >> - (FloatProp::BIT_WIDTH - 1 - FloatProp::EXPONENT_WIDTH)); + return uint16_t((bits & EXP_MASK) >> (TOTAL_LEN - 1 - EXP_LEN)); } LIBC_INLINE constexpr void set_implicit_bit(bool implicitVal) { - bits &= ~(UIntType(1) << FloatProp::MANTISSA_WIDTH); - bits |= (UIntType(implicitVal) << FloatProp::MANTISSA_WIDTH); + bits &= ~(StorageType(1) << FRACTION_LEN); + bits |= (StorageType(implicitVal) << FRACTION_LEN); } LIBC_INLINE constexpr bool get_implicit_bit() const { - return bool((bits & (UIntType(1) << FloatProp::MANTISSA_WIDTH)) >> - FloatProp::MANTISSA_WIDTH); + return bool((bits & (StorageType(1) << FRACTION_LEN)) >> FRACTION_LEN); } LIBC_INLINE constexpr void set_sign(bool signVal) { - bits &= ~(FloatProp::SIGN_MASK); - UIntType sign1 = UIntType(signVal) << (FloatProp::BIT_WIDTH - 1); + bits &= ~SIGN_MASK; + StorageType sign1 = StorageType(signVal) << (TOTAL_LEN - 1); bits |= sign1; } LIBC_INLINE constexpr bool get_sign() const { - return bool((bits & FloatProp::SIGN_MASK) >> (FloatProp::BIT_WIDTH - 1)); + return bool((bits & SIGN_MASK) >> (TOTAL_LEN - 1)); } LIBC_INLINE constexpr FPBits() : bits(0) {} @@ -101,23 +101,23 @@ template <> struct FPBits { template , int> = 0> LIBC_INLINE constexpr explicit FPBits(XType x) - : bits(cpp::bit_cast(x)) { + : bits(cpp::bit_cast(x)) { // bits starts uninitialized, and setting it to a long double only // overwrites the first 80 bits. This clears those upper bits. - bits = bits & ((UIntType(1) << 80) - 1); + bits = bits & ((StorageType(1) << 80) - 1); } template , int> = 0> + cpp::enable_if_t, int> = 0> LIBC_INLINE constexpr explicit FPBits(XType x) : bits(x) {} LIBC_INLINE constexpr operator long double() { return cpp::bit_cast(bits); } - LIBC_INLINE constexpr UIntType uintval() { + LIBC_INLINE constexpr StorageType uintval() { // We zero the padding bits as they can contain garbage. - return bits & FloatProp::FP_MASK; + return bits & FP_MASK; } LIBC_INLINE constexpr long double get_val() const { @@ -125,7 +125,7 @@ template <> struct FPBits { } LIBC_INLINE constexpr int get_exponent() const { - return int(get_biased_exponent()) - EXPONENT_BIAS; + return int(get_biased_exponent()) - EXP_BIAS; } // If the number is subnormal, the exponent is treated as if it were the @@ -139,9 +139,9 @@ template <> struct FPBits { if (is_zero()) { return 0; } else if (biased_exp == 0) { - return 1 - EXPONENT_BIAS; + return 1 - EXP_BIAS; } else { - return biased_exp - EXPONENT_BIAS; + return biased_exp - EXP_BIAS; } } @@ -187,7 +187,7 @@ template <> struct FPBits { LIBC_INLINE static constexpr long double neg_inf() { return inf(true); } - LIBC_INLINE static constexpr long double build_nan(UIntType v) { + LIBC_INLINE static constexpr long double build_nan(StorageType v) { FPBits bits(0.0l); bits.set_biased_exponent(MAX_EXPONENT); bits.set_implicit_bit(1); @@ -195,8 +195,8 @@ template <> struct FPBits { return bits; } - LIBC_INLINE static constexpr long double build_quiet_nan(UIntType v) { - return build_nan(FloatProp::QUIET_NAN_MASK | v); + LIBC_INLINE static constexpr long double build_quiet_nan(StorageType v) { + return build_nan(QUIET_NAN_MASK | v); } LIBC_INLINE static constexpr long double min_normal() { @@ -216,7 +216,7 @@ template <> struct FPBits { } LIBC_INLINE static constexpr FPBits - create_value(bool sign, UIntType biased_exp, UIntType mantissa) { + create_value(bool sign, StorageType biased_exp, StorageType mantissa) { FPBits result; result.set_sign(sign); result.set_biased_exponent(biased_exp); diff --git a/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h b/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h index 5e32f766ad58636f3efa75119462de8380e06458..b461da3a4c0abc6f786f87be6e33fd2d1683a928 100644 --- a/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h +++ b/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h @@ -43,18 +43,17 @@ LIBC_INLINE long double nextafter(long double from, long double to) { from_bits.set_biased_exponent(1); } - using UIntType = FPBits::UIntType; - constexpr UIntType SIGN_VAL = (UIntType(1) << 79); - constexpr UIntType MANTISSA_MASK = - (UIntType(1) << MantissaWidth::VALUE) - 1; - UIntType int_val = from_bits.uintval(); + using StorageType = FPBits::StorageType; + constexpr StorageType SIGN_VAL = (StorageType(1) << 79); + constexpr StorageType FRACTION_MASK = FPBits::FRACTION_MASK; + StorageType int_val = from_bits.uintval(); if (from < 0.0l) { if (from > to) { if (int_val == (SIGN_VAL + FPBits::MAX_SUBNORMAL)) { // We deal with normal/subnormal boundary separately to avoid // dealing with the implicit bit. int_val = SIGN_VAL + FPBits::MIN_NORMAL; - } else if ((int_val & MANTISSA_MASK) == MANTISSA_MASK) { + } else if ((int_val & FRACTION_MASK) == FRACTION_MASK) { from_bits.set_mantissa(0); // Incrementing exponent might overflow the value to infinity, // which is what is expected. Since NaNs are handling separately, @@ -71,8 +70,8 @@ LIBC_INLINE long double nextafter(long double from, long double to) { // We deal with normal/subnormal boundary separately to avoid // dealing with the implicit bit. int_val = SIGN_VAL + FPBits::MAX_SUBNORMAL; - } else if ((int_val & MANTISSA_MASK) == 0) { - from_bits.set_mantissa(MANTISSA_MASK); + } else if ((int_val & FRACTION_MASK) == 0) { + from_bits.set_mantissa(FRACTION_MASK); // from == 0 is handled separately so decrementing the exponent will not // lead to underflow. from_bits.set_biased_exponent(from_bits.get_biased_exponent() - 1); @@ -90,8 +89,8 @@ LIBC_INLINE long double nextafter(long double from, long double to) { if (from > to) { if (int_val == FPBits::MIN_NORMAL) { int_val = FPBits::MAX_SUBNORMAL; - } else if ((int_val & MANTISSA_MASK) == 0) { - from_bits.set_mantissa(MANTISSA_MASK); + } else if ((int_val & FRACTION_MASK) == 0) { + from_bits.set_mantissa(FRACTION_MASK); // from == 0 is handled separately so decrementing the exponent will not // lead to underflow. from_bits.set_biased_exponent(from_bits.get_biased_exponent() - 1); @@ -102,7 +101,7 @@ LIBC_INLINE long double nextafter(long double from, long double to) { } else { if (int_val == FPBits::MAX_SUBNORMAL) { int_val = FPBits::MIN_NORMAL; - } else if ((int_val & MANTISSA_MASK) == MANTISSA_MASK) { + } else if ((int_val & FRACTION_MASK) == FRACTION_MASK) { from_bits.set_mantissa(0); // Incrementing exponent might overflow the value to infinity, // which is what is expected. Since NaNs are handling separately, @@ -117,9 +116,8 @@ LIBC_INLINE long double nextafter(long double from, long double to) { } } - UIntType implicit_bit = - int_val & (UIntType(1) << MantissaWidth::VALUE); - if (implicit_bit == UIntType(0)) + StorageType implicit_bit = int_val & (StorageType(1) << FPBits::FRACTION_LEN); + if (implicit_bit == StorageType(0)) raise_except_if_required(FE_UNDERFLOW | FE_INEXACT); return cpp::bit_cast(int_val); diff --git a/libc/src/__support/File/linux/file.cpp b/libc/src/__support/File/linux/file.cpp index 2d4cea5b53c5815c8ff9a3f5a1387a27c8b17c2a..b84da64cbe6358957a86b93d33aa5a0044693f20 100644 --- a/libc/src/__support/File/linux/file.cpp +++ b/libc/src/__support/File/linux/file.cpp @@ -17,6 +17,7 @@ #include // For mode_t and other flags to the open syscall #include +#include // For S_IS*, S_IF*, and S_IR* flags. #include // For syscall numbers namespace LIBC_NAMESPACE { diff --git a/libc/src/__support/OSUtil/linux/quick_exit.h b/libc/src/__support/OSUtil/linux/quick_exit.h index c461d5f8b8fcb6c912dad3b8d8d9331bf5582aa5..432395584d8467797ef9e600939555ed9c4bdec2 100644 --- a/libc/src/__support/OSUtil/linux/quick_exit.h +++ b/libc/src/__support/OSUtil/linux/quick_exit.h @@ -9,7 +9,7 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_QUICK_EXIT_H #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_QUICK_EXIT_H -#include "syscall.h" // For internal syscall function. +#include "syscall.h" // For internal syscall function. #include "src/__support/common.h" @@ -17,7 +17,13 @@ namespace LIBC_NAMESPACE { -LIBC_INLINE void quick_exit(int status) { +// mark as no_stack_protector for x86 since TLS can be torn down before calling +// quick_exit so that the stack protector canary cannot be loaded. +#ifdef LIBC_TARGET_ARCH_IS_X86 +__attribute__((no_stack_protector)) +#endif +LIBC_INLINE void +quick_exit(int status) { for (;;) { LIBC_NAMESPACE::syscall_impl(SYS_exit_group, status); LIBC_NAMESPACE::syscall_impl(SYS_exit, status); diff --git a/libc/src/__support/float_to_string.h b/libc/src/__support/float_to_string.h index be105830a91ac1c25e7b9ed47ed34846c98345b5..923633e3d207f5dca1fd5559b9f11723aec3f08b 100644 --- a/libc/src/__support/float_to_string.h +++ b/libc/src/__support/float_to_string.h @@ -382,10 +382,10 @@ LIBC_INLINE uint32_t fast_uint_mod_1e9(const cpp::UInt &val) { (1000000000 * shifted)); } -LIBC_INLINE uint32_t mul_shift_mod_1e9(const FloatProp::UIntType mantissa, +LIBC_INLINE uint32_t mul_shift_mod_1e9(const FloatProp::StorageType mantissa, const cpp::UInt &large, const int32_t shift_amount) { - cpp::UInt val(large); + cpp::UInt val(large); val = (val * mantissa) >> shift_amount; return static_cast( val.div_uint32_times_pow_2(1000000000, 0).value()); @@ -414,10 +414,10 @@ class FloatToString { fputil::FPBits float_bits; bool is_negative; int exponent; - FloatProp::UIntType mantissa; + FloatProp::StorageType mantissa; - static constexpr int MANT_WIDTH = fputil::MantissaWidth::VALUE; - static constexpr int EXP_BIAS = fputil::FPBits::EXPONENT_BIAS; + static constexpr int FRACTION_LEN = fputil::FPBits::FRACTION_LEN; + static constexpr int EXP_BIAS = fputil::FPBits::EXP_BIAS; public: LIBC_INLINE constexpr FloatToString(T init_float) : float_bits(init_float) { @@ -426,7 +426,7 @@ public: mantissa = float_bits.get_explicit_mantissa(); // Adjust for the width of the mantissa. - exponent -= MANT_WIDTH; + exponent -= FRACTION_LEN; // init_convert(); } @@ -440,7 +440,7 @@ public: // get_block returns an integer that represents the digits in the requested // block. LIBC_INLINE constexpr BlockInt get_positive_block(int block_index) { - if (exponent >= -MANT_WIDTH) { + if (exponent >= -FRACTION_LEN) { // idx is ceil(exponent/16) or 0 if exponent is negative. This is used to // find the coarse section of the POW10_SPLIT table that will be used to // calculate the 9 digit window, as well as some other related values. @@ -567,12 +567,13 @@ public: } LIBC_INLINE constexpr size_t get_positive_blocks() { - if (exponent >= -MANT_WIDTH) { + if (exponent >= -FRACTION_LEN) { const uint32_t idx = exponent < 0 ? 0 : static_cast(exponent + (IDX_SIZE - 1)) / IDX_SIZE; - const uint32_t len = internal::length_for_num(idx * IDX_SIZE, MANT_WIDTH); + const uint32_t len = + internal::length_for_num(idx * IDX_SIZE, FRACTION_LEN); return len; } else { return 0; @@ -608,12 +609,12 @@ public: template <> LIBC_INLINE constexpr size_t FloatToString::get_positive_blocks() { - if (exponent >= -MANT_WIDTH) { + if (exponent >= -FRACTION_LEN) { const uint32_t idx = exponent < 0 ? 0 : static_cast(exponent + (IDX_SIZE - 1)) / IDX_SIZE; - const uint32_t len = internal::length_for_num(idx * IDX_SIZE, MANT_WIDTH); + const uint32_t len = internal::length_for_num(idx * IDX_SIZE, FRACTION_LEN); return len; } else { return 0; @@ -639,7 +640,7 @@ LIBC_INLINE constexpr bool FloatToString::is_lowest_block(size_t) { template <> LIBC_INLINE constexpr BlockInt FloatToString::get_positive_block(int block_index) { - if (exponent >= -MANT_WIDTH) { + if (exponent >= -FRACTION_LEN) { // idx is ceil(exponent/16) or 0 if exponent is negative. This is used to // find the coarse section of the POW10_SPLIT table that will be used to diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h index 2a6f15c018f1ecbd0707d46957fa8ab3df407e99..9984bcd7064d750e17249a945c0aac0bbc24dc20 100644 --- a/libc/src/__support/str_to_float.h +++ b/libc/src/__support/str_to_float.h @@ -29,7 +29,7 @@ namespace LIBC_NAMESPACE { namespace internal { template struct ExpandedFloat { - typename fputil::FPBits::UIntType mantissa; + typename fputil::FPBits::StorageType mantissa; int32_t exponent; }; @@ -71,10 +71,10 @@ LIBC_INLINE cpp::optional> eisel_lemire(ExpandedFloat init_num, RoundDirection round = RoundDirection::Nearest) { using FPBits = typename fputil::FPBits; - using FloatProp = typename FPBits::FloatProp; - using UIntType = typename FPBits::UIntType; + using FloatProp = typename fputil::FloatProperties; + using StorageType = typename FPBits::StorageType; - UIntType mantissa = init_num.mantissa; + StorageType mantissa = init_num.mantissa; int32_t exp10 = init_num.exponent; if (sizeof(T) > 8) { // This algorithm cannot handle anything longer than a @@ -89,11 +89,11 @@ eisel_lemire(ExpandedFloat init_num, } // Normalization - uint32_t clz = cpp::countl_zero(mantissa); + uint32_t clz = cpp::countl_zero(mantissa); mantissa <<= clz; - int32_t exp2 = exp10_to_exp2(exp10) + FloatProp::UINTTYPE_BITS + - FloatProp::EXPONENT_BIAS - clz; + int32_t exp2 = + exp10_to_exp2(exp10) + FloatProp::STORAGE_LEN + FloatProp::EXP_BIAS - clz; // Multiplication const uint64_t *power_of_ten = @@ -110,8 +110,8 @@ eisel_lemire(ExpandedFloat init_num, // accuracy, and the most significant bit is ignored.) = 9 bits. Similarly, // it's 6 bits for floats in this case. const uint64_t halfway_constant = - (uint64_t(1) << (FloatProp::UINTTYPE_BITS - - (FloatProp::MANTISSA_WIDTH + 3))) - + (uint64_t(1) << (FloatProp::STORAGE_LEN - + (FloatProp::FRACTION_LEN + 3))) - 1; if ((high64(first_approx) & halfway_constant) == halfway_constant && low64(first_approx) + mantissa < mantissa) { @@ -131,11 +131,11 @@ eisel_lemire(ExpandedFloat init_num, } // Shifting to 54 bits for doubles and 25 bits for floats - UIntType msb = static_cast(high64(final_approx) >> - (FloatProp::UINTTYPE_BITS - 1)); - UIntType final_mantissa = static_cast( + StorageType msb = static_cast(high64(final_approx) >> + (FloatProp::STORAGE_LEN - 1)); + StorageType final_mantissa = static_cast( high64(final_approx) >> - (msb + FloatProp::UINTTYPE_BITS - (FloatProp::MANTISSA_WIDTH + 3))); + (msb + FloatProp::STORAGE_LEN - (FloatProp::FRACTION_LEN + 3))); exp2 -= static_cast(1 ^ msb); // same as !msb if (round == RoundDirection::Nearest) { @@ -161,14 +161,14 @@ eisel_lemire(ExpandedFloat init_num, // From 54 to 53 bits for doubles and 25 to 24 bits for floats final_mantissa >>= 1; - if ((final_mantissa >> (FloatProp::MANTISSA_WIDTH + 1)) > 0) { + if ((final_mantissa >> (FloatProp::FRACTION_LEN + 1)) > 0) { final_mantissa >>= 1; ++exp2; } // The if block is equivalent to (but has fewer branches than): // if exp2 <= 0 || exp2 >= 0x7FF { etc } - if (static_cast(exp2) - 1 >= (1 << FloatProp::EXPONENT_WIDTH) - 2) { + if (static_cast(exp2) - 1 >= (1 << FloatProp::EXP_LEN) - 2) { return cpp::nullopt; } @@ -184,10 +184,10 @@ LIBC_INLINE cpp::optional> eisel_lemire(ExpandedFloat init_num, RoundDirection round) { using FPBits = typename fputil::FPBits; - using FloatProp = typename FPBits::FloatProp; - using UIntType = typename FPBits::UIntType; + using FloatProp = typename fputil::FloatProperties; + using StorageType = typename FPBits::StorageType; - UIntType mantissa = init_num.mantissa; + StorageType mantissa = init_num.mantissa; int32_t exp10 = init_num.exponent; // Exp10 Range @@ -206,11 +206,11 @@ eisel_lemire(ExpandedFloat init_num, } // Normalization - uint32_t clz = cpp::countl_zero(mantissa); + uint32_t clz = cpp::countl_zero(mantissa); mantissa <<= clz; - int32_t exp2 = exp10_to_exp2(exp10) + FloatProp::UINTTYPE_BITS + - FloatProp::EXPONENT_BIAS - clz; + int32_t exp2 = + exp10_to_exp2(exp10) + FloatProp::STORAGE_LEN + FloatProp::EXP_BIAS - clz; // Multiplication const uint64_t *power_of_ten = @@ -247,8 +247,7 @@ eisel_lemire(ExpandedFloat init_num, // accuracy, and the most significant bit is ignored.) = 61 bits. Similarly, // it's 12 bits for 128 bit floats in this case. constexpr UInt128 HALFWAY_CONSTANT = - (UInt128(1) << (FloatProp::UINTTYPE_BITS - - (FloatProp::MANTISSA_WIDTH + 3))) - + (UInt128(1) << (FloatProp::STORAGE_LEN - (FloatProp::FRACTION_LEN + 3))) - 1; if ((final_approx_upper & HALFWAY_CONSTANT) == HALFWAY_CONSTANT && @@ -257,11 +256,11 @@ eisel_lemire(ExpandedFloat init_num, } // Shifting to 65 bits for 80 bit floats and 113 bits for 128 bit floats - uint32_t msb = static_cast(final_approx_upper >> - (FloatProp::UINTTYPE_BITS - 1)); - UIntType final_mantissa = + uint32_t msb = + static_cast(final_approx_upper >> (FloatProp::STORAGE_LEN - 1)); + StorageType final_mantissa = final_approx_upper >> - (msb + FloatProp::UINTTYPE_BITS - (FloatProp::MANTISSA_WIDTH + 3)); + (msb + FloatProp::STORAGE_LEN - (FloatProp::FRACTION_LEN + 3)); exp2 -= static_cast(1 ^ msb); // same as !msb if (round == RoundDirection::Nearest) { @@ -286,14 +285,14 @@ eisel_lemire(ExpandedFloat init_num, // From 65 to 64 bits for 80 bit floats and 113 to 112 bits for 128 bit // floats final_mantissa >>= 1; - if ((final_mantissa >> (FloatProp::MANTISSA_WIDTH + 1)) > 0) { + if ((final_mantissa >> (FloatProp::FRACTION_LEN + 1)) > 0) { final_mantissa >>= 1; ++exp2; } // The if block is equivalent to (but has fewer branches than): // if exp2 <= 0 || exp2 >= MANTISSA_MAX { etc } - if (exp2 - 1 >= (1 << FloatProp::EXPONENT_WIDTH) - 2) { + if (exp2 - 1 >= (1 << FloatProp::EXP_LEN) - 2) { return cpp::nullopt; } @@ -322,8 +321,8 @@ LIBC_INLINE FloatConvertReturn simple_decimal_conversion(const char *__restrict numStart, RoundDirection round = RoundDirection::Nearest) { using FPBits = typename fputil::FPBits; - using FloatProp = typename FPBits::FloatProp; - using UIntType = typename FPBits::UIntType; + using FloatProp = typename fputil::FloatProperties; + using StorageType = typename FPBits::StorageType; int32_t exp2 = 0; HighPrecisionDecimal hpd = HighPrecisionDecimal(numStart); @@ -338,7 +337,7 @@ simple_decimal_conversion(const char *__restrict numStart, // If the exponent is too large and can't be represented in this size of // float, return inf. if (hpd.get_decimal_point() > 0 && - exp10_to_exp2(hpd.get_decimal_point() - 1) > FloatProp::EXPONENT_BIAS) { + exp10_to_exp2(hpd.get_decimal_point() - 1) > FloatProp::EXP_BIAS) { output.num = {0, fputil::FPBits::MAX_EXPONENT}; output.error = ERANGE; return output; @@ -346,8 +345,8 @@ simple_decimal_conversion(const char *__restrict numStart, // If the exponent is too small even for a subnormal, return 0. if (hpd.get_decimal_point() < 0 && exp10_to_exp2(-hpd.get_decimal_point()) > - (FloatProp::EXPONENT_BIAS + - static_cast(FloatProp::MANTISSA_WIDTH))) { + (FloatProp::EXP_BIAS + + static_cast(FloatProp::FRACTION_LEN))) { output.num = {0, 0}; output.error = ERANGE; return output; @@ -386,7 +385,7 @@ simple_decimal_conversion(const char *__restrict numStart, hpd.shift(1); // Get the biased exponent - exp2 += FloatProp::EXPONENT_BIAS; + exp2 += FloatProp::EXP_BIAS; // Handle the exponent being too large (and return inf). if (exp2 >= FPBits::MAX_EXPONENT) { @@ -396,8 +395,8 @@ simple_decimal_conversion(const char *__restrict numStart, } // Shift left to fill the mantissa - hpd.shift(FloatProp::MANTISSA_WIDTH); - UIntType final_mantissa = hpd.round_to_integer_type(); + hpd.shift(FloatProp::FRACTION_LEN); + StorageType final_mantissa = hpd.round_to_integer_type(); // Handle subnormals if (exp2 <= 0) { @@ -409,16 +408,16 @@ simple_decimal_conversion(const char *__restrict numStart, // Shift right one more time to compensate for the left shift to get it // between 1 and 2. hpd.shift(-1); - final_mantissa = hpd.round_to_integer_type(round); + final_mantissa = hpd.round_to_integer_type(round); // Check if by shifting right we've caused this to round to a normal number. - if ((final_mantissa >> FloatProp::MANTISSA_WIDTH) != 0) { + if ((final_mantissa >> FloatProp::FRACTION_LEN) != 0) { ++exp2; } } // Check if rounding added a bit, and shift down if that's the case. - if (final_mantissa == UIntType(2) << FloatProp::MANTISSA_WIDTH) { + if (final_mantissa == StorageType(2) << FloatProp::FRACTION_LEN) { final_mantissa >>= 1; ++exp2; @@ -516,19 +515,19 @@ LIBC_INLINE cpp::optional> clinger_fast_path(ExpandedFloat init_num, RoundDirection round = RoundDirection::Nearest) { using FPBits = typename fputil::FPBits; - using FloatProp = typename FPBits::FloatProp; - using UIntType = typename FPBits::UIntType; + using FloatProp = typename fputil::FloatProperties; + using StorageType = typename FPBits::StorageType; - UIntType mantissa = init_num.mantissa; + StorageType mantissa = init_num.mantissa; int32_t exp10 = init_num.exponent; - if ((mantissa >> FloatProp::MANTISSA_WIDTH) > 0) { + if ((mantissa >> FloatProp::FRACTION_LEN) > 0) { return cpp::nullopt; } FPBits result; T float_mantissa; - if constexpr (cpp::is_same_v>) { + if constexpr (cpp::is_same_v>) { float_mantissa = static_cast(fputil::DyadicFloat<128>( false, 0, fputil::DyadicFloat<128>::MantissaType( @@ -606,7 +605,7 @@ clinger_fast_path(ExpandedFloat init_num, // log10(2^(exponent bias)). // The generic approximation uses the fact that log10(2^x) ~= x/3 template constexpr int32_t get_upper_bound() { - return fputil::FloatProperties::EXPONENT_BIAS / 3; + return fputil::FloatProperties::EXP_BIAS / 3; } template <> constexpr int32_t get_upper_bound() { return 39; } @@ -623,10 +622,10 @@ template <> constexpr int32_t get_upper_bound() { return 309; } // end of the final mantissa. template constexpr int32_t get_lower_bound() { using FloatProp = typename fputil::FloatProperties; - return -((FloatProp::EXPONENT_BIAS + - static_cast(FloatProp::MANTISSA_WIDTH + - FloatProp::UINTTYPE_BITS)) / - 3); + return -( + (FloatProp::EXP_BIAS + + static_cast(FloatProp::FRACTION_LEN + FloatProp::STORAGE_LEN)) / + 3); } template <> constexpr int32_t get_lower_bound() { @@ -647,9 +646,9 @@ LIBC_INLINE FloatConvertReturn decimal_exp_to_float(ExpandedFloat init_num, const char *__restrict numStart, bool truncated, RoundDirection round) { using FPBits = typename fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; - UIntType mantissa = init_num.mantissa; + StorageType mantissa = init_num.mantissa; int32_t exp10 = init_num.exponent; FloatConvertReturn output; @@ -724,46 +723,47 @@ LIBC_INLINE FloatConvertReturn binary_exp_to_float(ExpandedFloat init_num, bool truncated, RoundDirection round) { using FPBits = typename fputil::FPBits; - using FloatProp = typename FPBits::FloatProp; - using UIntType = typename FPBits::UIntType; + using FloatProp = typename fputil::FloatProperties; + using StorageType = typename FPBits::StorageType; - UIntType mantissa = init_num.mantissa; + StorageType mantissa = init_num.mantissa; int32_t exp2 = init_num.exponent; FloatConvertReturn output; // This is the number of leading zeroes a properly normalized float of type T // should have. - constexpr int32_t INF_EXP = (1 << FloatProp::EXPONENT_WIDTH) - 1; + constexpr int32_t INF_EXP = (1 << FloatProp::EXP_LEN) - 1; - // Normalization step 1: Bring the leading bit to the highest bit of UIntType. - uint32_t amount_to_shift_left = cpp::countl_zero(mantissa); + // Normalization step 1: Bring the leading bit to the highest bit of + // StorageType. + uint32_t amount_to_shift_left = cpp::countl_zero(mantissa); mantissa <<= amount_to_shift_left; - // Keep exp2 representing the exponent of the lowest bit of UIntType. + // Keep exp2 representing the exponent of the lowest bit of StorageType. exp2 -= amount_to_shift_left; // biased_exponent represents the biased exponent of the most significant bit. int32_t biased_exponent = - exp2 + FloatProp::UINTTYPE_BITS + FPBits::EXPONENT_BIAS - 1; + exp2 + FloatProp::STORAGE_LEN + FPBits::EXP_BIAS - 1; // Handle numbers that're too large and get squashed to inf if (biased_exponent >= INF_EXP) { // This indicates an overflow, so we make the result INF and set errno. - output.num = {0, (1 << FloatProp::EXPONENT_WIDTH) - 1}; + output.num = {0, (1 << FloatProp::EXP_LEN) - 1}; output.error = ERANGE; return output; } uint32_t amount_to_shift_right = - FloatProp::UINTTYPE_BITS - FloatProp::MANTISSA_WIDTH - 1; + FloatProp::STORAGE_LEN - FloatProp::FRACTION_LEN - 1; // Handle subnormals. if (biased_exponent <= 0) { amount_to_shift_right += 1 - biased_exponent; biased_exponent = 0; - if (amount_to_shift_right > FloatProp::UINTTYPE_BITS) { + if (amount_to_shift_right > FloatProp::STORAGE_LEN) { // Return 0 if the exponent is too small. output.num = {0, 0}; output.error = ERANGE; @@ -771,19 +771,19 @@ LIBC_INLINE FloatConvertReturn binary_exp_to_float(ExpandedFloat init_num, } } - UIntType round_bit_mask = UIntType(1) << (amount_to_shift_right - 1); - UIntType sticky_mask = round_bit_mask - 1; + StorageType round_bit_mask = StorageType(1) << (amount_to_shift_right - 1); + StorageType sticky_mask = round_bit_mask - 1; bool round_bit = static_cast(mantissa & round_bit_mask); bool sticky_bit = static_cast(mantissa & sticky_mask) || truncated; - if (amount_to_shift_right < FloatProp::UINTTYPE_BITS) { + if (amount_to_shift_right < FloatProp::STORAGE_LEN) { // Shift the mantissa and clear the implicit bit. mantissa >>= amount_to_shift_right; - mantissa &= FloatProp::MANTISSA_MASK; + mantissa &= FloatProp::FRACTION_MASK; } else { mantissa = 0; } - bool least_significant_bit = static_cast(mantissa & UIntType(1)); + bool least_significant_bit = static_cast(mantissa & StorageType(1)); // TODO: check that this rounding behavior is correct. @@ -802,7 +802,7 @@ LIBC_INLINE FloatConvertReturn binary_exp_to_float(ExpandedFloat init_num, } } - if (mantissa > FloatProp::MANTISSA_MASK) { + if (mantissa > FloatProp::FRACTION_MASK) { // Rounding causes the exponent to increase. ++biased_exponent; @@ -815,7 +815,7 @@ LIBC_INLINE FloatConvertReturn binary_exp_to_float(ExpandedFloat init_num, output.error = ERANGE; } - output.num = {mantissa & FloatProp::MANTISSA_MASK, biased_exponent}; + output.num = {mantissa & FloatProp::FRACTION_MASK, biased_exponent}; return output; } @@ -844,7 +844,7 @@ LIBC_INLINE StrToNumResult> decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT, RoundDirection round) { using FPBits = typename fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; constexpr uint32_t BASE = 10; constexpr char EXPONENT_MARKER = 'e'; @@ -852,7 +852,7 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT, bool truncated = false; bool seen_digit = false; bool after_decimal = false; - UIntType mantissa = 0; + StorageType mantissa = 0; int32_t exponent = 0; size_t index = 0; @@ -863,8 +863,8 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT, // the format mantissa * (base ^ exponent) // The loop fills the mantissa with as many digits as it can hold - const UIntType bitstype_max_div_by_base = - cpp::numeric_limits::max() / BASE; + const StorageType bitstype_max_div_by_base = + cpp::numeric_limits::max() / BASE; while (true) { if (isdigit(src[index])) { uint32_t digit = src[index] - '0'; @@ -953,7 +953,7 @@ LIBC_INLINE StrToNumResult> hexadecimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT, RoundDirection round) { using FPBits = typename fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; constexpr uint32_t BASE = 16; constexpr char EXPONENT_MARKER = 'p'; @@ -961,7 +961,7 @@ hexadecimal_string_to_float(const char *__restrict src, bool truncated = false; bool seen_digit = false; bool after_decimal = false; - UIntType mantissa = 0; + StorageType mantissa = 0; int32_t exponent = 0; size_t index = 0; @@ -972,8 +972,8 @@ hexadecimal_string_to_float(const char *__restrict src, // the format mantissa * (base ^ exponent) // The loop fills the mantissa with as many digits as it can hold - const UIntType bitstype_max_div_by_base = - cpp::numeric_limits::max() / BASE; + const StorageType bitstype_max_div_by_base = + cpp::numeric_limits::max() / BASE; while (true) { if (isalnum(src[index])) { uint32_t digit = b36_char_to_int(src[index]); @@ -1060,7 +1060,7 @@ hexadecimal_string_to_float(const char *__restrict src, template LIBC_INLINE StrToNumResult strtofloatingpoint(const char *__restrict src) { using FPBits = typename fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; FPBits result = FPBits(); bool seen_digit = false; @@ -1134,7 +1134,7 @@ LIBC_INLINE StrToNumResult strtofloatingpoint(const char *__restrict src) { tolower(src[index + 2]) == nan_string[2]) { seen_digit = true; index += 3; - UIntType nan_mantissa = 0; + StorageType nan_mantissa = 0; // this handles the case of `NaN(n-character-sequence)`, where the // n-character-sequence is made of 0 or more letters and numbers in any // order. @@ -1148,10 +1148,10 @@ LIBC_INLINE StrToNumResult strtofloatingpoint(const char *__restrict src) { if (src[index] == ')') { ++index; if (isdigit(src[left_paren + 1])) { - // This is to prevent errors when UIntType is larger than 64 bits, - // since strtointeger only supports up to 64 bits. This is actually - // more than is required by the specification, which says for the - // input type "NAN(n-char-sequence)" that "the meaning of + // This is to prevent errors when StorageType is larger than 64 + // bits, since strtointeger only supports up to 64 bits. This is + // actually more than is required by the specification, which says + // for the input type "NAN(n-char-sequence)" that "the meaning of // the n-char sequence is implementation-defined." auto strtoint_result = @@ -1159,7 +1159,7 @@ LIBC_INLINE StrToNumResult strtofloatingpoint(const char *__restrict src) { if (strtoint_result.has_error()) { error = strtoint_result.error; } - nan_mantissa = static_cast(strtoint_result.value); + nan_mantissa = static_cast(strtoint_result.value); if (src[left_paren + 1 + strtoint_result.parsed_len] != ')') nan_mantissa = 0; } diff --git a/libc/src/math/generic/acoshf.cpp b/libc/src/math/generic/acoshf.cpp index 9438be1bee74eb4614739319a35f200b17c5f568..142c17795d083a2cbfa359935539fc207cd50956 100644 --- a/libc/src/math/generic/acoshf.cpp +++ b/libc/src/math/generic/acoshf.cpp @@ -34,7 +34,7 @@ LLVM_LIBC_FUNCTION(float, acoshf, (float x)) { if (LIBC_UNLIKELY(x_u >= 0x4f8ffb03)) { // Check for exceptional values. - uint32_t x_abs = x_u & FPBits_t::FloatProp::EXP_MANT_MASK; + uint32_t x_abs = x_u & FPBits_t::EXP_MANT_MASK; if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { // x is +inf or NaN. return x; diff --git a/libc/src/math/generic/asinf.cpp b/libc/src/math/generic/asinf.cpp index f40a08e752ed3989247f3462cc77f79f90591e55..51eefe984b6779fe5f084fd8e231a45e00be4d69 100644 --- a/libc/src/math/generic/asinf.cpp +++ b/libc/src/math/generic/asinf.cpp @@ -108,8 +108,7 @@ LLVM_LIBC_FUNCTION(float, asinf, (float x)) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); } - return x + - FPBits::build_nan(1 << (fputil::MantissaWidth::VALUE - 1)); + return x + FPBits::build_nan(FPBits::FRACTION_MASK); } // Check for exceptional values diff --git a/libc/src/math/generic/asinhf.cpp b/libc/src/math/generic/asinhf.cpp index 6bde08d42a429cdd3533b0ea389399c8c95709d9..5b2f63d3fe144e9700536d5716eb57ff3e1128b2 100644 --- a/libc/src/math/generic/asinhf.cpp +++ b/libc/src/math/generic/asinhf.cpp @@ -21,7 +21,7 @@ LLVM_LIBC_FUNCTION(float, asinhf, (float x)) { using FPBits_t = typename fputil::FPBits; FPBits_t xbits(x); uint32_t x_u = xbits.uintval(); - uint32_t x_abs = x_u & FPBits_t::FloatProp::EXP_MANT_MASK; + uint32_t x_abs = x_u & FPBits_t::EXP_MANT_MASK; // |x| <= 2^-3 if (LIBC_UNLIKELY(x_abs <= 0x3e80'0000U)) { diff --git a/libc/src/math/generic/atanhf.cpp b/libc/src/math/generic/atanhf.cpp index 839ef5b076ac35576a854c837687e160ecd4de84..dfec28e9a44a7234a27cb941080d2663b9ad4414 100644 --- a/libc/src/math/generic/atanhf.cpp +++ b/libc/src/math/generic/atanhf.cpp @@ -17,7 +17,7 @@ LLVM_LIBC_FUNCTION(float, atanhf, (float x)) { using FPBits = typename fputil::FPBits; FPBits xbits(x); bool sign = xbits.get_sign(); - uint32_t x_abs = xbits.uintval() & FPBits::FloatProp::EXP_MANT_MASK; + uint32_t x_abs = xbits.uintval() & FPBits::EXP_MANT_MASK; // |x| >= 1.0 if (LIBC_UNLIKELY(x_abs >= 0x3F80'0000U)) { diff --git a/libc/src/math/generic/erff.cpp b/libc/src/math/generic/erff.cpp index a7b0897c3b58cb76a900c1b5429fac53e145ad49..333ca197dbedb510ca7809987b665c1e118fd085 100644 --- a/libc/src/math/generic/erff.cpp +++ b/libc/src/math/generic/erff.cpp @@ -154,7 +154,7 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) { double xd = static_cast(x); double xsq = xd * xd; - const uint32_t EIGHT = 3 << FPBits::FloatProp::MANTISSA_WIDTH; + const uint32_t EIGHT = 3 << FPBits::FRACTION_LEN; int idx = static_cast(FPBits(x_abs + EIGHT).get_val()); double x4 = xsq * xsq; diff --git a/libc/src/math/generic/exp.cpp b/libc/src/math/generic/exp.cpp index b3f645fb0939b280599d7115b72aee49cb6b9eb3..ebfd14dd6cc166105103eb7172bc9017ca28fbd6 100644 --- a/libc/src/math/generic/exp.cpp +++ b/libc/src/math/generic/exp.cpp @@ -382,7 +382,7 @@ LLVM_LIBC_FUNCTION(double, exp, (double x)) { if (LIBC_LIKELY(upper == lower)) { // to multiply by 2^hi, a fast way is to simply add hi to the exponent // field. - int64_t exp_hi = static_cast(hi) << FloatProp::MANTISSA_WIDTH; + int64_t exp_hi = static_cast(hi) << FloatProp::FRACTION_LEN; double r = cpp::bit_cast(exp_hi + cpp::bit_cast(upper)); return r; } @@ -400,7 +400,7 @@ LLVM_LIBC_FUNCTION(double, exp, (double x)) { double lower_dd = r_dd.hi + (r_dd.lo - ERR_DD); if (LIBC_LIKELY(upper_dd == lower_dd)) { - int64_t exp_hi = static_cast(hi) << FloatProp::MANTISSA_WIDTH; + int64_t exp_hi = static_cast(hi) << FloatProp::FRACTION_LEN; double r = cpp::bit_cast(exp_hi + cpp::bit_cast(upper_dd)); return r; diff --git a/libc/src/math/generic/exp10.cpp b/libc/src/math/generic/exp10.cpp index b152425b14b597b900a7d97d3833c5452b055c71..4e1babcee541bdf454eb38234c953763269f3288 100644 --- a/libc/src/math/generic/exp10.cpp +++ b/libc/src/math/generic/exp10.cpp @@ -395,7 +395,7 @@ LLVM_LIBC_FUNCTION(double, exp10, (double x)) { if (LIBC_LIKELY(upper == lower)) { // To multiply by 2^hi, a fast way is to simply add hi to the exponent // field. - int64_t exp_hi = static_cast(hi) << FloatProp::MANTISSA_WIDTH; + int64_t exp_hi = static_cast(hi) << FloatProp::FRACTION_LEN; double r = cpp::bit_cast(exp_hi + cpp::bit_cast(upper)); return r; } @@ -462,7 +462,7 @@ LLVM_LIBC_FUNCTION(double, exp10, (double x)) { if (LIBC_LIKELY(upper_dd == lower_dd)) { // To multiply by 2^hi, a fast way is to simply add hi to the exponent // field. - int64_t exp_hi = static_cast(hi) << FloatProp::MANTISSA_WIDTH; + int64_t exp_hi = static_cast(hi) << FloatProp::FRACTION_LEN; double r = cpp::bit_cast(exp_hi + cpp::bit_cast(upper_dd)); return r; } diff --git a/libc/src/math/generic/exp2.cpp b/libc/src/math/generic/exp2.cpp index b4b9960ccb2fb65dd8c7002a2077d611e576418e..07691ca0e7b62ae45792e4fda7df1f293dfddb15 100644 --- a/libc/src/math/generic/exp2.cpp +++ b/libc/src/math/generic/exp2.cpp @@ -362,7 +362,7 @@ LLVM_LIBC_FUNCTION(double, exp2, (double x)) { if (LIBC_LIKELY(upper == lower)) { // To multiply by 2^hi, a fast way is to simply add hi to the exponent // field. - int64_t exp_hi = static_cast(hi) << FloatProp::MANTISSA_WIDTH; + int64_t exp_hi = static_cast(hi) << FloatProp::FRACTION_LEN; double r = cpp::bit_cast(exp_hi + cpp::bit_cast(upper)); return r; } @@ -376,7 +376,7 @@ LLVM_LIBC_FUNCTION(double, exp2, (double x)) { if (LIBC_LIKELY(upper_dd == lower_dd)) { // To multiply by 2^hi, a fast way is to simply add hi to the exponent // field. - int64_t exp_hi = static_cast(hi) << FloatProp::MANTISSA_WIDTH; + int64_t exp_hi = static_cast(hi) << FloatProp::FRACTION_LEN; double r = cpp::bit_cast(exp_hi + cpp::bit_cast(upper_dd)); return r; } diff --git a/libc/src/math/generic/exp2f_impl.h b/libc/src/math/generic/exp2f_impl.h index 961fb16977eb83409477808a223fe9144a6e57f2..1d86e4d08770ca7ce28987435bbd3a864a4d74e4 100644 --- a/libc/src/math/generic/exp2f_impl.h +++ b/libc/src/math/generic/exp2f_impl.h @@ -137,7 +137,7 @@ LIBC_INLINE float exp2f(float x) { // exp_hi = shift hi to the exponent field of double precision. int64_t exp_hi = static_cast(static_cast(k >> ExpBase::MID_BITS) - << fputil::FloatProperties::MANTISSA_WIDTH); + << fputil::FloatProperties::FRACTION_LEN); // mh = 2^hi * 2^mid // mh_bits = bit field of mh int64_t mh_bits = ExpBase::EXP_2_MID[k & ExpBase::MID_MASK] + exp_hi; diff --git a/libc/src/math/generic/explogxf.h b/libc/src/math/generic/explogxf.h index 77ec9cb94e085455355f4a4e776516268e25e618..705bf9f5db1cb8ac5dd9a21055dc4b016ca54d6f 100644 --- a/libc/src/math/generic/explogxf.h +++ b/libc/src/math/generic/explogxf.h @@ -162,7 +162,7 @@ template LIBC_INLINE exp_b_reduc_t exp_b_range_reduc(float x) { // hi = floor(kd * 2^(-MID_BITS)) // exp_hi = shift hi to the exponent field of double precision. int64_t exp_hi = static_cast((k >> Base::MID_BITS)) - << fputil::FloatProperties::MANTISSA_WIDTH; + << fputil::FloatProperties::FRACTION_LEN; // mh = 2^hi * 2^mid // mh_bits = bit field of mh int64_t mh_bits = Base::EXP_2_MID[k & Base::MID_MASK] + exp_hi; @@ -235,9 +235,9 @@ template LIBC_INLINE double exp_pm_eval(float x) { // hi = floor(kf * 2^(-5)) // exp_hi = shift hi to the exponent field of double precision. int64_t exp_hi_p = static_cast((k_p >> ExpBase::MID_BITS)) - << fputil::FloatProperties::MANTISSA_WIDTH; + << fputil::FloatProperties::FRACTION_LEN; int64_t exp_hi_m = static_cast((k_m >> ExpBase::MID_BITS)) - << fputil::FloatProperties::MANTISSA_WIDTH; + << fputil::FloatProperties::FRACTION_LEN; // mh_p = 2^(hi + mid) // mh_m = 2^(-(hi + mid)) // mh_bits_* = bit field of mh_* @@ -280,12 +280,11 @@ LIBC_INLINE static double log2_eval(double x) { double result = 0; result += bs.get_exponent(); - int p1 = - (bs.get_mantissa() >> (FPB::FloatProp::MANTISSA_WIDTH - LOG_P1_BITS)) & - (LOG_P1_SIZE - 1); + int p1 = (bs.get_mantissa() >> (FPB::FRACTION_LEN - LOG_P1_BITS)) & + (LOG_P1_SIZE - 1); - bs.bits &= FPB::FloatProp::MANTISSA_MASK >> LOG_P1_BITS; - bs.set_biased_exponent(FPB::FloatProp::EXPONENT_BIAS); + bs.bits &= FPB::FRACTION_MASK >> LOG_P1_BITS; + bs.set_biased_exponent(FPB::EXP_BIAS); double dx = (bs.get_val() - 1.0) * LOG_P1_1_OVER[p1]; // Taylor series for log(2,1+x) @@ -311,12 +310,11 @@ LIBC_INLINE static double log_eval(double x) { // p1 is the leading 7 bits of mx, i.e. // p1 * 2^(-7) <= m_x < (p1 + 1) * 2^(-7). - int p1 = static_cast(bs.get_mantissa() >> - (FPB::FloatProp::MANTISSA_WIDTH - 7)); + int p1 = static_cast(bs.get_mantissa() >> (FPB::FRACTION_LEN - 7)); // Set bs to (1 + (mx - p1*2^(-7)) - bs.bits &= FPB::FloatProp::MANTISSA_MASK >> 7; - bs.set_biased_exponent(FPB::FloatProp::EXPONENT_BIAS); + bs.bits &= FPB::FRACTION_MASK >> 7; + bs.set_biased_exponent(FPB::EXP_BIAS); // dx = (mx - p1*2^(-7)) / (1 + p1*2^(-7)). double dx = (bs.get_val() - 1.0) * ONE_OVER_F[p1]; @@ -347,7 +345,7 @@ LIBC_INLINE cpp::optional ziv_test_denorm(int hi, double mid, double lo, using FloatProp = typename fputil::FloatProperties; // Scaling factor = 1/(min normal number) = 2^1022 - int64_t exp_hi = static_cast(hi + 1022) << FloatProp::MANTISSA_WIDTH; + int64_t exp_hi = static_cast(hi + 1022) << FloatProp::FRACTION_LEN; double mid_hi = cpp::bit_cast(exp_hi + cpp::bit_cast(mid)); double lo_scaled = (lo != 0.0) ? cpp::bit_cast(exp_hi + cpp::bit_cast(lo)) diff --git a/libc/src/math/generic/expm1.cpp b/libc/src/math/generic/expm1.cpp index e75139548153410f0fd01727c3d77607fcf9ea69..a0d47f00828ce48311160e21c6fbb7e6d4d2d71b 100644 --- a/libc/src/math/generic/expm1.cpp +++ b/libc/src/math/generic/expm1.cpp @@ -390,7 +390,7 @@ LLVM_LIBC_FUNCTION(double, expm1, (double x)) { // -2^(-hi) double one_scaled = - FPBits::create_value(true, FPBits::EXPONENT_BIAS - hi, 0).get_val(); + FPBits::create_value(true, FPBits::EXP_BIAS - hi, 0).get_val(); // 2^(mid1 + mid2) - 2^(-hi) DoubleDouble hi_part = x_sign ? fputil::exact_add(one_scaled, exp_mid.hi) @@ -465,7 +465,7 @@ LLVM_LIBC_FUNCTION(double, expm1, (double x)) { if (LIBC_LIKELY(upper == lower)) { // to multiply by 2^hi, a fast way is to simply add hi to the exponent // field. - int64_t exp_hi = static_cast(hi) << FloatProp::MANTISSA_WIDTH; + int64_t exp_hi = static_cast(hi) << FloatProp::FRACTION_LEN; double r = cpp::bit_cast(exp_hi + cpp::bit_cast(upper)); return r; } @@ -479,7 +479,7 @@ LLVM_LIBC_FUNCTION(double, expm1, (double x)) { double lower_dd = r_dd.hi + (r_dd.lo - err_dd); if (LIBC_LIKELY(upper_dd == lower_dd)) { - int64_t exp_hi = static_cast(hi) << FloatProp::MANTISSA_WIDTH; + int64_t exp_hi = static_cast(hi) << FloatProp::FRACTION_LEN; double r = cpp::bit_cast(exp_hi + cpp::bit_cast(upper_dd)); return r; } diff --git a/libc/src/math/generic/hypotf.cpp b/libc/src/math/generic/hypotf.cpp index 389de3c450299d479ad4c53a1daf8e9568b79ab3..93dd4feb36bee65577fd05435f4faa01f190347b 100644 --- a/libc/src/math/generic/hypotf.cpp +++ b/libc/src/math/generic/hypotf.cpp @@ -23,7 +23,7 @@ LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) { uint16_t y_exp = y_bits.get_biased_exponent(); uint16_t exp_diff = (x_exp > y_exp) ? (x_exp - y_exp) : (y_exp - x_exp); - if (exp_diff >= fputil::MantissaWidth::VALUE + 2) { + if (exp_diff >= FPBits::FRACTION_LEN + 2) { return fputil::abs(x) + fputil::abs(y); } diff --git a/libc/src/math/generic/inv_trigf_utils.h b/libc/src/math/generic/inv_trigf_utils.h index c88ded20b5bf24f4da93451cd1cad2d22604ba62..588ebbfa71aeb045eddaea65fb98356e03955b47 100644 --- a/libc/src/math/generic/inv_trigf_utils.h +++ b/libc/src/math/generic/inv_trigf_utils.h @@ -40,18 +40,17 @@ LIBC_INLINE double atan_eval(double x) { using FPB = fputil::FPBits; // Added some small value to umin and umax mantissa to avoid possible rounding // errors. - FPB::UIntType umin = - FPB::create_value(false, FPB::EXPONENT_BIAS - ATAN_T_BITS - 1, + FPB::StorageType umin = + FPB::create_value(false, FPB::EXP_BIAS - ATAN_T_BITS - 1, 0x100000000000UL) .uintval(); - FPB::UIntType umax = - FPB::create_value(false, FPB::EXPONENT_BIAS + ATAN_T_BITS, - 0xF000000000000UL) + FPB::StorageType umax = + FPB::create_value(false, FPB::EXP_BIAS + ATAN_T_BITS, 0xF000000000000UL) .uintval(); FPB bs(x); bool sign = bs.get_sign(); - auto x_abs = bs.uintval() & FPB::FloatProp::EXP_MANT_MASK; + auto x_abs = bs.uintval() & FPB::EXP_MANT_MASK; if (x_abs <= umin) { double pe = LIBC_NAMESPACE::fputil::polyeval( @@ -64,7 +63,8 @@ LIBC_INLINE double atan_eval(double x) { double one_over_x2 = one_over_x_m * one_over_x_m; double pe = LIBC_NAMESPACE::fputil::polyeval( one_over_x2, ATAN_K[0], ATAN_K[1], ATAN_K[2], ATAN_K[3]); - return fputil::multiply_add(pe, one_over_x_m, sign ? (-M_MATH_PI_2) : (M_MATH_PI_2)); + return fputil::multiply_add(pe, one_over_x_m, + sign ? (-M_MATH_PI_2) : (M_MATH_PI_2)); } double pos_x = FPB(x_abs).get_val(); diff --git a/libc/src/math/generic/log.cpp b/libc/src/math/generic/log.cpp index dfa41ad64578d300e0c921a3752237bc51c1a24c..f82683bcc05544c1421b9f3e331145a06cc61a74 100644 --- a/libc/src/math/generic/log.cpp +++ b/libc/src/math/generic/log.cpp @@ -734,7 +734,7 @@ LLVM_LIBC_FUNCTION(double, log, (double x)) { FPBits_t xbits(x); uint64_t x_u = xbits.uintval(); - int x_e = -FPBits_t::EXPONENT_BIAS; + int x_e = -FPBits_t::EXP_BIAS; if (LIBC_UNLIKELY(x_u == 0x3FF0'0000'0000'0000ULL)) { // log(1.0) = +0.0 diff --git a/libc/src/math/generic/log10.cpp b/libc/src/math/generic/log10.cpp index 2a801c6e98429a686220fb55265403159cd56091..d2b94f22687fb8274f1c9c55b5b01e1cc80eef63 100644 --- a/libc/src/math/generic/log10.cpp +++ b/libc/src/math/generic/log10.cpp @@ -735,7 +735,7 @@ LLVM_LIBC_FUNCTION(double, log10, (double x)) { FPBits_t xbits(x); uint64_t x_u = xbits.uintval(); - int x_e = -FPBits_t::EXPONENT_BIAS; + int x_e = -FPBits_t::EXP_BIAS; if (LIBC_UNLIKELY(x_u == 0x3FF0'0000'0000'0000ULL)) { // log10(1.0) = +0.0 diff --git a/libc/src/math/generic/log10f.cpp b/libc/src/math/generic/log10f.cpp index 927af35c98f28b0c9231a69f0d9b0781a6336353..b70183958899cc767c522cf86cb8a8736044e57c 100644 --- a/libc/src/math/generic/log10f.cpp +++ b/libc/src/math/generic/log10f.cpp @@ -158,7 +158,7 @@ LLVM_LIBC_FUNCTION(float, log10f, (float x)) { } } - int m = -FPBits::EXPONENT_BIAS; + int m = -FPBits::EXP_BIAS; if (LIBC_UNLIKELY(x_u < FPBits::MIN_NORMAL || x_u > FPBits::MAX_NORMAL)) { if (xbits.is_zero()) { diff --git a/libc/src/math/generic/log1p.cpp b/libc/src/math/generic/log1p.cpp index c8b45fd57b42f8803bdd1102e7ff31085d6b89a1..74eed6ceeb28dc60b696f2e300ca5c78bb2764c1 100644 --- a/libc/src/math/generic/log1p.cpp +++ b/libc/src/math/generic/log1p.cpp @@ -872,9 +872,9 @@ LIBC_INLINE double log1p_accurate(int e_x, int index, LLVM_LIBC_FUNCTION(double, log1p, (double x)) { using FPBits_t = typename fputil::FPBits; - constexpr int EXPONENT_BIAS = FPBits_t::EXPONENT_BIAS; - constexpr int MANTISSA_WIDTH = FPBits_t::FloatProp::MANTISSA_WIDTH; - constexpr uint64_t MANTISSA_MASK = FPBits_t::FloatProp::MANTISSA_MASK; + constexpr int EXP_BIAS = FPBits_t::EXP_BIAS; + constexpr int FRACTION_LEN = FPBits_t::FRACTION_LEN; + constexpr uint64_t FRACTION_MASK = FPBits_t::FRACTION_MASK; FPBits_t xbits(x); uint64_t x_u = xbits.uintval(); @@ -882,7 +882,7 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) { uint16_t x_exp = xbits.get_biased_exponent(); - if (x_exp >= EXPONENT_BIAS) { + if (x_exp >= EXP_BIAS) { // |x| >= 1 if (LIBC_UNLIKELY(x_u >= 0x4650'0000'0000'0000ULL)) { // x >= 2^102 or x is negative, inf, or NaN @@ -910,7 +910,7 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) { } else { // |x| < 1 if (LIBC_UNLIKELY(xbits.get_biased_exponent() < - EXPONENT_BIAS - MANTISSA_WIDTH - 1)) { + EXP_BIAS - FRACTION_LEN - 1)) { // Quick return when |x| < 2^-53. // Since log(1 + x) = x - x^2/2 + x^3/3 - ..., // for |x| < 2^-53, @@ -949,9 +949,9 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) { x_u = xhi_bits.uintval(); // Range reduction: // Find k such that |x_hi - k * 2^-7| <= 2^-8. - int idx = static_cast( - ((x_u & MANTISSA_MASK) + (1ULL << (MANTISSA_WIDTH - 8))) >> - (MANTISSA_WIDTH - 7)); + int idx = + static_cast(((x_u & FRACTION_MASK) + (1ULL << (FRACTION_LEN - 8))) >> + (FRACTION_LEN - 7)); int x_e = xhi_bits.get_exponent() + (idx >> 7); double e_x = static_cast(x_e); @@ -967,9 +967,8 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) { double err_hi = ERR_HI[hi == 0.0]; // Scaling factior = 2^(-xh_bits.get_exponent()) - uint64_t s_u = - (static_cast(EXPONENT_BIAS) << (MANTISSA_WIDTH + 1)) - - (x_u & FPBits_t::FloatProp::EXPONENT_MASK); + uint64_t s_u = (static_cast(EXP_BIAS) << (FRACTION_LEN + 1)) - + (x_u & FPBits_t::EXP_MASK); // When the exponent of x is 2^1023, its inverse, 2^(-1023), is subnormal. const double EXPONENT_CORRECTION[2] = {0.0, 0x1.0p-1023}; double scaling = FPBits_t(s_u).get_val() + EXPONENT_CORRECTION[s_u == 0]; @@ -999,7 +998,7 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) { v_hi = fputil::multiply_add(r, m_dd.hi, -1.0); // Exact. #else // c = 1 + idx * 2^-7. - double c = FPBits_t((static_cast(idx) << (MANTISSA_WIDTH - 7)) + + double c = FPBits_t((static_cast(idx) << (FRACTION_LEN - 7)) + uint64_t(0x3FF0'0000'0000'0000ULL)) .get_val(); v_hi = fputil::multiply_add(r, m_dd.hi - c, RCM1[idx]); // Exact diff --git a/libc/src/math/generic/log1pf.cpp b/libc/src/math/generic/log1pf.cpp index fd3cf4647fd0da93f3c9bb5330b8118eb2f6047e..891700d5ed08c85358e540ea2c2d98977535e145 100644 --- a/libc/src/math/generic/log1pf.cpp +++ b/libc/src/math/generic/log1pf.cpp @@ -56,8 +56,8 @@ LIBC_INLINE float log(double x) { // Get the 8 highest bits, use 7 bits (excluding the implicit hidden bit) for // lookup tables. - int f_index = static_cast( - xbits.get_mantissa() >> 45); // fputil::MantissaWidth::VALUE - 7 + int f_index = static_cast(xbits.get_mantissa() >> + (fputil::FPBits::FRACTION_LEN - 7)); // Set bits to 1.m xbits.set_biased_exponent(0x3FF); diff --git a/libc/src/math/generic/log2.cpp b/libc/src/math/generic/log2.cpp index 2ceddf87dfd56090e31b41aeb0bf35787e7f4c6e..a333a075fe5affd95566bf93688dc678906e83a9 100644 --- a/libc/src/math/generic/log2.cpp +++ b/libc/src/math/generic/log2.cpp @@ -856,7 +856,7 @@ LLVM_LIBC_FUNCTION(double, log2, (double x)) { FPBits_t xbits(x); uint64_t x_u = xbits.uintval(); - int x_e = -FPBits_t::EXPONENT_BIAS; + int x_e = -FPBits_t::EXP_BIAS; if (LIBC_UNLIKELY(x_u == 0x3FF0'0000'0000'0000ULL)) { // log2(1.0) = +0.0 diff --git a/libc/src/math/generic/log2f.cpp b/libc/src/math/generic/log2f.cpp index 4bbc9f51c3d2af7c0736afd91102bb45cd312deb..e7aeda723b50a83a137a8d1c7f470ae9c76878d4 100644 --- a/libc/src/math/generic/log2f.cpp +++ b/libc/src/math/generic/log2f.cpp @@ -61,7 +61,7 @@ LLVM_LIBC_FUNCTION(float, log2f, (float x)) { // Hard to round value(s). using fputil::round_result_slightly_up; - int m = -FPBits::EXPONENT_BIAS; + int m = -FPBits::EXP_BIAS; // log2(1.0f) = 0.0f. if (LIBC_UNLIKELY(x_u == 0x3f80'0000U)) diff --git a/libc/src/math/generic/logf.cpp b/libc/src/math/generic/logf.cpp index 2dfada38b972383bcfa68bc907b3d9f46a9762bd..2ebdddbb2d16daca604b04ef010f06c1c6fc0e16 100644 --- a/libc/src/math/generic/logf.cpp +++ b/libc/src/math/generic/logf.cpp @@ -57,7 +57,7 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) { FPBits xbits(x); uint32_t x_u = xbits.uintval(); - int m = -FPBits::EXPONENT_BIAS; + int m = -FPBits::EXP_BIAS; using fputil::round_result_slightly_down; using fputil::round_result_slightly_up; diff --git a/libc/src/math/generic/powf.cpp b/libc/src/math/generic/powf.cpp index efc866618ef21923fe35c6dd662af052489a0ded..dd7fa7f6115d4edf70db509b35bcdd8091ba9a36 100644 --- a/libc/src/math/generic/powf.cpp +++ b/libc/src/math/generic/powf.cpp @@ -389,24 +389,22 @@ static constexpr DoubleDouble LOG2_R2_DD[] = { LIBC_INLINE bool is_odd_integer(float x) { using FloatProp = typename fputil::FloatProperties; uint32_t x_u = cpp::bit_cast(x); - int32_t x_e = static_cast((x_u & FloatProp::EXPONENT_MASK) >> - FloatProp::MANTISSA_WIDTH); - int32_t lsb = cpp::countr_zero(x_u | FloatProp::EXPONENT_MASK); + int32_t x_e = static_cast((x_u & FloatProp::EXP_MASK) >> + FloatProp::FRACTION_LEN); + int32_t lsb = cpp::countr_zero(x_u | FloatProp::EXP_MASK); constexpr int32_t UNIT_EXPONENT = - FloatProp::EXPONENT_BIAS + - static_cast(FloatProp::MANTISSA_WIDTH); + FloatProp::EXP_BIAS + static_cast(FloatProp::FRACTION_LEN); return (x_e + lsb == UNIT_EXPONENT); } LIBC_INLINE bool is_integer(float x) { using FloatProp = typename fputil::FloatProperties; uint32_t x_u = cpp::bit_cast(x); - int32_t x_e = static_cast((x_u & FloatProp::EXPONENT_MASK) >> - FloatProp::MANTISSA_WIDTH); - int32_t lsb = cpp::countr_zero(x_u | FloatProp::EXPONENT_MASK); + int32_t x_e = static_cast((x_u & FloatProp::EXP_MASK) >> + FloatProp::FRACTION_LEN); + int32_t lsb = cpp::countr_zero(x_u | FloatProp::EXP_MASK); constexpr int32_t UNIT_EXPONENT = - FloatProp::EXPONENT_BIAS + - static_cast(FloatProp::MANTISSA_WIDTH); + FloatProp::EXP_BIAS + static_cast(FloatProp::FRACTION_LEN); return (x_e + lsb >= UNIT_EXPONENT); } @@ -502,7 +500,7 @@ double powf_double_double(int idx_x, double dx, double y6, double lo6_hi, bool lo_sign = DoubleBits(r.lo).get_sign(); if (hi_sign == lo_sign) { ++r_bits; - } else if ((r_bits & DoubleProp::MANTISSA_MASK) > 0) { + } else if ((r_bits & DoubleProp::FRACTION_MASK) > 0) { --r_bits; } } @@ -591,7 +589,7 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { } } - int ex = -FloatBits::EXPONENT_BIAS; + int ex = -FloatBits::EXP_BIAS; uint64_t sign = 0; // y is finite and non-zero. @@ -671,11 +669,11 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { x_u = FloatBits(x).uintval(); // Extract exponent field of x. - ex += (x_u >> FloatProp::MANTISSA_WIDTH); + ex += (x_u >> FloatProp::FRACTION_LEN); double e_x = static_cast(ex); // Use the highest 7 fractional bits of m_x as the index for look up tables. - uint32_t x_mant = x_u & FloatProp::MANTISSA_MASK; - int idx_x = static_cast(x_mant >> (FloatProp::MANTISSA_WIDTH - 7)); + uint32_t x_mant = x_u & FloatProp::FRACTION_MASK; + int idx_x = static_cast(x_mant >> (FloatProp::FRACTION_LEN - 7)); // Add the hidden bit to the mantissa. // 1 <= m_x < 2 float m_x = cpp::bit_cast(x_mant | 0x3f800000); @@ -776,7 +774,7 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { int idx_y = hm_i & 0x3f; // 2^hi - int64_t exp_hi_i = (hm_i >> 6) << DoubleProp::MANTISSA_WIDTH; + int64_t exp_hi_i = (hm_i >> 6) << DoubleProp::FRACTION_LEN; // 2^mid int64_t exp_mid_i = cpp::bit_cast(EXP2_MID1[idx_y].hi); // (-1)^sign * 2^hi * 2^mid diff --git a/libc/src/math/generic/range_reduction.h b/libc/src/math/generic/range_reduction.h index 551f2457ecb8e330cbebad954ef573465af25255..84f3cae9e3294eed41acf0618b889a35bcee7213 100644 --- a/libc/src/math/generic/range_reduction.h +++ b/libc/src/math/generic/range_reduction.h @@ -59,7 +59,7 @@ LIBC_INLINE int64_t small_range_reduction(double x, double &y) { LIBC_INLINE int64_t large_range_reduction(double x, int x_exp, double &y) { int idx = 0; y = 0; - int x_lsb_exp_m4 = x_exp - fputil::FloatProperties::MANTISSA_WIDTH; + int x_lsb_exp_m4 = x_exp - fputil::FloatProperties::FRACTION_LEN; // Skipping the first parts of 32/pi such that: // LSB of x * LSB of THIRTYTWO_OVER_PI_28[i] >= 32. diff --git a/libc/src/math/generic/sincosf.cpp b/libc/src/math/generic/sincosf.cpp index 7ed1c4381078b1f2460d9106db3c26829e680203..44371db710871acf5af0e067cfb39e2259caa0c1 100644 --- a/libc/src/math/generic/sincosf.cpp +++ b/libc/src/math/generic/sincosf.cpp @@ -148,8 +148,7 @@ LLVM_LIBC_FUNCTION(void, sincosf, (float x, float *sinp, float *cosp)) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); } - *sinp = - x + FPBits::build_nan(1 << (fputil::MantissaWidth::VALUE - 1)); + *sinp = x + FPBits::build_nan(FPBits::FRACTION_MASK); *cosp = *sinp; return; } diff --git a/libc/src/math/generic/sinhf.cpp b/libc/src/math/generic/sinhf.cpp index 2f48ddbc0f88d3c47531636b343632536f935cc0..db6794620b068c7dede0e529e8c7c13adcd6aa98 100644 --- a/libc/src/math/generic/sinhf.cpp +++ b/libc/src/math/generic/sinhf.cpp @@ -17,7 +17,7 @@ namespace LIBC_NAMESPACE { LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { using FPBits = typename fputil::FPBits; FPBits xbits(x); - uint32_t x_abs = xbits.uintval() & FPBits::FloatProp::EXP_MANT_MASK; + uint32_t x_abs = xbits.uintval() & FPBits::EXP_MANT_MASK; // When |x| >= 90, or x is inf or nan if (LIBC_UNLIKELY(x_abs >= 0x42b4'0000U || x_abs <= 0x3da0'0000U)) { @@ -57,8 +57,7 @@ LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { int rounding = fputil::quick_get_round(); if (sign) { if (LIBC_UNLIKELY(rounding == FE_UPWARD || rounding == FE_TOWARDZERO)) - return FPBits(FPBits::MAX_NORMAL | FPBits::FloatProp::SIGN_MASK) - .get_val(); + return FPBits(FPBits::MAX_NORMAL | FPBits::SIGN_MASK).get_val(); } else { if (LIBC_UNLIKELY(rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)) return FPBits(FPBits::MAX_NORMAL).get_val(); diff --git a/libc/src/math/generic/tanhf.cpp b/libc/src/math/generic/tanhf.cpp index 7d9f86cf9044b237941896b150f16779aeee882b..9042a41c5ed3fe09fa5716784780186db6a677fd 100644 --- a/libc/src/math/generic/tanhf.cpp +++ b/libc/src/math/generic/tanhf.cpp @@ -24,7 +24,7 @@ LLVM_LIBC_FUNCTION(float, tanhf, (float x)) { using FPBits = typename fputil::FPBits; FPBits xbits(x); uint32_t x_u = xbits.uintval(); - uint32_t x_abs = x_u & FPBits::FloatProp::EXP_MANT_MASK; + uint32_t x_abs = x_u & FPBits::EXP_MANT_MASK; // When |x| >= 15, or x is inf or nan, or |x| <= 0.078125 if (LIBC_UNLIKELY((x_abs >= 0x4170'0000U) || (x_abs <= 0x3da0'0000U))) { @@ -90,7 +90,7 @@ LLVM_LIBC_FUNCTION(float, tanhf, (float x)) { // -hi = floor(-k * 2^(-MID_BITS)) // exp_mhi = shift -hi to the exponent field of double precision. int64_t exp_mhi = static_cast(mk >> ExpBase::MID_BITS) - << fputil::FloatProperties::MANTISSA_WIDTH; + << fputil::FloatProperties::FRACTION_LEN; // mh = 2^(-hi - mid) int64_t mh_bits = ExpBase::EXP_2_MID[mk & ExpBase::MID_MASK] + exp_mhi; double mh = fputil::FPBits(uint64_t(mh_bits)).get_val(); diff --git a/libc/src/stdio/printf_core/core_structs.h b/libc/src/stdio/printf_core/core_structs.h index 88a13703fd947613b4d6d84342f401e0cebf9373..37538362fa3e72ea5469338f2fc0f14aebf15a6f 100644 --- a/libc/src/stdio/printf_core/core_structs.h +++ b/libc/src/stdio/printf_core/core_structs.h @@ -46,7 +46,7 @@ struct FormatSection { int precision = -1; // Needs to be large enough to hold a long double. - fputil::FPBits::UIntType conv_val_raw; + fputil::FPBits::StorageType conv_val_raw; void *conv_val_ptr; char conv_name; diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h index ca522710040696354de0ddf22f3c04bf6aa573fb..458f494d5edfdadbadf56a7226e395247081edea 100644 --- a/libc/src/stdio/printf_core/float_dec_converter.h +++ b/libc/src/stdio/printf_core/float_dec_converter.h @@ -31,7 +31,7 @@ namespace LIBC_NAMESPACE { namespace printf_core { -using MantissaInt = fputil::FPBits::UIntType; +using StorageType = fputil::FPBits::StorageType; using DecimalString = IntegerToString; using ExponentString = IntegerToString::WithSign>; @@ -245,7 +245,7 @@ class FloatWriter { // -exponent will never overflow because all long double types we support // have at most 15 bits of mantissa and the C standard defines an int as // being at least 16 bits. - static_assert(fputil::FloatProperties::EXPONENT_WIDTH < + static_assert(fputil::FloatProperties::EXP_LEN < (sizeof(int) * 8)); public: @@ -477,8 +477,8 @@ template , int> = 0> LIBC_INLINE int convert_float_decimal_typed(Writer *writer, const FormatSection &to_conv, fputil::FPBits float_bits) { - // signed because later we use -MANT_WIDTH - constexpr int32_t MANT_WIDTH = fputil::MantissaWidth::VALUE; + // signed because later we use -FRACTION_LEN + constexpr int32_t FRACTION_LEN = fputil::FloatProperties::FRACTION_LEN; bool is_negative = float_bits.get_sign(); int exponent = float_bits.get_explicit_exponent(); @@ -536,7 +536,7 @@ LIBC_INLINE int convert_float_decimal_typed(Writer *writer, float_writer.write_first_block(0); } - if (exponent < MANT_WIDTH) { + if (exponent < FRACTION_LEN) { const uint32_t blocks = (precision / static_cast(BLOCK_SIZE)) + 1; uint32_t i = 0; // if all the blocks we should write are zero @@ -569,9 +569,9 @@ LIBC_INLINE int convert_float_decimal_typed(Writer *writer, digits /= 10; } RoundDirection round; - const bool truncated = - !zero_after_digits(exponent - MANT_WIDTH, precision, - float_bits.get_explicit_mantissa(), MANT_WIDTH); + const bool truncated = !zero_after_digits( + exponent - FRACTION_LEN, precision, + float_bits.get_explicit_mantissa(), FRACTION_LEN); round = get_round_direction(last_digit, truncated, is_negative); RET_IF_RESULT_NEGATIVE( @@ -590,11 +590,11 @@ template , int> = 0> LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer, const FormatSection &to_conv, fputil::FPBits float_bits) { - // signed because later we use -MANT_WIDTH - constexpr int32_t MANT_WIDTH = fputil::MantissaWidth::VALUE; + // signed because later we use -FRACTION_LEN + constexpr int32_t FRACTION_LEN = fputil::FloatProperties::FRACTION_LEN; bool is_negative = float_bits.get_sign(); int exponent = float_bits.get_explicit_exponent(); - MantissaInt mantissa = float_bits.get_explicit_mantissa(); + StorageType mantissa = float_bits.get_explicit_mantissa(); const char a = (to_conv.conv_name & 32) | 'A'; @@ -733,11 +733,11 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer, } } // If it's still not truncated and there are digits below the decimal point - if (!truncated && exponent - MANT_WIDTH < 0) { + if (!truncated && exponent - FRACTION_LEN < 0) { // Use the formula from %f. - truncated = - !zero_after_digits(exponent - MANT_WIDTH, precision - final_exponent, - float_bits.get_explicit_mantissa(), MANT_WIDTH); + truncated = !zero_after_digits( + exponent - FRACTION_LEN, precision - final_exponent, + float_bits.get_explicit_mantissa(), FRACTION_LEN); } } round = get_round_direction(last_digit, truncated, is_negative); @@ -753,11 +753,11 @@ template , int> = 0> LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer, const FormatSection &to_conv, fputil::FPBits float_bits) { - // signed because later we use -MANT_WIDTH - constexpr int32_t MANT_WIDTH = fputil::MantissaWidth::VALUE; + // signed because later we use -FRACTION_LEN + constexpr int32_t FRACTION_LEN = fputil::FloatProperties::FRACTION_LEN; bool is_negative = float_bits.get_sign(); int exponent = float_bits.get_explicit_exponent(); - MantissaInt mantissa = float_bits.get_explicit_mantissa(); + StorageType mantissa = float_bits.get_explicit_mantissa(); // From the standard: Let P (init_precision) equal the precision if nonzero, 6 // if the precision is omitted, or 1 if the precision is zero. @@ -980,11 +980,11 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer, } } // If it's still not truncated and there are digits below the decimal point - if (!truncated && exponent - MANT_WIDTH < 0) { + if (!truncated && exponent - FRACTION_LEN < 0) { // Use the formula from %f. - truncated = - !zero_after_digits(exponent - MANT_WIDTH, exp_precision - base_10_exp, - float_bits.get_explicit_mantissa(), MANT_WIDTH); + truncated = !zero_after_digits( + exponent - FRACTION_LEN, exp_precision - base_10_exp, + float_bits.get_explicit_mantissa(), FRACTION_LEN); } } @@ -1120,15 +1120,15 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer, LIBC_INLINE int convert_float_decimal(Writer *writer, const FormatSection &to_conv) { if (to_conv.length_modifier == LengthModifier::L) { - fputil::FPBits::UIntType float_raw = to_conv.conv_val_raw; + fputil::FPBits::StorageType float_raw = to_conv.conv_val_raw; fputil::FPBits float_bits(float_raw); if (!float_bits.is_inf_or_nan()) { return convert_float_decimal_typed(writer, to_conv, float_bits); } } else { - fputil::FPBits::UIntType float_raw = - static_cast::UIntType>(to_conv.conv_val_raw); + fputil::FPBits::StorageType float_raw = + static_cast::StorageType>(to_conv.conv_val_raw); fputil::FPBits float_bits(float_raw); if (!float_bits.is_inf_or_nan()) { return convert_float_decimal_typed(writer, to_conv, float_bits); @@ -1141,15 +1141,15 @@ LIBC_INLINE int convert_float_decimal(Writer *writer, LIBC_INLINE int convert_float_dec_exp(Writer *writer, const FormatSection &to_conv) { if (to_conv.length_modifier == LengthModifier::L) { - fputil::FPBits::UIntType float_raw = to_conv.conv_val_raw; + fputil::FPBits::StorageType float_raw = to_conv.conv_val_raw; fputil::FPBits float_bits(float_raw); if (!float_bits.is_inf_or_nan()) { return convert_float_dec_exp_typed(writer, to_conv, float_bits); } } else { - fputil::FPBits::UIntType float_raw = - static_cast::UIntType>(to_conv.conv_val_raw); + fputil::FPBits::StorageType float_raw = + static_cast::StorageType>(to_conv.conv_val_raw); fputil::FPBits float_bits(float_raw); if (!float_bits.is_inf_or_nan()) { return convert_float_dec_exp_typed(writer, to_conv, float_bits); @@ -1162,15 +1162,15 @@ LIBC_INLINE int convert_float_dec_exp(Writer *writer, LIBC_INLINE int convert_float_dec_auto(Writer *writer, const FormatSection &to_conv) { if (to_conv.length_modifier == LengthModifier::L) { - fputil::FPBits::UIntType float_raw = to_conv.conv_val_raw; + fputil::FPBits::StorageType float_raw = to_conv.conv_val_raw; fputil::FPBits float_bits(float_raw); if (!float_bits.is_inf_or_nan()) { return convert_float_dec_auto_typed(writer, to_conv, float_bits); } } else { - fputil::FPBits::UIntType float_raw = - static_cast::UIntType>(to_conv.conv_val_raw); + fputil::FPBits::StorageType float_raw = + static_cast::StorageType>(to_conv.conv_val_raw); fputil::FPBits float_bits(float_raw); if (!float_bits.is_inf_or_nan()) { return convert_float_dec_auto_typed(writer, to_conv, float_bits); diff --git a/libc/src/stdio/printf_core/float_hex_converter.h b/libc/src/stdio/printf_core/float_hex_converter.h index 1f105492e8e5a3944608ce3f3384769b4581a0fd..a3a8c0420beffca27ae9cb777ef2e21dd448903f 100644 --- a/libc/src/stdio/printf_core/float_hex_converter.h +++ b/libc/src/stdio/printf_core/float_hex_converter.h @@ -25,10 +25,10 @@ namespace LIBC_NAMESPACE { namespace printf_core { -using MantissaInt = fputil::FPBits::UIntType; - LIBC_INLINE int convert_float_hex_exp(Writer *writer, const FormatSection &to_conv) { + using LDBits = fputil::FPBits; + using StorageType = LDBits::StorageType; // All of the letters will be defined relative to variable a, which will be // the appropriate case based on the name of the conversion. This converts any // conversion name into the letter 'a' with the appropriate case. @@ -36,22 +36,23 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, bool is_negative; int exponent; - MantissaInt mantissa; + StorageType mantissa; bool is_inf_or_nan; - uint32_t mantissa_width; + uint32_t fraction_bits; if (to_conv.length_modifier == LengthModifier::L) { - mantissa_width = fputil::MantissaWidth::VALUE; - fputil::FPBits::UIntType float_raw = to_conv.conv_val_raw; - fputil::FPBits float_bits(float_raw); + fraction_bits = LDBits::FRACTION_LEN; + LDBits::StorageType float_raw = to_conv.conv_val_raw; + LDBits float_bits(float_raw); is_negative = float_bits.get_sign(); exponent = float_bits.get_explicit_exponent(); mantissa = float_bits.get_explicit_mantissa(); is_inf_or_nan = float_bits.is_inf_or_nan(); } else { - mantissa_width = fputil::MantissaWidth::VALUE; - fputil::FPBits::UIntType float_raw = - static_cast::UIntType>(to_conv.conv_val_raw); - fputil::FPBits float_bits(float_raw); + using LBits = fputil::FPBits; + fraction_bits = LBits::FRACTION_LEN; + LBits::StorageType float_raw = + static_cast(to_conv.conv_val_raw); + LBits float_bits(float_raw); is_negative = float_bits.get_sign(); exponent = float_bits.get_explicit_exponent(); mantissa = float_bits.get_explicit_mantissa(); @@ -77,8 +78,8 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, // digits. This is primarily relevant for x86 80 bit long doubles, which have // 63 bit mantissas. In the case where the mantissa is 0, however, the // exponent should stay as 0. - if (mantissa_width % BITS_IN_HEX_DIGIT != 0 && mantissa > 0) { - exponent -= mantissa_width % BITS_IN_HEX_DIGIT; + if (fraction_bits % BITS_IN_HEX_DIGIT != 0 && mantissa > 0) { + exponent -= fraction_bits % BITS_IN_HEX_DIGIT; } // This is the max number of digits it can take to represent the mantissa. @@ -86,10 +87,10 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, // for the extra implicit bit. We use the larger of the two possible values // since the size must be constant. constexpr size_t MANT_BUFF_LEN = - (fputil::MantissaWidth::VALUE / BITS_IN_HEX_DIGIT) + 1; + (LDBits::FRACTION_LEN / BITS_IN_HEX_DIGIT) + 1; char mant_buffer[MANT_BUFF_LEN]; - size_t mant_len = (mantissa_width / BITS_IN_HEX_DIGIT) + 1; + size_t mant_len = (fraction_bits / BITS_IN_HEX_DIGIT) + 1; // Precision only tracks the number of digits after the hexadecimal point, so // we have to add one to account for the digit before the hexadecimal point. @@ -99,9 +100,9 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, const size_t shift_amount = (mant_len - intended_digits) * BITS_IN_HEX_DIGIT; - const MantissaInt truncated_bits = - mantissa & ((MantissaInt(1) << shift_amount) - 1); - const MantissaInt halfway_const = MantissaInt(1) << (shift_amount - 1); + const StorageType truncated_bits = + mantissa & ((StorageType(1) << shift_amount) - 1); + const StorageType halfway_const = StorageType(1) << (shift_amount - 1); mantissa >>= shift_amount; @@ -127,7 +128,7 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, // If the rounding caused an overflow, shift the mantissa and adjust the // exponent to match. - if (mantissa >= (MantissaInt(1) << (intended_digits * BITS_IN_HEX_DIGIT))) { + if (mantissa >= (StorageType(1) << (intended_digits * BITS_IN_HEX_DIGIT))) { mantissa >>= BITS_IN_HEX_DIGIT; exponent += BITS_IN_HEX_DIGIT; } @@ -157,8 +158,7 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, // 15 -> 5 // 11 -> 4 // 8 -> 3 - constexpr size_t EXP_LEN = - (((fputil::ExponentWidth::VALUE * 5) + 15) / 16) + 1; + constexpr size_t EXP_LEN = (((LDBits::EXP_LEN * 5) + 15) / 16) + 1; char exp_buffer[EXP_LEN]; bool exp_is_negative = false; diff --git a/libc/src/stdio/printf_core/float_inf_nan_converter.h b/libc/src/stdio/printf_core/float_inf_nan_converter.h index 27a034cdcab1b72523c3a4663b9c06da2474ebd8..a0310dc88b5604984ec973582d082d0ebe99420f 100644 --- a/libc/src/stdio/printf_core/float_inf_nan_converter.h +++ b/libc/src/stdio/printf_core/float_inf_nan_converter.h @@ -21,7 +21,7 @@ namespace LIBC_NAMESPACE { namespace printf_core { -using MantissaInt = fputil::FPBits::UIntType; +using StorageType = fputil::FPBits::StorageType; LIBC_INLINE int convert_inf_nan(Writer *writer, const FormatSection &to_conv) { // All of the letters will be defined relative to variable a, which will be @@ -29,15 +29,15 @@ LIBC_INLINE int convert_inf_nan(Writer *writer, const FormatSection &to_conv) { const char a = (to_conv.conv_name & 32) | 'A'; bool is_negative; - MantissaInt mantissa; + StorageType mantissa; if (to_conv.length_modifier == LengthModifier::L) { - fputil::FPBits::UIntType float_raw = to_conv.conv_val_raw; + fputil::FPBits::StorageType float_raw = to_conv.conv_val_raw; fputil::FPBits float_bits(float_raw); is_negative = float_bits.get_sign(); mantissa = float_bits.get_mantissa(); } else { - fputil::FPBits::UIntType float_raw = - static_cast::UIntType>(to_conv.conv_val_raw); + fputil::FPBits::StorageType float_raw = + static_cast::StorageType>(to_conv.conv_val_raw); fputil::FPBits float_bits(float_raw); is_negative = float_bits.get_sign(); mantissa = float_bits.get_mantissa(); diff --git a/libc/src/stdio/printf_core/parser.h b/libc/src/stdio/printf_core/parser.h index 7cf87dd6e17d1989f23ab2389a1add2861a70791..f1994517e1ab1c1f0de3137eb604f8b0559a1fcd 100644 --- a/libc/src/stdio/printf_core/parser.h +++ b/libc/src/stdio/printf_core/parser.h @@ -26,10 +26,10 @@ template struct int_type_of { using type = T; }; template <> struct int_type_of { - using type = fputil::FPBits::UIntType; + using type = fputil::FPBits::StorageType; }; template <> struct int_type_of { - using type = fputil::FPBits::UIntType; + using type = fputil::FPBits::StorageType; }; template using int_type_of_v = typename int_type_of::type; diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt index c54d32eb7afdb1adf07630323f32f2c9a52838f4..a4d51fb9a11eef19d5fe512b552b8ccfd63516e1 100644 --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -268,18 +268,27 @@ if(LLVM_LIBC_INCLUDE_SCUDO) set(SCUDO_DEPS "") include(${LIBC_SOURCE_DIR}/../compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake) - if(NOT (LIBC_TARGET_ARCHITECTURE IN_LIST ALL_SCUDO_STANDALONE_SUPPORTED_ARCH)) - message(FATAL_ERROR "Architecture ${LIBC_TARGET_ARCHITECTURE} is not supported by SCUDO. + + # scudo distinguishes riscv32 and riscv64, so we need to translate the architecture + set(LIBC_TARGET_ARCHITECTURE_FOR_SCUDO ${LIBC_TARGET_ARCHITECTURE}) + if(LIBC_TARGET_ARCHITECTURE_IS_RISCV64) + set(LIBC_TARGET_ARCHITECTURE_FOR_SCUDO riscv64) + elseif(LIBC_TARGET_ARCHITECTURE_IS_RISCV32) + set(LIBC_TARGET_ARCHITECTURE_FOR_SCUDO riscv32) + endif() + + if(NOT (LIBC_TARGET_ARCHITECTURE_FOR_SCUDO IN_LIST ALL_SCUDO_STANDALONE_SUPPORTED_ARCH)) + message(FATAL_ERROR "Architecture ${LIBC_TARGET_ARCHITECTURE_FOR_SCUDO} is not supported by SCUDO. Either disable LLVM_LIBC_INCLUDE_SCUDO or change your target architecture.") endif() - list(APPEND SCUDO_DEPS RTScudoStandalone.${LIBC_TARGET_ARCHITECTURE} - RTScudoStandaloneCWrappers.${LIBC_TARGET_ARCHITECTURE}) + list(APPEND SCUDO_DEPS RTScudoStandalone.${LIBC_TARGET_ARCHITECTURE_FOR_SCUDO} + RTScudoStandaloneCWrappers.${LIBC_TARGET_ARCHITECTURE_FOR_SCUDO}) list(APPEND SCUDO_DEPS - RTGwpAsan.${LIBC_TARGET_ARCHITECTURE} - RTGwpAsanBacktraceLibc.${LIBC_TARGET_ARCHITECTURE} - RTGwpAsanSegvHandler.${LIBC_TARGET_ARCHITECTURE} + RTGwpAsan.${LIBC_TARGET_ARCHITECTURE_FOR_SCUDO} + RTGwpAsanBacktraceLibc.${LIBC_TARGET_ARCHITECTURE_FOR_SCUDO} + RTGwpAsanSegvHandler.${LIBC_TARGET_ARCHITECTURE_FOR_SCUDO} ) add_entrypoint_external( diff --git a/libc/src/sys/socket/CMakeLists.txt b/libc/src/sys/socket/CMakeLists.txt index 7079d6e4466c68311a088ea70bb8504687a22ce7..e0bc48735a031465093ed511cdc5d4c0cc23e964 100644 --- a/libc/src/sys/socket/CMakeLists.txt +++ b/libc/src/sys/socket/CMakeLists.txt @@ -9,3 +9,9 @@ add_entrypoint_object( .${LIBC_TARGET_OS}.socket ) +add_entrypoint_object( + bind + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.bind +) diff --git a/libc/src/sys/socket/bind.h b/libc/src/sys/socket/bind.h new file mode 100644 index 0000000000000000000000000000000000000000..62e6221bf1b2d74f6b69fca1b4f95bbab5caeba6 --- /dev/null +++ b/libc/src/sys/socket/bind.h @@ -0,0 +1,20 @@ +//===-- Implementation header for bind --------------------------*- 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_LIBC_SRC_SYS_SOCKET_BIND_H +#define LLVM_LIBC_SRC_SYS_SOCKET_BIND_H + +#include + +namespace LIBC_NAMESPACE { + +int bind(int domain, const struct sockaddr *address, socklen_t address_len); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_SYS_SOCKET_BIND_H diff --git a/libc/src/sys/socket/linux/CMakeLists.txt b/libc/src/sys/socket/linux/CMakeLists.txt index 41bcc9c9055f4769d8a68c3b125ffc80636887f9..fc9febdec2cc3c3b77213ad28dbb5b4dbe266c44 100644 --- a/libc/src/sys/socket/linux/CMakeLists.txt +++ b/libc/src/sys/socket/linux/CMakeLists.txt @@ -10,3 +10,16 @@ add_entrypoint_object( libc.src.__support.OSUtil.osutil libc.src.errno.errno ) + +add_entrypoint_object( + bind + SRCS + bind.cpp + HDRS + ../bind.h + DEPENDS + libc.include.sys_syscall + libc.include.sys_socket + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) diff --git a/libc/src/sys/socket/linux/bind.cpp b/libc/src/sys/socket/linux/bind.cpp new file mode 100644 index 0000000000000000000000000000000000000000..36afc646d29f6d0f10de6074b1073ac4b0e9ed4c --- /dev/null +++ b/libc/src/sys/socket/linux/bind.cpp @@ -0,0 +1,43 @@ +//===-- Linux implementation of bind --------------------------------------===// +// +// 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 "src/sys/socket/bind.h" + +#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" + +#include "src/errno/libc_errno.h" + +#include // For SYS_SOCKET socketcall number. +#include // For syscall numbers. + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, bind, + (int domain, const struct sockaddr *address, + socklen_t address_len)) { +#ifdef SYS_socket + int ret = + LIBC_NAMESPACE::syscall_impl(SYS_bind, domain, address, address_len); +#elif defined(SYS_socketcall) + unsigned long sockcall_args[3] = {static_cast(domain), + reinterpret_cast(address), + static_cast(address_len)}; + int ret = LIBC_NAMESPACE::syscall_impl(SYS_socketcall, SYS_BIND, + sockcall_args); +#else +#error "socket and socketcall syscalls unavailable for this platform." +#endif + if (ret < 0) { + libc_errno = -ret; + return -1; + } + return ret; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/sys/socket/linux/socket.cpp b/libc/src/sys/socket/linux/socket.cpp index 6429fd12013ea04397ff1f89b8e525e7a70fd9a5..90a7dc632e26960aab6cf24962269900c9096839 100644 --- a/libc/src/sys/socket/linux/socket.cpp +++ b/libc/src/sys/socket/linux/socket.cpp @@ -23,7 +23,9 @@ LLVM_LIBC_FUNCTION(int, socket, (int domain, int type, int protocol)) { int ret = LIBC_NAMESPACE::syscall_impl(SYS_socket, domain, type, protocol); #elif defined(SYS_socketcall) - unsigned long sockcall_args[3] = {domain, type, protocol}; + unsigned long sockcall_args[3] = {static_cast(domain), + static_cast(type), + static_cast(protocol)}; int ret = LIBC_NAMESPACE::syscall_impl(SYS_socketcall, SYS_SOCKET, sockcall_args); #else diff --git a/libc/startup/linux/aarch64/start.cpp b/libc/startup/linux/aarch64/start.cpp index b5c426866b56d74daeb02f41de8d6a62ec482a08..bc01582aeb49c70e624464ba751c6df661f4f54d 100644 --- a/libc/startup/linux/aarch64/start.cpp +++ b/libc/startup/linux/aarch64/start.cpp @@ -126,12 +126,7 @@ static void call_fini_array_callbacks() { } // namespace LIBC_NAMESPACE using LIBC_NAMESPACE::app; - -// TODO: Would be nice to use the aux entry structure from elf.h when available. -struct AuxEntry { - uint64_t type; - uint64_t value; -}; +using LIBC_NAMESPACE::AuxEntry; __attribute__((noinline)) static void do_start() { auto tid = LIBC_NAMESPACE::syscall_impl(SYS_gettid); @@ -155,9 +150,9 @@ __attribute__((noinline)) static void do_start() { // denoted by an AT_NULL entry. Elf64_Phdr *program_hdr_table = nullptr; uintptr_t program_hdr_count; - for (AuxEntry *aux_entry = reinterpret_cast(env_end_marker + 1); - aux_entry->type != AT_NULL; ++aux_entry) { - switch (aux_entry->type) { + app.auxv_ptr = reinterpret_cast(env_end_marker + 1); + for (auto *aux_entry = app.auxv_ptr; aux_entry->id != AT_NULL; ++aux_entry) { + switch (aux_entry->id) { case AT_PHDR: program_hdr_table = reinterpret_cast(aux_entry->value); break; @@ -184,7 +179,9 @@ __attribute__((noinline)) static void do_start() { app.tls.align = phdr->p_align; } - LIBC_NAMESPACE::TLSDescriptor tls; + // This descriptor has to be static since its cleanup function cannot + // capture the context. + static LIBC_NAMESPACE::TLSDescriptor tls; LIBC_NAMESPACE::init_tls(tls); if (tls.size != 0) LIBC_NAMESPACE::set_thread_ptr(tls.tp); @@ -192,7 +189,11 @@ __attribute__((noinline)) static void do_start() { LIBC_NAMESPACE::self.attrib = &LIBC_NAMESPACE::main_thread_attrib; LIBC_NAMESPACE::main_thread_attrib.atexit_callback_mgr = LIBC_NAMESPACE::internal::get_thread_atexit_callback_mgr(); - + // We register the cleanup_tls function to be the last atexit callback to be + // invoked. It will tear down the TLS. Other callbacks may depend on TLS (such + // as the stack protector canary). + LIBC_NAMESPACE::atexit( + []() { LIBC_NAMESPACE::cleanup_tls(tls.tp, tls.size); }); // We want the fini array callbacks to be run after other atexit // callbacks are run. So, we register them before running the init // array callbacks as they can potentially register their own atexit @@ -208,10 +209,6 @@ __attribute__((noinline)) static void do_start() { reinterpret_cast(app.args->argv), reinterpret_cast(env_ptr)); - // TODO: TLS cleanup should be done after all other atexit callbacks - // are run. So, register a cleanup callback for it with atexit before - // everything else. - LIBC_NAMESPACE::cleanup_tls(tls.addr, tls.size); LIBC_NAMESPACE::exit(retval); } diff --git a/libc/startup/linux/riscv/start.cpp b/libc/startup/linux/riscv/start.cpp index bf04be5ad14ad1d747a57c1904d392d1260a98f6..5b6e5bde8da81d20c237d739f43af59e3b8241dc 100644 --- a/libc/startup/linux/riscv/start.cpp +++ b/libc/startup/linux/riscv/start.cpp @@ -115,12 +115,7 @@ static void call_fini_array_callbacks() { } // namespace LIBC_NAMESPACE using LIBC_NAMESPACE::app; - -// TODO: Would be nice to use the aux entry structure from elf.h when available. -struct AuxEntry { - LIBC_NAMESPACE::AuxEntryType type; - LIBC_NAMESPACE::AuxEntryType value; -}; +using LIBC_NAMESPACE::AuxEntry; #if defined(LIBC_TARGET_ARCH_IS_X86_64) || \ defined(LIBC_TARGET_ARCH_IS_AARCH64) || \ @@ -158,9 +153,9 @@ __attribute__((noinline)) static void do_start() { // denoted by an AT_NULL entry. PgrHdrTableType *program_hdr_table = nullptr; uintptr_t program_hdr_count; - for (AuxEntry *aux_entry = reinterpret_cast(env_end_marker + 1); - aux_entry->type != AT_NULL; ++aux_entry) { - switch (aux_entry->type) { + app.auxv_ptr = reinterpret_cast(env_end_marker + 1); + for (auto *aux_entry = app.auxv_ptr; aux_entry->id != AT_NULL; ++aux_entry) { + switch (aux_entry->id) { case AT_PHDR: program_hdr_table = reinterpret_cast(aux_entry->value); break; @@ -187,7 +182,9 @@ __attribute__((noinline)) static void do_start() { app.tls.align = phdr->p_align; } - LIBC_NAMESPACE::TLSDescriptor tls; + // This descriptor has to be static since its cleanup function cannot + // capture the context. + static LIBC_NAMESPACE::TLSDescriptor tls; LIBC_NAMESPACE::init_tls(tls); if (tls.size != 0) LIBC_NAMESPACE::set_thread_ptr(tls.tp); @@ -195,7 +192,11 @@ __attribute__((noinline)) static void do_start() { LIBC_NAMESPACE::self.attrib = &LIBC_NAMESPACE::main_thread_attrib; LIBC_NAMESPACE::main_thread_attrib.atexit_callback_mgr = LIBC_NAMESPACE::internal::get_thread_atexit_callback_mgr(); - + // We register the cleanup_tls function to be the last atexit callback to be + // invoked. It will tear down the TLS. Other callbacks may depend on TLS (such + // as the stack protector canary). + LIBC_NAMESPACE::atexit( + []() { LIBC_NAMESPACE::cleanup_tls(tls.tp, tls.size); }); // We want the fini array callbacks to be run after other atexit // callbacks are run. So, we register them before running the init // array callbacks as they can potentially register their own atexit @@ -211,10 +212,6 @@ __attribute__((noinline)) static void do_start() { reinterpret_cast(app.args->argv), reinterpret_cast(env_ptr)); - // TODO: TLS cleanup should be done after all other atexit callbacks - // are run. So, register a cleanup callback for it with atexit before - // everything else. - LIBC_NAMESPACE::cleanup_tls(tls.addr, tls.size); LIBC_NAMESPACE::exit(retval); } diff --git a/libc/startup/linux/x86_64/CMakeLists.txt b/libc/startup/linux/x86_64/CMakeLists.txt index 076c0c3e444f565e0fd0544965c54eaeeff9a8a3..aac5a0626a176a4dc3f99c0a7ea7e056e4ebd6af 100644 --- a/libc/startup/linux/x86_64/CMakeLists.txt +++ b/libc/startup/linux/x86_64/CMakeLists.txt @@ -15,6 +15,7 @@ add_startup_object( libc.src.string.memory_utils.inline_memcpy libc.src.unistd.environ COMPILE_OPTIONS + -fno-stack-protector -fno-omit-frame-pointer -ffreestanding # To avoid compiler warnings about calling the main function. -fno-builtin diff --git a/libc/startup/linux/x86_64/start.cpp b/libc/startup/linux/x86_64/start.cpp index bc1b4f0487f316a2a920ac65984007873c204445..c98f58a4ac0aff3e2a62b51a7f97de99c622cd7c 100644 --- a/libc/startup/linux/x86_64/start.cpp +++ b/libc/startup/linux/x86_64/start.cpp @@ -144,12 +144,7 @@ static void call_fini_array_callbacks() { } // namespace LIBC_NAMESPACE using LIBC_NAMESPACE::app; - -// TODO: Would be nice to use the aux entry structure from elf.h when available. -struct AuxEntry { - uint64_t type; - uint64_t value; -}; +using LIBC_NAMESPACE::AuxEntry; extern "C" void _start() { // This TU is compiled with -fno-omit-frame-pointer. Hence, the previous value @@ -193,9 +188,9 @@ extern "C" void _start() { // denoted by an AT_NULL entry. Elf64_Phdr *program_hdr_table = nullptr; uintptr_t program_hdr_count = 0; - for (AuxEntry *aux_entry = reinterpret_cast(env_end_marker + 1); - aux_entry->type != AT_NULL; ++aux_entry) { - switch (aux_entry->type) { + app.auxv_ptr = reinterpret_cast(env_end_marker + 1); + for (auto *aux_entry = app.auxv_ptr; aux_entry->id != AT_NULL; ++aux_entry) { + switch (aux_entry->id) { case AT_PHDR: program_hdr_table = reinterpret_cast(aux_entry->value); break; @@ -222,7 +217,9 @@ extern "C" void _start() { app.tls.align = phdr->p_align; } - LIBC_NAMESPACE::TLSDescriptor tls; + // This descriptor has to be static since its cleanup function cannot + // capture the context. + static LIBC_NAMESPACE::TLSDescriptor tls; LIBC_NAMESPACE::init_tls(tls); if (tls.size != 0 && !LIBC_NAMESPACE::set_thread_ptr(tls.tp)) LIBC_NAMESPACE::syscall_impl(SYS_exit, 1); @@ -230,7 +227,11 @@ extern "C" void _start() { LIBC_NAMESPACE::self.attrib = &LIBC_NAMESPACE::main_thread_attrib; LIBC_NAMESPACE::main_thread_attrib.atexit_callback_mgr = LIBC_NAMESPACE::internal::get_thread_atexit_callback_mgr(); - + // We register the cleanup_tls function to be the last atexit callback to be + // invoked. It will tear down the TLS. Other callbacks may depend on TLS (such + // as the stack protector canary). + LIBC_NAMESPACE::atexit( + []() { LIBC_NAMESPACE::cleanup_tls(tls.tp, tls.size); }); // We want the fini array callbacks to be run after other atexit // callbacks are run. So, we register them before running the init // array callbacks as they can potentially register their own atexit @@ -246,9 +247,5 @@ extern "C" void _start() { reinterpret_cast(app.args->argv), reinterpret_cast(env_ptr)); - // TODO: TLS cleanup should be done after all other atexit callbacks - // are run. So, register a cleanup callback for it with atexit before - // everything else. - LIBC_NAMESPACE::cleanup_tls(tls.addr, tls.size); LIBC_NAMESPACE::exit(retval); } diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h index 90bda0067d0476bceae8dbf409fc3f3d9f9909ca..003de7eb72ac8ed0a7c8d747623e11f258563c33 100644 --- a/libc/test/UnitTest/FPMatcher.h +++ b/libc/test/UnitTest/FPMatcher.h @@ -9,6 +9,7 @@ #ifndef LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H #define LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H +#include "src/__support/CPP/type_traits.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/fpbits_str.h" @@ -61,7 +62,9 @@ template FPMatcher getMatcher(T expectedValue) { template struct FPTest : public Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; + static constexpr StorageType STORAGE_MAX = + LIBC_NAMESPACE::cpp::numeric_limits::max(); static constexpr T zero = FPBits::zero(); static constexpr T neg_zero = FPBits::neg_zero(); static constexpr T aNaN = FPBits::build_quiet_nan(1); @@ -87,7 +90,9 @@ template struct FPTest : public Test { #define DECLARE_SPECIAL_CONSTANTS(T) \ using FPBits = LIBC_NAMESPACE::fputil::FPBits; \ - using UIntType = typename FPBits::UIntType; \ + using StorageType = typename FPBits::StorageType; \ + static constexpr StorageType STORAGE_MAX = \ + LIBC_NAMESPACE::cpp::numeric_limits::max(); \ const T zero = FPBits::zero(); \ const T neg_zero = FPBits::neg_zero(); \ const T aNaN = FPBits::build_quiet_nan(1); \ diff --git a/libc/test/UnitTest/PrintfMatcher.cpp b/libc/test/UnitTest/PrintfMatcher.cpp index e895da2be120f8cfba96b1f1f18512d6cc9afecc..32f3be73307e3a54dde5850d4c4a224c30adc899 100644 --- a/libc/test/UnitTest/PrintfMatcher.cpp +++ b/libc/test/UnitTest/PrintfMatcher.cpp @@ -77,7 +77,7 @@ static void display(FormatSection form) { << "\n"; else if (form.conv_name != '%') tlog << "\tvalue: " - << int_to_hex::UIntType>( + << int_to_hex::StorageType>( form.conv_val_raw) << "\n"; } diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt index 740209bc83d75e1392e5a1920a7811a5bb03fdec..fe8b3c4c84c388411083b64e067af493c055069f 100644 --- a/libc/test/src/__support/CMakeLists.txt +++ b/libc/test/src/__support/CMakeLists.txt @@ -50,6 +50,8 @@ add_libc_test( libc-support-tests SRCS str_to_float_test.cpp + str_to_double_test.cpp + str_to_long_double_test.cpp DEPENDS libc.src.__support.str_to_float libc.src.__support.uint128 diff --git a/libc/test/src/__support/str_to_double_test.cpp b/libc/test/src/__support/str_to_double_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b66935f0988e0567c9238d3c134d085cdcbaefdc --- /dev/null +++ b/libc/test/src/__support/str_to_double_test.cpp @@ -0,0 +1,105 @@ +#include "str_to_fp_test.h" + +namespace LIBC_NAMESPACE { +using LlvmLibcStrToDblTest = LlvmLibcStrToFloatTest; + +TEST_F(LlvmLibcStrToDblTest, ClingerFastPathFloat64Simple) { + clinger_fast_path_test(123, 0, 0xEC00000000000, 1029); + clinger_fast_path_test(1234567890123456, 1, 0x5ee2a2eb5a5c0, 1076); + clinger_fast_path_test(1234567890, -10, 0xf9add3739635f, 1019); +} + +TEST_F(LlvmLibcStrToDblTest, ClingerFastPathFloat64ExtendedExp) { + clinger_fast_path_test(1, 30, 0x93e5939a08cea, 1122); + clinger_fast_path_test(1, 37, 0xe17b84357691b, 1145); + clinger_fast_path_fails_test(10, 37); + clinger_fast_path_fails_test(1, 100); +} + +TEST_F(LlvmLibcStrToDblTest, ClingerFastPathFloat64NegativeExp) { + clinger_fast_path_test(1, -10, 0xb7cdfd9d7bdbb, 989); + clinger_fast_path_test(1, -20, 0x79ca10c924223, 956); + clinger_fast_path_fails_test(1, -25); +} + +TEST_F(LlvmLibcStrToDblTest, EiselLemireFloat64Simple) { + eisel_lemire_test(12345678901234567890u, 1, 0x1AC53A7E04BCDA, 1089); + eisel_lemire_test(123, 0, 0x1EC00000000000, 1029); + eisel_lemire_test(12345678901234568192u, 0, 0x156A95319D63E2, 1086); +} + +TEST_F(LlvmLibcStrToDblTest, EiselLemireFloat64SpecificFailures) { + // These test cases have caused failures in the past. + eisel_lemire_test(358416272, -33, 0x1BBB2A68C9D0B9, 941); + eisel_lemire_test(2166568064000000238u, -9, 0x10246690000000, 1054); + eisel_lemire_test(2794967654709307187u, 1, 0x183e132bc608c8, 1087); + eisel_lemire_test(2794967654709307188u, 1, 0x183e132bc608c9, 1087); +} + +// Check the fallback states for the algorithm: +TEST_F(LlvmLibcStrToDblTest, EiselLemireFallbackStates) { + // This number can't be evaluated by Eisel-Lemire since it's exactly 1024 away + // from both of its closest floating point approximations + // (12345678901234548736 and 12345678901234550784) + ASSERT_FALSE( + internal::eisel_lemire({12345678901234549760u, 0}).has_value()); +} + +TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicWholeNumbers) { + simple_decimal_conversion_test("123456789012345678900", 0x1AC53A7E04BCDA, + 1089); + simple_decimal_conversion_test("123", 0x1EC00000000000, 1029); + simple_decimal_conversion_test("12345678901234549760", 0x156A95319D63D8, + 1086); +} + +TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicDecimals) { + simple_decimal_conversion_test("1.2345", 0x13c083126e978d, 1023); + simple_decimal_conversion_test(".2345", 0x1e04189374bc6a, 1020); + simple_decimal_conversion_test(".299792458", 0x132fccb4aca314, 1021); +} + +TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicExponents) { + simple_decimal_conversion_test("1e10", 0x12a05f20000000, 1056); + simple_decimal_conversion_test("1e-10", 0x1b7cdfd9d7bdbb, 989); + simple_decimal_conversion_test("1e300", 0x17e43c8800759c, 2019); + simple_decimal_conversion_test("1e-300", 0x156e1fc2f8f359, 26); +} + +TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64BasicSubnormals) { + simple_decimal_conversion_test("1e-320", 0x7e8, 0, ERANGE); + simple_decimal_conversion_test("1e-308", 0x730d67819e8d2, 0, ERANGE); + simple_decimal_conversion_test("2.9e-308", 0x14da6df5e4bcc8, 1); +} + +TEST_F(LlvmLibcStrToDblTest, SimpleDecimalConversion64SubnormalRounding) { + + // Technically you can keep adding digits until you hit the truncation limit, + // but this is the shortest string that results in the maximum subnormal that + // I found. + simple_decimal_conversion_test("2.225073858507201e-308", 0xfffffffffffff, 0, + ERANGE); + + // Same here, if you were to extend the max subnormal out for another 800 + // digits, incrementing any one of those digits would create a normal number. + simple_decimal_conversion_test("2.2250738585072012e-308", 0x10000000000000, + 1); +} + +TEST(LlvmLibcStrToDblTest, SimpleDecimalConversionExtraTypes) { + uint64_t double_output_mantissa = 0; + uint32_t output_exp2 = 0; + + libc_errno = 0; + auto double_result = + internal::simple_decimal_conversion("123456789012345678900"); + + double_output_mantissa = double_result.num.mantissa; + output_exp2 = double_result.num.exponent; + + EXPECT_EQ(double_output_mantissa, uint64_t(0x1AC53A7E04BCDA)); + EXPECT_EQ(output_exp2, uint32_t(1089)); + EXPECT_EQ(double_result.error, 0); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/test/src/__support/str_to_float_test.cpp b/libc/test/src/__support/str_to_float_test.cpp index 35f7318fb9c78df71f1fb3f591533f5d20b63e51..3102fa7aa91ec18a67ea0b3be8c9d1f4b01edc94 100644 --- a/libc/test/src/__support/str_to_float_test.cpp +++ b/libc/test/src/__support/str_to_float_test.cpp @@ -1,321 +1,59 @@ -//===-- Unittests for str_to_float ----------------------------------------===// -// -// 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 "str_to_fp_test.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/UInt128.h" -#include "src/__support/str_to_float.h" -#include "src/errno/libc_errno.h" +namespace LIBC_NAMESPACE { -#include "test/UnitTest/Test.h" +using LlvmLibcStrToFltTest = LlvmLibcStrToFloatTest; -class LlvmLibcStrToFloatTest : public LIBC_NAMESPACE::testing::Test { -public: - template - void clinger_fast_path_test( - const typename LIBC_NAMESPACE::fputil::FPBits::UIntType inputMantissa, - const int32_t inputExp10, - const typename LIBC_NAMESPACE::fputil::FPBits::UIntType - expectedOutputMantissa, - const uint32_t expectedOutputExp2) { - typename LIBC_NAMESPACE::fputil::FPBits::UIntType - actual_output_mantissa = 0; - uint32_t actual_output_exp2 = 0; - - auto result = LIBC_NAMESPACE::internal::clinger_fast_path( - {inputMantissa, inputExp10}); - - ASSERT_TRUE(result.has_value()); - - actual_output_mantissa = result->mantissa; - actual_output_exp2 = result->exponent; - - EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa); - EXPECT_EQ(actual_output_exp2, expectedOutputExp2); - } - - template - void clinger_fast_path_fails_test( - const typename LIBC_NAMESPACE::fputil::FPBits::UIntType inputMantissa, - const int32_t inputExp10) { - ASSERT_FALSE(LIBC_NAMESPACE::internal::clinger_fast_path( - {inputMantissa, inputExp10}) - .has_value()); - } - - template - void eisel_lemire_test( - const typename LIBC_NAMESPACE::fputil::FPBits::UIntType inputMantissa, - const int32_t inputExp10, - const typename LIBC_NAMESPACE::fputil::FPBits::UIntType - expectedOutputMantissa, - const uint32_t expectedOutputExp2) { - typename LIBC_NAMESPACE::fputil::FPBits::UIntType - actual_output_mantissa = 0; - uint32_t actual_output_exp2 = 0; - - auto result = - LIBC_NAMESPACE::internal::eisel_lemire({inputMantissa, inputExp10}); - - ASSERT_TRUE(result.has_value()); - - actual_output_mantissa = result->mantissa; - actual_output_exp2 = result->exponent; - - EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa); - EXPECT_EQ(actual_output_exp2, expectedOutputExp2); - } - - template - void simple_decimal_conversion_test( - const char *__restrict numStart, - const typename LIBC_NAMESPACE::fputil::FPBits::UIntType - expectedOutputMantissa, - const uint32_t expectedOutputExp2, const int expectedErrno = 0) { - typename LIBC_NAMESPACE::fputil::FPBits::UIntType - actual_output_mantissa = 0; - uint32_t actual_output_exp2 = 0; - libc_errno = 0; - - auto result = - LIBC_NAMESPACE::internal::simple_decimal_conversion(numStart); - - actual_output_mantissa = result.num.mantissa; - actual_output_exp2 = result.num.exponent; - - EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa); - EXPECT_EQ(actual_output_exp2, expectedOutputExp2); - EXPECT_EQ(result.error, expectedErrno); - } -}; - -TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat64Simple) { - clinger_fast_path_test(123, 0, 0xEC00000000000, 1029); - clinger_fast_path_test(1234567890123456, 1, 0x5ee2a2eb5a5c0, 1076); - clinger_fast_path_test(1234567890, -10, 0xf9add3739635f, 1019); +TEST_F(LlvmLibcStrToFltTest, ClingerFastPathFloat32Simple) { + clinger_fast_path_test(123, 0, 0x760000, 133); + clinger_fast_path_test(1234567, 1, 0x3c6146, 150); + clinger_fast_path_test(12345, -5, 0x7cd35b, 123); } -TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat64ExtendedExp) { - clinger_fast_path_test(1, 30, 0x93e5939a08cea, 1122); - clinger_fast_path_test(1, 37, 0xe17b84357691b, 1145); - clinger_fast_path_fails_test(10, 37); - clinger_fast_path_fails_test(1, 100); +TEST_F(LlvmLibcStrToFltTest, ClingerFastPathFloat32ExtendedExp) { + clinger_fast_path_test(1, 15, 0x635fa9, 176); + clinger_fast_path_test(1, 17, 0x31a2bc, 183); + clinger_fast_path_fails_test(10, 17); + clinger_fast_path_fails_test(1, 50); } -TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat64NegativeExp) { - clinger_fast_path_test(1, -10, 0xb7cdfd9d7bdbb, 989); - clinger_fast_path_test(1, -20, 0x79ca10c924223, 956); - clinger_fast_path_fails_test(1, -25); -} - -TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat32Simple) { - clinger_fast_path_test(123, 0, 0x760000, 133); - clinger_fast_path_test(1234567, 1, 0x3c6146, 150); - clinger_fast_path_test(12345, -5, 0x7cd35b, 123); -} - -TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat32ExtendedExp) { - clinger_fast_path_test(1, 15, 0x635fa9, 176); - clinger_fast_path_test(1, 17, 0x31a2bc, 183); - clinger_fast_path_fails_test(10, 17); - clinger_fast_path_fails_test(1, 50); -} - -TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat32NegativeExp) { - clinger_fast_path_test(1, -5, 0x27c5ac, 110); - clinger_fast_path_test(1, -10, 0x5be6ff, 93); - clinger_fast_path_fails_test(1, -15); -} - -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat64Simple) { - eisel_lemire_test(12345678901234567890u, 1, 0x1AC53A7E04BCDA, 1089); - eisel_lemire_test(123, 0, 0x1EC00000000000, 1029); - eisel_lemire_test(12345678901234568192u, 0, 0x156A95319D63E2, 1086); -} - -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat64SpecificFailures) { - // These test cases have caused failures in the past. - eisel_lemire_test(358416272, -33, 0x1BBB2A68C9D0B9, 941); - eisel_lemire_test(2166568064000000238u, -9, 0x10246690000000, 1054); - eisel_lemire_test(2794967654709307187u, 1, 0x183e132bc608c8, 1087); - eisel_lemire_test(2794967654709307188u, 1, 0x183e132bc608c9, 1087); +TEST_F(LlvmLibcStrToFltTest, ClingerFastPathFloat32NegativeExp) { + clinger_fast_path_test(1, -5, 0x27c5ac, 110); + clinger_fast_path_test(1, -10, 0x5be6ff, 93); + clinger_fast_path_fails_test(1, -15); } // Check the fallback states for the algorithm: -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFallbackStates) { +TEST_F(LlvmLibcStrToFltTest, EiselLemireFallbackStates) { // This number can't be evaluated by Eisel-Lemire since it's exactly 1024 away // from both of its closest floating point approximations // (12345678901234548736 and 12345678901234550784) - ASSERT_FALSE( - LIBC_NAMESPACE::internal::eisel_lemire({12345678901234549760u, 0}) - .has_value()); - - ASSERT_FALSE( - LIBC_NAMESPACE::internal::eisel_lemire({20040229, 0}).has_value()); + ASSERT_FALSE(internal::eisel_lemire({20040229, 0}).has_value()); } -TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicWholeNumbers) { - simple_decimal_conversion_test("123456789012345678900", - 0x1AC53A7E04BCDA, 1089); - simple_decimal_conversion_test("123", 0x1EC00000000000, 1029); - simple_decimal_conversion_test("12345678901234549760", - 0x156A95319D63D8, 1086); -} - -TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicDecimals) { - simple_decimal_conversion_test("1.2345", 0x13c083126e978d, 1023); - simple_decimal_conversion_test(".2345", 0x1e04189374bc6a, 1020); - simple_decimal_conversion_test(".299792458", 0x132fccb4aca314, 1021); -} - -TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicExponents) { - simple_decimal_conversion_test("1e10", 0x12a05f20000000, 1056); - simple_decimal_conversion_test("1e-10", 0x1b7cdfd9d7bdbb, 989); - simple_decimal_conversion_test("1e300", 0x17e43c8800759c, 2019); - simple_decimal_conversion_test("1e-300", 0x156e1fc2f8f359, 26); -} - -TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicSubnormals) { - simple_decimal_conversion_test("1e-320", 0x7e8, 0, ERANGE); - simple_decimal_conversion_test("1e-308", 0x730d67819e8d2, 0, ERANGE); - simple_decimal_conversion_test("2.9e-308", 0x14da6df5e4bcc8, 1); -} - -TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64SubnormalRounding) { - - // Technically you can keep adding digits until you hit the truncation limit, - // but this is the shortest string that results in the maximum subnormal that - // I found. - simple_decimal_conversion_test("2.225073858507201e-308", - 0xfffffffffffff, 0, ERANGE); - - // Same here, if you were to extend the max subnormal out for another 800 - // digits, incrementing any one of those digits would create a normal number. - simple_decimal_conversion_test("2.2250738585072012e-308", - 0x10000000000000, 1); -} - -TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion32SpecificFailures) { - simple_decimal_conversion_test( +TEST_F(LlvmLibcStrToFltTest, SimpleDecimalConversion32SpecificFailures) { + simple_decimal_conversion_test( "1.4012984643248170709237295832899161312802619418765e-45", 0x1, 0, ERANGE); - simple_decimal_conversion_test( + simple_decimal_conversion_test( "7." "006492321624085354618647916449580656401309709382578858785341419448955413" "42930300743319094181060791015625e-46", 0x0, 0, ERANGE); } -TEST(LlvmLibcStrToFloatTest, SimpleDecimalConversionExtraTypes) { +TEST(LlvmLibcStrToFltTest, SimpleDecimalConversionExtraTypes) { uint32_t float_output_mantissa = 0; uint32_t output_exp2 = 0; libc_errno = 0; auto float_result = - LIBC_NAMESPACE::internal::simple_decimal_conversion( - "123456789012345678900"); + internal::simple_decimal_conversion("123456789012345678900"); float_output_mantissa = float_result.num.mantissa; output_exp2 = float_result.num.exponent; EXPECT_EQ(float_output_mantissa, uint32_t(0xd629d4)); EXPECT_EQ(output_exp2, uint32_t(193)); EXPECT_EQ(float_result.error, 0); - - uint64_t double_output_mantissa = 0; - output_exp2 = 0; - - libc_errno = 0; - auto double_result = - LIBC_NAMESPACE::internal::simple_decimal_conversion( - "123456789012345678900"); - - double_output_mantissa = double_result.num.mantissa; - output_exp2 = double_result.num.exponent; - - EXPECT_EQ(double_output_mantissa, uint64_t(0x1AC53A7E04BCDA)); - EXPECT_EQ(output_exp2, uint32_t(1089)); - EXPECT_EQ(double_result.error, 0); } -#if defined(LIBC_LONG_DOUBLE_IS_FLOAT64) -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat64AsLongDouble) { - eisel_lemire_test(123, 0, 0x1EC00000000000, 1029); -} -#elif defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80) -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80Simple) { - eisel_lemire_test(123, 0, 0xf600000000000000, 16389); - eisel_lemire_test(12345678901234568192u, 0, 0xab54a98ceb1f0c00, - 16446); -} - -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80LongerMantissa) { - eisel_lemire_test((UInt128(0x1234567812345678) << 64) + - UInt128(0x1234567812345678), - 0, 0x91a2b3c091a2b3c1, 16507); - eisel_lemire_test((UInt128(0x1234567812345678) << 64) + - UInt128(0x1234567812345678), - 300, 0xd97757de56adb65c, 17503); - eisel_lemire_test((UInt128(0x1234567812345678) << 64) + - UInt128(0x1234567812345678), - -300, 0xc30feb9a7618457d, 15510); -} - -// These tests check numbers at the edge of the DETAILED_POWERS_OF_TEN table. -// This doesn't reach very far into the range for long doubles, since it's sized -// for doubles and their 11 exponent bits, and not for long doubles and their -// 15 exponent bits. This is a known tradeoff, and was made because a proper -// long double table would be approximately 16 times longer (specifically the -// maximum exponent would need to be about 5000, leading to a 10,000 entry -// table). This would have significant memory and storage costs all the time to -// speed up a relatively uncommon path. -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80TableLimits) { - eisel_lemire_test(1, 347, 0xd13eb46469447567, 17535); - eisel_lemire_test(1, -348, 0xfa8fd5a0081c0288, 15226); -} - -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80Fallback) { - // This number is halfway between two possible results, and the algorithm - // can't determine which is correct. - ASSERT_FALSE(LIBC_NAMESPACE::internal::eisel_lemire( - {12345678901234567890u, 1}) - .has_value()); - - // These numbers' exponents are out of range for the current powers of ten - // table. - ASSERT_FALSE(LIBC_NAMESPACE::internal::eisel_lemire({1, 1000}) - .has_value()); - ASSERT_FALSE(LIBC_NAMESPACE::internal::eisel_lemire({1, -1000}) - .has_value()); -} -#else // Quad precision long double -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat128Simple) { - eisel_lemire_test(123, 0, (UInt128(0x1ec0000000000) << 64), - 16389); - eisel_lemire_test( - 12345678901234568192u, 0, - (UInt128(0x156a95319d63e) << 64) + UInt128(0x1800000000000000), 16446); -} - -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat128LongerMantissa) { - eisel_lemire_test( - (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), 0, - (UInt128(0x1234567812345) << 64) + UInt128(0x6781234567812345), 16507); - eisel_lemire_test( - (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), 300, - (UInt128(0x1b2eeafbcad5b) << 64) + UInt128(0x6cb8b4451dfcde19), 17503); - eisel_lemire_test( - (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), -300, - (UInt128(0x1861fd734ec30) << 64) + UInt128(0x8afa7189f0f7595f), 15510); -} - -TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat128Fallback) { - ASSERT_FALSE( - LIBC_NAMESPACE::internal::eisel_lemire( - {(UInt128(0x5ce0e9a56015fec5) << 64) + UInt128(0xaadfa328ae39b333), - 1}) - .has_value()); -} -#endif +} // namespace LIBC_NAMESPACE diff --git a/libc/test/src/__support/str_to_fp_test.h b/libc/test/src/__support/str_to_fp_test.h new file mode 100644 index 0000000000000000000000000000000000000000..1e7343f865b7d731d609a5d14f635181955c549e --- /dev/null +++ b/libc/test/src/__support/str_to_fp_test.h @@ -0,0 +1,82 @@ +//===-- Unittests for str_to_float ----------------------------------------===// +// +// 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 "src/__support/FPUtil/FloatProperties.h" +#include "src/__support/UInt128.h" +#include "src/__support/str_to_float.h" +#include "src/errno/libc_errno.h" + +#include "test/UnitTest/Test.h" + +namespace LIBC_NAMESPACE { + +template struct LlvmLibcStrToFloatTest : public testing::Test { + using StorageType = typename fputil::FloatProperties::StorageType; + + void clinger_fast_path_test(const StorageType inputMantissa, + const int32_t inputExp10, + const StorageType expectedOutputMantissa, + const uint32_t expectedOutputExp2) { + StorageType actual_output_mantissa = 0; + uint32_t actual_output_exp2 = 0; + + auto result = internal::clinger_fast_path({inputMantissa, inputExp10}); + + ASSERT_TRUE(result.has_value()); + + actual_output_mantissa = result->mantissa; + actual_output_exp2 = result->exponent; + + EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa); + EXPECT_EQ(actual_output_exp2, expectedOutputExp2); + } + + void clinger_fast_path_fails_test(const StorageType inputMantissa, + const int32_t inputExp10) { + ASSERT_FALSE(internal::clinger_fast_path({inputMantissa, inputExp10}) + .has_value()); + } + + void eisel_lemire_test(const StorageType inputMantissa, + const int32_t inputExp10, + const StorageType expectedOutputMantissa, + const uint32_t expectedOutputExp2) { + StorageType actual_output_mantissa = 0; + uint32_t actual_output_exp2 = 0; + + auto result = internal::eisel_lemire({inputMantissa, inputExp10}); + + ASSERT_TRUE(result.has_value()); + + actual_output_mantissa = result->mantissa; + actual_output_exp2 = result->exponent; + + EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa); + EXPECT_EQ(actual_output_exp2, expectedOutputExp2); + } + + void simple_decimal_conversion_test(const char *__restrict numStart, + const StorageType expectedOutputMantissa, + const uint32_t expectedOutputExp2, + const int expectedErrno = 0) { + StorageType actual_output_mantissa = 0; + uint32_t actual_output_exp2 = 0; + libc_errno = 0; + + auto result = internal::simple_decimal_conversion(numStart); + + actual_output_mantissa = result.num.mantissa; + actual_output_exp2 = result.num.exponent; + + EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa); + EXPECT_EQ(actual_output_exp2, expectedOutputExp2); + EXPECT_EQ(result.error, expectedErrno); + } +}; + +} // namespace LIBC_NAMESPACE diff --git a/libc/test/src/__support/str_to_long_double_test.cpp b/libc/test/src/__support/str_to_long_double_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6fefc89ac3a945be9e6c3c62f31dde73cabd68ee --- /dev/null +++ b/libc/test/src/__support/str_to_long_double_test.cpp @@ -0,0 +1,88 @@ +#include "str_to_fp_test.h" + +namespace LIBC_NAMESPACE { + +using LlvmLibcStrToLongDblTest = LlvmLibcStrToFloatTest; + +#if defined(LIBC_LONG_DOUBLE_IS_FLOAT64) + +TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat64AsLongDouble) { + eisel_lemire_test(123, 0, 0x1EC00000000000, 1029); +} + +#elif defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80) + +TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80Simple) { + eisel_lemire_test(123, 0, 0xf600000000000000, 16389); + eisel_lemire_test(12345678901234568192u, 0, 0xab54a98ceb1f0c00, 16446); +} + +TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80LongerMantissa) { + eisel_lemire_test((UInt128(0x1234567812345678) << 64) + + UInt128(0x1234567812345678), + 0, 0x91a2b3c091a2b3c1, 16507); + eisel_lemire_test((UInt128(0x1234567812345678) << 64) + + UInt128(0x1234567812345678), + 300, 0xd97757de56adb65c, 17503); + eisel_lemire_test((UInt128(0x1234567812345678) << 64) + + UInt128(0x1234567812345678), + -300, 0xc30feb9a7618457d, 15510); +} + +// These tests check numbers at the edge of the DETAILED_POWERS_OF_TEN table. +// This doesn't reach very far into the range for long doubles, since it's sized +// for doubles and their 11 exponent bits, and not for long doubles and their +// 15 exponent bits. This is a known tradeoff, and was made because a proper +// long double table would be approximately 16 times longer (specifically the +// maximum exponent would need to be about 5000, leading to a 10,000 entry +// table). This would have significant memory and storage costs all the time to +// speed up a relatively uncommon path. +TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80TableLimits) { + eisel_lemire_test(1, 347, 0xd13eb46469447567, 17535); + eisel_lemire_test(1, -348, 0xfa8fd5a0081c0288, 15226); +} + +TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat80Fallback) { + // This number is halfway between two possible results, and the algorithm + // can't determine which is correct. + ASSERT_FALSE(internal::eisel_lemire({12345678901234567890u, 1}) + .has_value()); + + // These numbers' exponents are out of range for the current powers of ten + // table. + ASSERT_FALSE(internal::eisel_lemire({1, 1000}).has_value()); + ASSERT_FALSE(internal::eisel_lemire({1, -1000}).has_value()); +} + +#else // Quad precision long double + +TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128Simple) { + eisel_lemire_test(123, 0, (UInt128(0x1ec0000000000) << 64), 16389); + eisel_lemire_test( + 12345678901234568192u, 0, + (UInt128(0x156a95319d63e) << 64) + UInt128(0x1800000000000000), 16446); +} + +TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128LongerMantissa) { + eisel_lemire_test( + (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), 0, + (UInt128(0x1234567812345) << 64) + UInt128(0x6781234567812345), 16507); + eisel_lemire_test( + (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), 300, + (UInt128(0x1b2eeafbcad5b) << 64) + UInt128(0x6cb8b4451dfcde19), 17503); + eisel_lemire_test( + (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), -300, + (UInt128(0x1861fd734ec30) << 64) + UInt128(0x8afa7189f0f7595f), 15510); +} + +TEST_F(LlvmLibcStrToLongDblTest, EiselLemireFloat128Fallback) { + ASSERT_FALSE( + internal::eisel_lemire( + {(UInt128(0x5ce0e9a56015fec5) << 64) + UInt128(0xaadfa328ae39b333), + 1}) + .has_value()); +} + +#endif + +} // namespace LIBC_NAMESPACE diff --git a/libc/test/src/fcntl/creat_test.cpp b/libc/test/src/fcntl/creat_test.cpp index ca926b30e62faf72134abfaf973d372765fafe3b..ef30d8862c45f263bdc93b9d96a10c80f503d9bd 100644 --- a/libc/test/src/fcntl/creat_test.cpp +++ b/libc/test/src/fcntl/creat_test.cpp @@ -13,6 +13,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcCreatTest, CreatAndOpen) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; constexpr const char *TEST_FILE = "testdata/creat.test"; diff --git a/libc/test/src/math/CeilTest.h b/libc/test/src/math/CeilTest.h index d1e2b2e6fd17d4f8bf9a8e7af57d60b0a6f715cd..67b33cb14110bcc898dc9370a05c1bbf0e31900f 100644 --- a/libc/test/src/math/CeilTest.h +++ b/libc/test/src/math/CeilTest.h @@ -64,9 +64,9 @@ public: } void testRange(CeilFunc func) { - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x)) continue; diff --git a/libc/test/src/math/CopySignTest.h b/libc/test/src/math/CopySignTest.h index aecd012d1d524a17a6f4436e0f5c700487b0f819..c916416a2e5b91608364aff5e6526cdef76964e9 100644 --- a/libc/test/src/math/CopySignTest.h +++ b/libc/test/src/math/CopySignTest.h @@ -34,9 +34,9 @@ public: } void testRange(CopySignFunc func) { - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x)) continue; diff --git a/libc/test/src/math/FAbsTest.h b/libc/test/src/math/FAbsTest.h index 3342926142ff1fb2e889c2689f261a63ab55010f..b2b146167e62529626f5d6e677eb7e24061f8935 100644 --- a/libc/test/src/math/FAbsTest.h +++ b/libc/test/src/math/FAbsTest.h @@ -32,9 +32,9 @@ public: } void testRange(FabsFunc func) { - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x)) continue; diff --git a/libc/test/src/math/FDimTest.h b/libc/test/src/math/FDimTest.h index 3118c3661013e7cf97101e8cdb28adba09145972..e926640abc90e0e03dcbd39e7bef0d1a5f2b952d 100644 --- a/libc/test/src/math/FDimTest.h +++ b/libc/test/src/math/FDimTest.h @@ -17,7 +17,7 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test { public: using FuncPtr = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; void test_na_n_arg(FuncPtr func) { EXPECT_FP_EQ(nan, func(nan, inf)); @@ -53,9 +53,11 @@ public: } void test_in_range(FuncPtr func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0, w = UIntType(-1); i <= COUNT; + constexpr StorageType STORAGE_MAX = + LIBC_NAMESPACE::cpp::numeric_limits::max(); + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT; ++i, v += STEP, w -= STEP) { T x = T(FPBits(v)), y = T(FPBits(w)); if (isnan(x) || isinf(x)) @@ -74,9 +76,9 @@ public: private: // constexpr does not work on FPBits yet, so we cannot have these constants as // static. - const T nan = T(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)); - const T inf = T(LIBC_NAMESPACE::fputil::FPBits::inf()); - const T neg_inf = T(LIBC_NAMESPACE::fputil::FPBits::neg_inf()); - const T zero = T(LIBC_NAMESPACE::fputil::FPBits::zero()); - const T neg_zero = T(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); + const T nan = T(FPBits::build_quiet_nan(1)); + const T inf = T(FPBits::inf()); + const T neg_inf = T(FPBits::neg_inf()); + const T zero = T(FPBits::zero()); + const T neg_zero = T(FPBits::neg_zero()); }; diff --git a/libc/test/src/math/FMaxTest.h b/libc/test/src/math/FMaxTest.h index e371086274acf7c71b8c45f451d9254775ee4e4e..1a1d2a77268d1cb87bc50978bb0920386893a317 100644 --- a/libc/test/src/math/FMaxTest.h +++ b/libc/test/src/math/FMaxTest.h @@ -55,9 +55,9 @@ public: } void testRange(FMaxFunc func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0, w = UIntType(-1); i <= COUNT; + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT; ++i, v += STEP, w -= STEP) { T x = T(FPBits(v)), y = T(FPBits(w)); if (isnan(x) || isinf(x)) diff --git a/libc/test/src/math/FMinTest.h b/libc/test/src/math/FMinTest.h index 7f8393ac2b5e91011781fc8a2e0160458a595322..742bb5cdd1021b939f04621f6f07cf38121edbc3 100644 --- a/libc/test/src/math/FMinTest.h +++ b/libc/test/src/math/FMinTest.h @@ -55,9 +55,9 @@ public: } void testRange(FMinFunc func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0, w = UIntType(-1); i <= COUNT; + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT; ++i, v += STEP, w -= STEP) { T x = T(FPBits(v)), y = T(FPBits(w)); if (isnan(x) || isinf(x)) diff --git a/libc/test/src/math/FloorTest.h b/libc/test/src/math/FloorTest.h index 843c70ba2baeb37a6ce773148083eab4780fb96d..c1b05c5d13083460fe402b94334587cb1cfdb511 100644 --- a/libc/test/src/math/FloorTest.h +++ b/libc/test/src/math/FloorTest.h @@ -64,9 +64,9 @@ public: } void testRange(FloorFunc func) { - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x)) continue; diff --git a/libc/test/src/math/FmaTest.h b/libc/test/src/math/FmaTest.h index c2573d03792692fa9d27481176c2bc96fad46dea..57eb43821c5a4e80679b0d5c7c1f9e3bc477deaa 100644 --- a/libc/test/src/math/FmaTest.h +++ b/libc/test/src/math/FmaTest.h @@ -22,16 +22,16 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test { private: using Func = T (*)(T, T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; - const T nan = T(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)); - const T inf = T(LIBC_NAMESPACE::fputil::FPBits::inf()); - const T neg_inf = T(LIBC_NAMESPACE::fputil::FPBits::neg_inf()); - const T zero = T(LIBC_NAMESPACE::fputil::FPBits::zero()); - const T neg_zero = T(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); + using StorageType = typename FPBits::StorageType; + const T nan = T(FPBits::build_quiet_nan(1)); + const T inf = T(FPBits::inf()); + const T neg_inf = T(FPBits::neg_inf()); + const T zero = T(FPBits::zero()); + const T neg_zero = T(FPBits::neg_zero()); - UIntType get_random_bit_pattern() { - UIntType bits{0}; - for (UIntType i = 0; i < sizeof(UIntType) / 2; ++i) { + StorageType get_random_bit_pattern() { + StorageType bits{0}; + for (StorageType i = 0; i < sizeof(StorageType) / 2; ++i) { bits = (bits << 2) + static_cast(LIBC_NAMESPACE::testutils::rand()); } @@ -52,9 +52,9 @@ public: // Test underflow rounding up. EXPECT_FP_EQ(func(T(0.5), T(FPBits(FPBits::MIN_SUBNORMAL)), T(FPBits(FPBits::MIN_SUBNORMAL))), - T(FPBits(UIntType(2)))); + T(FPBits(StorageType(2)))); // Test underflow rounding down. - T v = T(FPBits(FPBits::MIN_NORMAL + UIntType(1))); + T v = T(FPBits(FPBits::MIN_NORMAL + StorageType(1))); EXPECT_FP_EQ(func(T(1) / T(FPBits::MIN_NORMAL << 1), v, T(FPBits(FPBits::MIN_NORMAL))), v); @@ -67,11 +67,10 @@ public: } void test_subnormal_range(Func func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_SUBNORMAL) - UIntType(FPBits::MIN_SUBNORMAL)) / - COUNT; - for (UIntType v = FPBits::MIN_SUBNORMAL, w = FPBits::MAX_SUBNORMAL; + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = + (FPBits::MAX_SUBNORMAL - FPBits::MIN_SUBNORMAL) / COUNT; + for (StorageType v = FPBits::MIN_SUBNORMAL, w = FPBits::MAX_SUBNORMAL; v <= FPBits::MAX_SUBNORMAL && w >= FPBits::MIN_SUBNORMAL; v += STEP, w -= STEP) { T x = T(FPBits(get_random_bit_pattern())), y = T(FPBits(v)), @@ -83,10 +82,10 @@ public: } void test_normal_range(Func func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; - for (UIntType v = FPBits::MIN_NORMAL, w = FPBits::MAX_NORMAL; + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = + (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + for (StorageType v = FPBits::MIN_NORMAL, w = FPBits::MAX_NORMAL; v <= FPBits::MAX_NORMAL && w >= FPBits::MIN_NORMAL; v += STEP, w -= STEP) { T x = T(FPBits(v)), y = T(FPBits(w)), diff --git a/libc/test/src/math/FrexpTest.h b/libc/test/src/math/FrexpTest.h index 19c98872e0411671bf445d22f1dee1442ab543c6..0e66bd5804d58c598f68b2707c0203db1d61775a 100644 --- a/libc/test/src/math/FrexpTest.h +++ b/libc/test/src/math/FrexpTest.h @@ -19,8 +19,9 @@ template class FrexpTest : public LIBC_NAMESPACE::testing::Test { DECLARE_SPECIAL_CONSTANTS(T) - static constexpr UIntType HIDDEN_BIT = - UIntType(1) << LIBC_NAMESPACE::fputil::MantissaWidth::VALUE; + static constexpr StorageType HIDDEN_BIT = + StorageType(1) + << LIBC_NAMESPACE::fputil::FloatProperties::FRACTION_LEN; public: typedef T (*FrexpFunc)(T, int *); @@ -92,10 +93,10 @@ public: } void testRange(FrexpFunc func) { - using UIntType = typename FPBits::UIntType; - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + using StorageType = typename FPBits::StorageType; + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = static_cast(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0l) continue; diff --git a/libc/test/src/math/HypotTest.h b/libc/test/src/math/HypotTest.h index c01a771b9505fae054f25f09d384c87b2bfdcde3..b9567c4b4641640555fd1ebc9d09d1faad42281c 100644 --- a/libc/test/src/math/HypotTest.h +++ b/libc/test/src/math/HypotTest.h @@ -23,7 +23,7 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test { private: using Func = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; const T nan = T(FPBits::build_quiet_nan(1)); const T inf = T(FPBits::inf()); const T neg_inf = T(FPBits::neg_inf()); @@ -59,12 +59,12 @@ public: } void test_subnormal_range(Func func) { - constexpr UIntType COUNT = 10'001; + constexpr StorageType COUNT = 10'001; for (unsigned scale = 0; scale < 4; ++scale) { - UIntType max_value = FPBits::MAX_SUBNORMAL << scale; - UIntType step = (max_value - FPBits::MIN_SUBNORMAL) / COUNT; + StorageType max_value = FPBits::MAX_SUBNORMAL << scale; + StorageType step = (max_value - FPBits::MIN_SUBNORMAL) / COUNT; for (int signs = 0; signs < 4; ++signs) { - for (UIntType v = FPBits::MIN_SUBNORMAL, w = max_value; + for (StorageType v = FPBits::MIN_SUBNORMAL, w = max_value; v <= max_value && w >= FPBits::MIN_SUBNORMAL; v += step, w -= step) { T x = T(FPBits(v)), y = T(FPBits(w)); @@ -84,11 +84,12 @@ public: } void test_normal_range(Func func) { - constexpr UIntType COUNT = 10'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; + constexpr StorageType COUNT = 10'001; + constexpr StorageType STEP = + (StorageType(FPBits::MAX_NORMAL) - StorageType(FPBits::MIN_NORMAL)) / + COUNT; for (int signs = 0; signs < 4; ++signs) { - for (UIntType v = FPBits::MIN_NORMAL, w = FPBits::MAX_NORMAL; + for (StorageType v = FPBits::MIN_NORMAL, w = FPBits::MAX_NORMAL; v <= FPBits::MAX_NORMAL && w >= FPBits::MIN_NORMAL; v += STEP, w -= STEP) { T x = T(FPBits(v)), y = T(FPBits(w)); diff --git a/libc/test/src/math/ILogbTest.h b/libc/test/src/math/ILogbTest.h index e51a5d7a2544cdc3877c8a93cb7c49d10563ddfd..9f857da5547c7d7847d5e5e1e4843a38466f57f2 100644 --- a/libc/test/src/math/ILogbTest.h +++ b/libc/test/src/math/ILogbTest.h @@ -24,15 +24,12 @@ public: template void test_special_numbers(typename ILogbFunc::Func func) { - EXPECT_EQ(FP_ILOGB0, func(T(LIBC_NAMESPACE::fputil::FPBits::zero()))); - EXPECT_EQ(FP_ILOGB0, - func(T(LIBC_NAMESPACE::fputil::FPBits::neg_zero()))); - - EXPECT_EQ(FP_ILOGBNAN, - func(T(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)))); - - EXPECT_EQ(INT_MAX, func(T(LIBC_NAMESPACE::fputil::FPBits::inf()))); - EXPECT_EQ(INT_MAX, func(T(LIBC_NAMESPACE::fputil::FPBits::neg_inf()))); + using FPBits = LIBC_NAMESPACE::fputil::FPBits; + EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero()))); + EXPECT_EQ(FP_ILOGB0, func(T(FPBits::neg_zero()))); + EXPECT_EQ(FP_ILOGBNAN, func(T(FPBits::build_quiet_nan(1)))); + EXPECT_EQ(INT_MAX, func(T(FPBits::inf()))); + EXPECT_EQ(INT_MAX, func(T(FPBits::neg_inf()))); } template @@ -77,12 +74,11 @@ public: template void test_subnormal_range(typename ILogbFunc::Func func) { using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; - constexpr UIntType COUNT = 10'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_SUBNORMAL) - UIntType(FPBits::MIN_SUBNORMAL)) / - COUNT; - for (UIntType v = FPBits::MIN_SUBNORMAL; v <= FPBits::MAX_SUBNORMAL; + using StorageType = typename FPBits::StorageType; + constexpr StorageType COUNT = 10'001; + constexpr StorageType STEP = + (FPBits::MAX_SUBNORMAL - FPBits::MIN_SUBNORMAL) / COUNT; + for (StorageType v = FPBits::MIN_SUBNORMAL; v <= FPBits::MAX_SUBNORMAL; v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0) @@ -97,11 +93,12 @@ public: template void test_normal_range(typename ILogbFunc::Func func) { using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; - constexpr UIntType COUNT = 10'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; - for (UIntType v = FPBits::MIN_NORMAL; v <= FPBits::MAX_NORMAL; v += STEP) { + using StorageType = typename FPBits::StorageType; + constexpr StorageType COUNT = 10'001; + constexpr StorageType STEP = + (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + for (StorageType v = FPBits::MIN_NORMAL; v <= FPBits::MAX_NORMAL; + v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0) continue; diff --git a/libc/test/src/math/LdExpTest.h b/libc/test/src/math/LdExpTest.h index a75c8ef31a2cf83e9e279008eff5ec7553a0919e..5c144add3a4a3d34c5ca32def09c7b840c52ac1d 100644 --- a/libc/test/src/math/LdExpTest.h +++ b/libc/test/src/math/LdExpTest.h @@ -22,17 +22,15 @@ template class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat; - using UIntType = typename FPBits::UIntType; - static constexpr UIntType MANTISSA_WIDTH = - LIBC_NAMESPACE::fputil::MantissaWidth::VALUE; + using StorageType = typename FPBits::StorageType; // A normalized mantissa to be used with tests. - static constexpr UIntType MANTISSA = NormalFloat::ONE + 0x1234; + static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234; - const T zero = T(LIBC_NAMESPACE::fputil::FPBits::zero()); - const T neg_zero = T(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); - const T inf = T(LIBC_NAMESPACE::fputil::FPBits::inf()); - const T neg_inf = T(LIBC_NAMESPACE::fputil::FPBits::neg_inf()); - const T nan = T(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)); + const T zero = T(FPBits::zero()); + const T neg_zero = T(FPBits::neg_zero()); + const T inf = T(FPBits::inf()); + const T neg_inf = T(FPBits::neg_inf()); + const T nan = T(FPBits::build_quiet_nan(1)); public: typedef T (*LdExpFunc)(T, int); @@ -70,7 +68,7 @@ public: void testUnderflowToZeroOnNormal(LdExpFunc func) { // In this test, we pass a normal nubmer to func and expect zero // to be returned due to underflow. - int32_t base_exponent = FPBits::EXPONENT_BIAS + int32_t(MANTISSA_WIDTH); + int32_t base_exponent = FPBits::EXP_BIAS + FPBits::FRACTION_LEN; int32_t exp_array[] = {base_exponent + 5, base_exponent + 4, base_exponent + 3, base_exponent + 2, base_exponent + 1}; @@ -83,11 +81,11 @@ public: void testUnderflowToZeroOnSubnormal(LdExpFunc func) { // In this test, we pass a normal nubmer to func and expect zero // to be returned due to underflow. - int32_t base_exponent = FPBits::EXPONENT_BIAS + int32_t(MANTISSA_WIDTH); + int32_t base_exponent = FPBits::EXP_BIAS + FPBits::FRACTION_LEN; int32_t exp_array[] = {base_exponent + 5, base_exponent + 4, base_exponent + 3, base_exponent + 2, base_exponent + 1}; - T x = NormalFloat(-FPBits::EXPONENT_BIAS, MANTISSA, 0); + T x = NormalFloat(-FPBits::EXP_BIAS, MANTISSA, 0); for (int32_t exp : exp_array) { ASSERT_FP_EQ(func(x, -exp), x > 0 ? zero : neg_zero); } @@ -99,9 +97,9 @@ public: NormalFloat(100, MANTISSA, 0), NormalFloat(-100, MANTISSA, 0), NormalFloat(100, MANTISSA, 1), NormalFloat(-100, MANTISSA, 1), // Subnormal numbers - NormalFloat(-FPBits::EXPONENT_BIAS, MANTISSA, 0), - NormalFloat(-FPBits::EXPONENT_BIAS, MANTISSA, 1)}; - for (int32_t exp = 0; exp <= static_cast(MANTISSA_WIDTH); ++exp) { + NormalFloat(-FPBits::EXP_BIAS, MANTISSA, 0), + NormalFloat(-FPBits::EXP_BIAS, MANTISSA, 1)}; + for (int32_t exp = 0; exp <= FPBits::FRACTION_LEN; ++exp) { for (T x : val_array) { // We compare the result of ldexp with the result // of the native multiplication/division instruction. @@ -119,14 +117,14 @@ public: } // Normal which trigger mantissa overflow. - T x = NormalFloat(-FPBits::EXPONENT_BIAS + 1, - UIntType(2) * NormalFloat::ONE - UIntType(1), 0); + T x = NormalFloat(-FPBits::EXP_BIAS + 1, + StorageType(2) * NormalFloat::ONE - StorageType(1), 0); ASSERT_FP_EQ(func(x, -1), x / 2); ASSERT_FP_EQ(func(-x, -1), -x / 2); // Start with a normal number high exponent but pass a very low number for // exp. The result should be a subnormal number. - x = NormalFloat(FPBits::EXPONENT_BIAS, NormalFloat::ONE, 0); + x = NormalFloat(FPBits::EXP_BIAS, NormalFloat::ONE, 0); int exp = -FPBits::MAX_EXPONENT - 5; T result = func(x, exp); FPBits result_bits(result); @@ -135,12 +133,12 @@ public: ASSERT_EQ(result_bits.get_biased_exponent(), uint16_t(0)); // But if the exp is so less that normalization leads to zero, then // the result should be zero. - result = func(x, -FPBits::MAX_EXPONENT - int(MANTISSA_WIDTH) - 5); + result = func(x, -FPBits::MAX_EXPONENT - FPBits::FRACTION_LEN - 5); ASSERT_TRUE(FPBits(result).is_zero()); // Start with a subnormal number but pass a very high number for exponent. // The result should not be infinity. - x = NormalFloat(-FPBits::EXPONENT_BIAS + 1, NormalFloat::ONE >> 10, 0); + x = NormalFloat(-FPBits::EXP_BIAS + 1, NormalFloat::ONE >> 10, 0); exp = FPBits::MAX_EXPONENT + 5; ASSERT_FALSE(FPBits(func(x, exp)).is_inf()); // But if the exp is large enough to oversome than the normalization shift, diff --git a/libc/test/src/math/LogbTest.h b/libc/test/src/math/LogbTest.h index c2cf4f1f1483336cd34106c4529c614868e4276e..2049c8ffe950eead6e8f4c6dde9b825d5a8d4e70 100644 --- a/libc/test/src/math/LogbTest.h +++ b/libc/test/src/math/LogbTest.h @@ -19,8 +19,9 @@ template class LogbTest : public LIBC_NAMESPACE::testing::Test { DECLARE_SPECIAL_CONSTANTS(T) - static constexpr UIntType HIDDEN_BIT = - UIntType(1) << LIBC_NAMESPACE::fputil::MantissaWidth::VALUE; + static constexpr StorageType HIDDEN_BIT = + StorageType(1) + << LIBC_NAMESPACE::fputil::FloatProperties::FRACTION_LEN; public: typedef T (*LogbFunc)(T); @@ -71,10 +72,10 @@ public: } void testRange(LogbFunc func) { - using UIntType = typename FPBits::UIntType; - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + using StorageType = typename FPBits::StorageType; + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = static_cast(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0l) continue; diff --git a/libc/test/src/math/ModfTest.h b/libc/test/src/math/ModfTest.h index 21adef8a08d8d4948dfb3f369934cf4709d1d1c3..f5196a74fa7425cf31e1c4e7aed656a8d093bcae 100644 --- a/libc/test/src/math/ModfTest.h +++ b/libc/test/src/math/ModfTest.h @@ -84,9 +84,9 @@ public: } void testRange(ModfFunc func) { - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x) || x == T(0.0)) continue; diff --git a/libc/test/src/math/NextAfterTest.h b/libc/test/src/math/NextAfterTest.h index 57a801dfb28a316ae9f0a2d623217f199f2a3359..005c5730e8f52d51fdeaafbf0a7848650b71c761 100644 --- a/libc/test/src/math/NextAfterTest.h +++ b/libc/test/src/math/NextAfterTest.h @@ -20,21 +20,17 @@ template class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using MantissaWidth = LIBC_NAMESPACE::fputil::MantissaWidth; - using UIntType = typename FPBits::UIntType; - - static constexpr int BIT_WIDTH_OF_TYPE = - LIBC_NAMESPACE::fputil::FloatProperties::BIT_WIDTH; + using StorageType = typename FPBits::StorageType; const T zero = T(FPBits::zero()); const T neg_zero = T(FPBits::neg_zero()); const T inf = T(FPBits::inf()); const T neg_inf = T(FPBits::neg_inf()); const T nan = T(FPBits::build_quiet_nan(1)); - const UIntType min_subnormal = FPBits::MIN_SUBNORMAL; - const UIntType max_subnormal = FPBits::MAX_SUBNORMAL; - const UIntType min_normal = FPBits::MIN_NORMAL; - const UIntType max_normal = FPBits::MAX_NORMAL; + const StorageType min_subnormal = FPBits::MIN_SUBNORMAL; + const StorageType max_subnormal = FPBits::MAX_SUBNORMAL; + const StorageType min_normal = FPBits::MIN_NORMAL; + const StorageType max_normal = FPBits::MAX_NORMAL; public: typedef T (*NextAfterFunc)(T, T); @@ -51,12 +47,12 @@ public: // 'from' is zero|neg_zero. T x = zero; T result = func(x, T(1)); - UIntType expected_bits = 1; + StorageType expected_bits = 1; T expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); result = func(x, T(-1)); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1; + expected_bits = FPBits::SIGN_MASK + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); @@ -67,7 +63,7 @@ public: ASSERT_FP_EQ(result, expected); result = func(x, -1); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1; + expected_bits = FPBits::SIGN_MASK + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); @@ -85,13 +81,12 @@ public: x = -x; result = func(x, -1); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal; + expected_bits = FPBits::SIGN_MASK + min_normal; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); result = func(x, 0); - expected_bits = - (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal - 1; + expected_bits = FPBits::SIGN_MASK + max_subnormal - 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); @@ -105,8 +100,7 @@ public: x = -x; result = func(x, -1); - expected_bits = - (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_subnormal + 1; + expected_bits = FPBits::SIGN_MASK + min_subnormal + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); ASSERT_FP_EQ(func(x, 0), T(-0.0)); @@ -125,12 +119,12 @@ public: x = -x; result = func(x, 0); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal; + expected_bits = FPBits::SIGN_MASK + max_subnormal; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); result = func(x, -inf); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal + 1; + expected_bits = FPBits::SIGN_MASK + min_normal + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); @@ -152,7 +146,7 @@ public: x = neg_inf; result = func(x, 0); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_normal; + expected_bits = FPBits::SIGN_MASK + max_normal; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); ASSERT_FP_EQ(func(x, neg_inf), neg_inf); @@ -164,13 +158,13 @@ public: FPBits result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), uint16_t(x_bits.get_biased_exponent() - 1)); - ASSERT_EQ(result_bits.get_mantissa(), - (UIntType(1) << MantissaWidth::VALUE) - 1); + ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK); result = func(x, T(33.0)); result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent()); - ASSERT_EQ(result_bits.get_mantissa(), x_bits.get_mantissa() + UIntType(1)); + ASSERT_EQ(result_bits.get_mantissa(), + x_bits.get_mantissa() + StorageType(1)); x = -x; @@ -178,13 +172,13 @@ public: result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), uint16_t(x_bits.get_biased_exponent() - 1)); - ASSERT_EQ(result_bits.get_mantissa(), - (UIntType(1) << MantissaWidth::VALUE) - 1); + ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK); result = func(x, T(-33.0)); result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent()); - ASSERT_EQ(result_bits.get_mantissa(), x_bits.get_mantissa() + UIntType(1)); + ASSERT_EQ(result_bits.get_mantissa(), + x_bits.get_mantissa() + StorageType(1)); } }; diff --git a/libc/test/src/math/RIntTest.h b/libc/test/src/math/RIntTest.h index 272112142e21e0f3fb90e4fb856ea585846b22d2..2471b831759fe766a07a26ea263c27d3500fe32b 100644 --- a/libc/test/src/math/RIntTest.h +++ b/libc/test/src/math/RIntTest.h @@ -31,7 +31,7 @@ public: private: using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; const T zero = T(FPBits::zero()); const T neg_zero = T(FPBits::neg_zero()); @@ -93,11 +93,10 @@ public: } void testSubnormalRange(RIntFunc func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_SUBNORMAL) - UIntType(FPBits::MIN_SUBNORMAL)) / - COUNT; - for (UIntType i = FPBits::MIN_SUBNORMAL; i <= FPBits::MAX_SUBNORMAL; + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = + (FPBits::MAX_SUBNORMAL - FPBits::MIN_SUBNORMAL) / COUNT; + for (StorageType i = FPBits::MIN_SUBNORMAL; i <= FPBits::MAX_SUBNORMAL; i += STEP) { T x = T(FPBits(i)); for (int mode : ROUNDING_MODES) { @@ -109,10 +108,11 @@ public: } void testNormalRange(RIntFunc func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; - for (UIntType i = FPBits::MIN_NORMAL; i <= FPBits::MAX_NORMAL; i += STEP) { + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = + (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + for (StorageType i = FPBits::MIN_NORMAL; i <= FPBits::MAX_NORMAL; + i += STEP) { T x = T(FPBits(i)); // In normal range on x86 platforms, the long double implicit 1 bit can be // zero making the numbers NaN. We will skip them. diff --git a/libc/test/src/math/RemQuoTest.h b/libc/test/src/math/RemQuoTest.h index 6da0756c3a1b3de2859970bbe100a6e666cb9c8e..6495b61331dbb510e87231436a00f9b28d04b6b9 100644 --- a/libc/test/src/math/RemQuoTest.h +++ b/libc/test/src/math/RemQuoTest.h @@ -21,13 +21,13 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr; template class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; - const T zero = T(LIBC_NAMESPACE::fputil::FPBits::zero()); - const T neg_zero = T(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); - const T inf = T(LIBC_NAMESPACE::fputil::FPBits::inf()); - const T neg_inf = T(LIBC_NAMESPACE::fputil::FPBits::neg_inf()); - const T nan = T(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)); + const T zero = T(FPBits::zero()); + const T neg_zero = T(FPBits::neg_zero()); + const T inf = T(FPBits::inf()); + const T neg_inf = T(FPBits::neg_inf()); + const T nan = T(FPBits::build_quiet_nan(1)); public: typedef T (*RemQuoFunc)(T, T, int *); @@ -95,11 +95,10 @@ public: } void testSubnormalRange(RemQuoFunc func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_SUBNORMAL) - UIntType(FPBits::MIN_SUBNORMAL)) / - COUNT; - for (UIntType v = FPBits::MIN_SUBNORMAL, w = FPBits::MAX_SUBNORMAL; + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = + (FPBits::MAX_SUBNORMAL - FPBits::MIN_SUBNORMAL) / COUNT; + for (StorageType v = FPBits::MIN_SUBNORMAL, w = FPBits::MAX_SUBNORMAL; v <= FPBits::MAX_SUBNORMAL && w >= FPBits::MIN_SUBNORMAL; v += STEP, w -= STEP) { T x = T(FPBits(v)), y = T(FPBits(w)); @@ -111,10 +110,10 @@ public: } void testNormalRange(RemQuoFunc func) { - constexpr UIntType COUNT = 1'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; - for (UIntType v = FPBits::MIN_NORMAL, w = FPBits::MAX_NORMAL; + constexpr StorageType COUNT = 1'001; + constexpr StorageType STEP = + (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + for (StorageType v = FPBits::MIN_NORMAL, w = FPBits::MAX_NORMAL; v <= FPBits::MAX_NORMAL && w >= FPBits::MIN_NORMAL; v += STEP, w -= STEP) { T x = T(FPBits(v)), y = T(FPBits(w)); diff --git a/libc/test/src/math/RoundTest.h b/libc/test/src/math/RoundTest.h index e99491ccf380f854a7d01829dadef1a4d24d0d22..3ec46159c65d952ccef796a20e91434b7360a64e 100644 --- a/libc/test/src/math/RoundTest.h +++ b/libc/test/src/math/RoundTest.h @@ -64,9 +64,9 @@ public: } void testRange(RoundFunc func) { - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x)) continue; diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h index 1a976e97359eb76ab108a1a7ca824767c851946c..d76b5a10dfa259ecc76678f8c19706253e4c0e55 100644 --- a/libc/test/src/math/RoundToIntegerTest.h +++ b/libc/test/src/math/RoundToIntegerTest.h @@ -30,13 +30,13 @@ public: private: using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; - const F zero = F(LIBC_NAMESPACE::fputil::FPBits::zero()); - const F neg_zero = F(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); - const F inf = F(LIBC_NAMESPACE::fputil::FPBits::inf()); - const F neg_inf = F(LIBC_NAMESPACE::fputil::FPBits::neg_inf()); - const F nan = F(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)); + const F zero = F(FPBits::zero()); + const F neg_zero = F(FPBits::neg_zero()); + const F inf = F(FPBits::inf()); + const F neg_inf = F(FPBits::neg_inf()); + const F nan = F(FPBits::build_quiet_nan(1)); static constexpr I INTEGER_MIN = I(1) << (sizeof(I) * 8 - 1); static constexpr I INTEGER_MAX = -(INTEGER_MIN + 1); @@ -126,7 +126,7 @@ public: // We start with 1.0 so that the implicit bit for x86 long doubles // is set. FPBits bits(F(1.0)); - bits.set_biased_exponent(EXPONENT_LIMIT + FPBits::EXPONENT_BIAS); + bits.set_biased_exponent(EXPONENT_LIMIT + FPBits::EXP_BIAS); bits.set_sign(1); bits.set_mantissa(0); @@ -190,10 +190,9 @@ public: // We start with 1.0 so that the implicit bit for x86 long doubles // is set. FPBits bits(F(1.0)); - bits.set_biased_exponent(EXPONENT_LIMIT + FPBits::EXPONENT_BIAS); + bits.set_biased_exponent(EXPONENT_LIMIT + FPBits::EXP_BIAS); bits.set_sign(1); - bits.set_mantissa(UIntType(0x1) - << (LIBC_NAMESPACE::fputil::MantissaWidth::VALUE - 1)); + bits.set_mantissa(FPBits::FRACTION_MASK); F x = F(bits); if (TestModes) { @@ -214,11 +213,10 @@ public: } void testSubnormalRange(RoundToIntegerFunc func) { - constexpr UIntType COUNT = 1'000'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_SUBNORMAL) - UIntType(FPBits::MIN_SUBNORMAL)) / - COUNT; - for (UIntType i = FPBits::MIN_SUBNORMAL; i <= FPBits::MAX_SUBNORMAL; + constexpr StorageType COUNT = 1'000'001; + constexpr StorageType STEP = + (FPBits::MAX_SUBNORMAL - FPBits::MIN_SUBNORMAL) / COUNT; + for (StorageType i = FPBits::MIN_SUBNORMAL; i <= FPBits::MAX_SUBNORMAL; i += STEP) { F x = F(FPBits(i)); if (x == F(0.0)) @@ -259,10 +257,11 @@ public: if (sizeof(I) > sizeof(long)) return; - constexpr UIntType COUNT = 1'000'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; - for (UIntType i = FPBits::MIN_NORMAL; i <= FPBits::MAX_NORMAL; i += STEP) { + constexpr StorageType COUNT = 1'000'001; + constexpr StorageType STEP = + (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + for (StorageType i = FPBits::MIN_NORMAL; i <= FPBits::MAX_NORMAL; + i += STEP) { F x = F(FPBits(i)); // In normal range on x86 platforms, the long double implicit 1 bit can be // zero making the numbers NaN. We will skip them. diff --git a/libc/test/src/math/SqrtTest.h b/libc/test/src/math/SqrtTest.h index 24f14b78d2f0f5d850c3335a61e9e0b2d2b3e1d8..2cfe401c5542a35677e85dfb4bcfa0bfc35076a6 100644 --- a/libc/test/src/math/SqrtTest.h +++ b/libc/test/src/math/SqrtTest.h @@ -19,8 +19,9 @@ template class SqrtTest : public LIBC_NAMESPACE::testing::Test { DECLARE_SPECIAL_CONSTANTS(T) - static constexpr UIntType HIDDEN_BIT = - UIntType(1) << LIBC_NAMESPACE::fputil::MantissaWidth::VALUE; + static constexpr StorageType HIDDEN_BIT = + StorageType(1) + << LIBC_NAMESPACE::fputil::FloatProperties::FRACTION_LEN; public: typedef T (*SqrtFunc)(T); @@ -38,25 +39,25 @@ public: } void test_denormal_values(SqrtFunc func) { - for (UIntType mant = 1; mant < HIDDEN_BIT; mant <<= 1) { + for (StorageType mant = 1; mant < HIDDEN_BIT; mant <<= 1) { FPBits denormal(T(0.0)); denormal.set_mantissa(mant); T x = T(denormal); EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sqrt, x, func(x), 0.5); } - constexpr UIntType COUNT = 200'001; - constexpr UIntType STEP = HIDDEN_BIT / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 200'001; + constexpr StorageType STEP = HIDDEN_BIT / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = LIBC_NAMESPACE::cpp::bit_cast(v); EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sqrt, x, func(x), 0.5); } } void test_normal_range(SqrtFunc func) { - constexpr UIntType COUNT = 200'001; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 200'001; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = LIBC_NAMESPACE::cpp::bit_cast(v); if (isnan(x) || (x < 0)) { continue; diff --git a/libc/test/src/math/TruncTest.h b/libc/test/src/math/TruncTest.h index fa29ee1ce8c3a4d2245b4e2cc0ef154d09011e64..2be40790258ef7a2432c91c07da8fbbec697eba4 100644 --- a/libc/test/src/math/TruncTest.h +++ b/libc/test/src/math/TruncTest.h @@ -64,9 +64,9 @@ public: } void testRange(TruncFunc func) { - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x)) continue; diff --git a/libc/test/src/math/cos_test.cpp b/libc/test/src/math/cos_test.cpp index 738d66034f18d2141775fb5a50616bc4ad186b0e..a4c332bc7fb52b92bfd2eed1c9f0ebe52f48a5ae 100644 --- a/libc/test/src/math/cos_test.cpp +++ b/libc/test/src/math/cos_test.cpp @@ -19,9 +19,9 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr; TEST_F(LlvmLibcCosTest, Range) { static constexpr double _2pi = 6.283185307179586; - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { double x = double(FPBits(v)); // TODO: Expand the range of testing after range reduction is implemented. if (isnan(x) || isinf(x) || x > _2pi || x < -_2pi) diff --git a/libc/test/src/math/differential_testing/BinaryOpSingleOutputDiff.h b/libc/test/src/math/differential_testing/BinaryOpSingleOutputDiff.h index 1ea50deccb7eaf840c91af981a2df03881126a14..ada7c9e4954265d54a161cdbd604da6ce1fb8823 100644 --- a/libc/test/src/math/differential_testing/BinaryOpSingleOutputDiff.h +++ b/libc/test/src/math/differential_testing/BinaryOpSingleOutputDiff.h @@ -16,23 +16,24 @@ namespace testing { template class BinaryOpSingleOutputDiff { using FPBits = fputil::FPBits; - using UIntType = typename FPBits::UIntType; - static constexpr UIntType MSBIT = UIntType(1) << (8 * sizeof(UIntType) - 1); - static constexpr UIntType UINTMAX = (MSBIT - 1) + MSBIT; + using StorageType = typename FPBits::StorageType; + static constexpr StorageType UIntMax = + cpp::numeric_limits::max(); public: typedef T Func(T, T); static uint64_t run_diff_in_range(Func myFunc, Func otherFunc, - UIntType startingBit, UIntType endingBit, - UIntType N, std::ofstream &log) { + StorageType startingBit, + StorageType endingBit, StorageType N, + std::ofstream &log) { uint64_t result = 0; if (endingBit < startingBit) { return result; } - UIntType step = (endingBit - startingBit) / N; - for (UIntType bitsX = startingBit, bitsY = endingBit;; + StorageType step = (endingBit - startingBit) / N; + for (StorageType bitsX = startingBit, bitsY = endingBit;; bitsX += step, bitsY -= step) { T x = T(FPBits(bitsX)); T y = T(FPBits(bitsY)); @@ -57,16 +58,16 @@ public: } static void run_perf_in_range(Func myFunc, Func otherFunc, - UIntType startingBit, UIntType endingBit, - UIntType N, std::ofstream &log) { + StorageType startingBit, StorageType endingBit, + StorageType N, std::ofstream &log) { auto runner = [=](Func func) { volatile T result; if (endingBit < startingBit) { return; } - UIntType step = (endingBit - startingBit) / N; - for (UIntType bitsX = startingBit, bitsY = endingBit;; + StorageType step = (endingBit - startingBit) / N; + for (StorageType bitsX = startingBit, bitsY = endingBit;; bitsX += step, bitsY -= step) { T x = T(FPBits(bitsX)); T y = T(FPBits(bitsY)); @@ -107,7 +108,7 @@ public: static void run_perf(Func myFunc, Func otherFunc, const char *logFile) { std::ofstream log(logFile); log << " Performance tests with inputs in denormal range:\n"; - run_perf_in_range(myFunc, otherFunc, /* startingBit= */ UIntType(0), + run_perf_in_range(myFunc, otherFunc, /* startingBit= */ StorageType(0), /* endingBit= */ FPBits::MAX_SUBNORMAL, 1'000'001, log); log << "\n Performance tests with inputs in normal range:\n"; run_perf_in_range(myFunc, otherFunc, /* startingBit= */ FPBits::MIN_NORMAL, @@ -124,7 +125,7 @@ public: std::ofstream log(logFile); log << " Diff tests with inputs in denormal range:\n"; diffCount += run_diff_in_range( - myFunc, otherFunc, /* startingBit= */ UIntType(0), + myFunc, otherFunc, /* startingBit= */ StorageType(0), /* endingBit= */ FPBits::MAX_SUBNORMAL, 1'000'001, log); log << "\n Diff tests with inputs in normal range:\n"; diffCount += run_diff_in_range( diff --git a/libc/test/src/math/differential_testing/SingleInputSingleOutputDiff.h b/libc/test/src/math/differential_testing/SingleInputSingleOutputDiff.h index c20cf3152f622009274836ab2cccd0fcda28fbfb..e4cd06eb22b7162e412ec86467f5d2ab477a1f18 100644 --- a/libc/test/src/math/differential_testing/SingleInputSingleOutputDiff.h +++ b/libc/test/src/math/differential_testing/SingleInputSingleOutputDiff.h @@ -16,24 +16,24 @@ namespace testing { template class SingleInputSingleOutputDiff { using FPBits = fputil::FPBits; - using UIntType = typename FPBits::UIntType; - static constexpr UIntType MSBit = UIntType(1) << (8 * sizeof(UIntType) - 1); - static constexpr UIntType UIntMax = (MSBit - 1) + MSBit; + using StorageType = typename FPBits::StorageType; + static constexpr StorageType UIntMax = + cpp::numeric_limits::max(); public: typedef T Func(T); static void runDiff(Func myFunc, Func otherFunc, const char *logFile) { - UIntType diffCount = 0; + StorageType diffCount = 0; std::ofstream log(logFile); log << "Starting diff for values from 0 to " << UIntMax << '\n' << "Only differing results will be logged.\n\n"; - for (UIntType bits = 0;; ++bits) { + for (StorageType bits = 0;; ++bits) { T x = T(FPBits(bits)); T myResult = myFunc(x); T otherResult = otherFunc(x); - UIntType myBits = FPBits(myResult).uintval(); - UIntType otherBits = FPBits(otherResult).uintval(); + StorageType myBits = FPBits(myResult).uintval(); + StorageType otherBits = FPBits(otherResult).uintval(); if (myBits != otherBits) { ++diffCount; log << " Input: " << bits << " (" << x << ")\n" @@ -47,11 +47,12 @@ public: log << "Total number of differing results: " << diffCount << '\n'; } - static void runPerfInRange(Func myFunc, Func otherFunc, UIntType startingBit, - UIntType endingBit, std::ofstream &log) { + static void runPerfInRange(Func myFunc, Func otherFunc, + StorageType startingBit, StorageType endingBit, + std::ofstream &log) { auto runner = [=](Func func) { volatile T result; - for (UIntType bits = startingBit;; ++bits) { + for (StorageType bits = startingBit;; ++bits) { T x = T(FPBits(bits)); result = func(x); if (bits == endingBit) @@ -64,7 +65,7 @@ public: runner(myFunc); timer.stop(); - UIntType numberOfRuns = endingBit - startingBit + 1; + StorageType numberOfRuns = endingBit - startingBit + 1; double myAverage = static_cast(timer.nanoseconds()) / numberOfRuns; log << "-- My function --\n"; log << " Total time : " << timer.nanoseconds() << " ns \n"; @@ -91,7 +92,7 @@ public: static void runPerf(Func myFunc, Func otherFunc, const char *logFile) { std::ofstream log(logFile); log << " Performance tests with inputs in denormal range:\n"; - runPerfInRange(myFunc, otherFunc, /* startingBit= */ UIntType(0), + runPerfInRange(myFunc, otherFunc, /* startingBit= */ StorageType(0), /* endingBit= */ FPBits::MAX_SUBNORMAL, log); log << "\n Performance tests with inputs in normal range:\n"; runPerfInRange(myFunc, otherFunc, /* startingBit= */ FPBits::MIN_NORMAL, diff --git a/libc/test/src/math/exhaustive/exhaustive_test.h b/libc/test/src/math/exhaustive/exhaustive_test.h index c4e68d40e8e91e7e3875ccf0ac85af4a9406516f..dbb59e5269dc331ba8deb13e0f7042ddd9b9f807 100644 --- a/libc/test/src/math/exhaustive/exhaustive_test.h +++ b/libc/test/src/math/exhaustive/exhaustive_test.h @@ -24,7 +24,7 @@ // 1. Define a Checker class with: // - FloatType: define floating point type to be used. // - FPBits: fputil::FPBits. -// - UIntType: define bit type for the corresponding floating point type. +// - StorageType: define bit type for the corresponding floating point type. // - uint64_t check(start, stop, rounding_mode): a method to test in given // range for a given rounding mode, which returns the number of // failures. @@ -41,16 +41,17 @@ template Func> struct UnaryOpChecker : public virtual LIBC_NAMESPACE::testing::Test { using FloatType = T; using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; static constexpr UnaryOp *FUNC = Func; // Check in a range, return the number of failures. - uint64_t check(UIntType start, UIntType stop, mpfr::RoundingMode rounding) { + uint64_t check(StorageType start, StorageType stop, + mpfr::RoundingMode rounding) { mpfr::ForceRoundingMode r(rounding); if (!r.success) return (stop > start); - UIntType bits = start; + StorageType bits = start; uint64_t failed = 0; do { FPBits xbits(bits); @@ -68,32 +69,32 @@ struct UnaryOpChecker : public virtual LIBC_NAMESPACE::testing::Test { }; // Checker class needs inherit from LIBC_NAMESPACE::testing::Test and provide -// UIntType and check method. +// StorageType and check method. template struct LlvmLibcExhaustiveMathTest : public virtual LIBC_NAMESPACE::testing::Test, public Checker { using FloatType = typename Checker::FloatType; using FPBits = typename Checker::FPBits; - using UIntType = typename Checker::UIntType; + using StorageType = typename Checker::StorageType; - static constexpr UIntType INCREMENT = (1 << 20); + static constexpr StorageType INCREMENT = (1 << 20); // Break [start, stop) into `nthreads` subintervals and apply *check to each // subinterval in parallel. - void test_full_range(UIntType start, UIntType stop, + void test_full_range(StorageType start, StorageType stop, mpfr::RoundingMode rounding) { int n_threads = std::thread::hardware_concurrency(); std::vector thread_list; std::mutex mx_cur_val; int current_percent = -1; - UIntType current_value = start; + StorageType current_value = start; std::atomic failed(0); for (int i = 0; i < n_threads; ++i) { thread_list.emplace_back([&, this]() { while (true) { - UIntType range_begin, range_end; + StorageType range_begin, range_end; int new_percent = -1; { std::lock_guard lock(mx_cur_val); @@ -148,7 +149,7 @@ struct LlvmLibcExhaustiveMathTest ASSERT_EQ(failed.load(), uint64_t(0)); } - void test_full_range_all_roundings(UIntType start, UIntType stop) { + void test_full_range_all_roundings(StorageType start, StorageType stop) { std::cout << "-- Testing for FE_TONEAREST in range [0x" << std::hex << start << ", 0x" << stop << ") --" << std::dec << std::endl; test_full_range(start, stop, mpfr::RoundingMode::Nearest); diff --git a/libc/test/src/math/exhaustive/hypotf_test.cpp b/libc/test/src/math/exhaustive/hypotf_test.cpp index 8812f0e5dcde34a7f940f2f5fa834247821cddef..df597563ab0cd3f39f86a49a90714a2cc1e02866 100644 --- a/libc/test/src/math/exhaustive/hypotf_test.cpp +++ b/libc/test/src/math/exhaustive/hypotf_test.cpp @@ -18,7 +18,7 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr; struct HypotfChecker : public virtual LIBC_NAMESPACE::testing::Test { using FloatType = float; using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; uint64_t check(uint32_t start, uint32_t stop, mpfr::RoundingMode rounding) { // Range of the second input: [2^37, 2^48). diff --git a/libc/test/src/math/exhaustive/sincosf_test.cpp b/libc/test/src/math/exhaustive/sincosf_test.cpp index f73a1a64c5e4ddef943339c47ab8941a77f62047..4104034d17c6f06541d1eb523fe39948e05809d0 100644 --- a/libc/test/src/math/exhaustive/sincosf_test.cpp +++ b/libc/test/src/math/exhaustive/sincosf_test.cpp @@ -15,13 +15,14 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr; struct SincosfChecker : public virtual LIBC_NAMESPACE::testing::Test { using FloatType = float; using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = uint32_t; + using StorageType = uint32_t; - uint64_t check(UIntType start, UIntType stop, mpfr::RoundingMode rounding) { + uint64_t check(StorageType start, StorageType stop, + mpfr::RoundingMode rounding) { mpfr::ForceRoundingMode r(rounding); if (!r.success) return (stop > start); - UIntType bits = start; + StorageType bits = start; uint64_t failed = 0; do { FPBits xbits(bits); diff --git a/libc/test/src/math/sin_test.cpp b/libc/test/src/math/sin_test.cpp index b18219577a792576a7e56f872518c3aa04fd61b1..cd9eeaff598feaf4369f574688b33165ac99d3ca 100644 --- a/libc/test/src/math/sin_test.cpp +++ b/libc/test/src/math/sin_test.cpp @@ -20,9 +20,9 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr; TEST_F(LlvmLibcSinTest, Range) { static constexpr double _2pi = 6.283185307179586; - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { double x = double(FPBits(v)); // TODO: Expand the range of testing after range reduction is implemented. if (isnan(x) || isinf(x) || x > _2pi || x < -_2pi) diff --git a/libc/test/src/math/smoke/CopySignTest.h b/libc/test/src/math/smoke/CopySignTest.h index 5e748bb8fd8ed58487dffe61f541fc482b7aa169..1108a45ae673e51c71cf7512856a48651da8d7e4 100644 --- a/libc/test/src/math/smoke/CopySignTest.h +++ b/libc/test/src/math/smoke/CopySignTest.h @@ -31,9 +31,9 @@ public: } void testRange(CopySignFunc func) { - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { FPBits x_bits = FPBits(v); T x = T(v); if (x_bits.is_nan() || x_bits.is_inf()) diff --git a/libc/test/src/math/smoke/FDimTest.h b/libc/test/src/math/smoke/FDimTest.h index 3118c3661013e7cf97101e8cdb28adba09145972..e926640abc90e0e03dcbd39e7bef0d1a5f2b952d 100644 --- a/libc/test/src/math/smoke/FDimTest.h +++ b/libc/test/src/math/smoke/FDimTest.h @@ -17,7 +17,7 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test { public: using FuncPtr = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; void test_na_n_arg(FuncPtr func) { EXPECT_FP_EQ(nan, func(nan, inf)); @@ -53,9 +53,11 @@ public: } void test_in_range(FuncPtr func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0, w = UIntType(-1); i <= COUNT; + constexpr StorageType STORAGE_MAX = + LIBC_NAMESPACE::cpp::numeric_limits::max(); + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT; ++i, v += STEP, w -= STEP) { T x = T(FPBits(v)), y = T(FPBits(w)); if (isnan(x) || isinf(x)) @@ -74,9 +76,9 @@ public: private: // constexpr does not work on FPBits yet, so we cannot have these constants as // static. - const T nan = T(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)); - const T inf = T(LIBC_NAMESPACE::fputil::FPBits::inf()); - const T neg_inf = T(LIBC_NAMESPACE::fputil::FPBits::neg_inf()); - const T zero = T(LIBC_NAMESPACE::fputil::FPBits::zero()); - const T neg_zero = T(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); + const T nan = T(FPBits::build_quiet_nan(1)); + const T inf = T(FPBits::inf()); + const T neg_inf = T(FPBits::neg_inf()); + const T zero = T(FPBits::zero()); + const T neg_zero = T(FPBits::neg_zero()); }; diff --git a/libc/test/src/math/smoke/FMaxTest.h b/libc/test/src/math/smoke/FMaxTest.h index e1192a4e0a7d1aef69c685a90b12f0a18f8d7119..372d9c5571d319f43d8ead3b53eabc766efa5fd6 100644 --- a/libc/test/src/math/smoke/FMaxTest.h +++ b/libc/test/src/math/smoke/FMaxTest.h @@ -52,9 +52,9 @@ public: } void testRange(FMaxFunc func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0, w = UIntType(-1); i <= COUNT; + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT; ++i, v += STEP, w -= STEP) { T x = T(FPBits(v)), y = T(FPBits(w)); if (isnan(x) || isinf(x)) diff --git a/libc/test/src/math/smoke/FMinTest.h b/libc/test/src/math/smoke/FMinTest.h index f0764ec3855b23c4eaac0d3a2e8d8091639d8c70..a51f30803ba82a99f2dbf68407fa5cdb10b8b9ad 100644 --- a/libc/test/src/math/smoke/FMinTest.h +++ b/libc/test/src/math/smoke/FMinTest.h @@ -52,9 +52,9 @@ public: } void testRange(FMinFunc func) { - constexpr UIntType COUNT = 100'001; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0, w = UIntType(-1); i <= COUNT; + constexpr StorageType COUNT = 100'001; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT; ++i, v += STEP, w -= STEP) { T x = T(FPBits(v)), y = T(FPBits(w)); if (isnan(x) || isinf(x)) diff --git a/libc/test/src/math/smoke/FmaTest.h b/libc/test/src/math/smoke/FmaTest.h index 3c1c120d77d450864efdb08040e0524bb0ada331..0b4c7001f936ef500f98fa91a7903280a19817ce 100644 --- a/libc/test/src/math/smoke/FmaTest.h +++ b/libc/test/src/math/smoke/FmaTest.h @@ -18,12 +18,12 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test { private: using Func = T (*)(T, T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; - const T nan = T(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)); - const T inf = T(LIBC_NAMESPACE::fputil::FPBits::inf()); - const T neg_inf = T(LIBC_NAMESPACE::fputil::FPBits::neg_inf()); - const T zero = T(LIBC_NAMESPACE::fputil::FPBits::zero()); - const T neg_zero = T(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); + using StorageType = typename FPBits::StorageType; + const T nan = T(FPBits::build_quiet_nan(1)); + const T inf = T(FPBits::inf()); + const T neg_inf = T(FPBits::neg_inf()); + const T zero = T(FPBits::zero()); + const T neg_zero = T(FPBits::neg_zero()); public: void test_special_numbers(Func func) { @@ -39,9 +39,9 @@ public: // Test underflow rounding up. EXPECT_FP_EQ(func(T(0.5), T(FPBits(FPBits::MIN_SUBNORMAL)), T(FPBits(FPBits::MIN_SUBNORMAL))), - T(FPBits(UIntType(2)))); + T(FPBits(StorageType(2)))); // Test underflow rounding down. - T v = T(FPBits(FPBits::MIN_NORMAL + UIntType(1))); + T v = T(FPBits(FPBits::MIN_NORMAL + StorageType(1))); EXPECT_FP_EQ(func(T(1) / T(FPBits::MIN_NORMAL << 1), v, T(FPBits(FPBits::MIN_NORMAL))), v); diff --git a/libc/test/src/math/smoke/FrexpTest.h b/libc/test/src/math/smoke/FrexpTest.h index 3ff169091cc9a38f1bf48a50f8d965c59e7a4d49..21e3fc057cdb9a0bd1e21bf6d19a519f17001c93 100644 --- a/libc/test/src/math/smoke/FrexpTest.h +++ b/libc/test/src/math/smoke/FrexpTest.h @@ -16,8 +16,9 @@ template class FrexpTest : public LIBC_NAMESPACE::testing::Test { DECLARE_SPECIAL_CONSTANTS(T) - static constexpr UIntType HIDDEN_BIT = - UIntType(1) << LIBC_NAMESPACE::fputil::MantissaWidth::VALUE; + static constexpr StorageType HIDDEN_BIT = + StorageType(1) + << LIBC_NAMESPACE::fputil::FloatProperties::FRACTION_LEN; public: typedef T (*FrexpFunc)(T, int *); diff --git a/libc/test/src/math/smoke/HypotTest.h b/libc/test/src/math/smoke/HypotTest.h index 22c2fe4d1c3593bdca09e7c58dc333e20820dd6a..308dbb50c95b78a845eddf53b00275268f21df55 100644 --- a/libc/test/src/math/smoke/HypotTest.h +++ b/libc/test/src/math/smoke/HypotTest.h @@ -20,7 +20,7 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test { private: using Func = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; const T nan = T(FPBits::build_quiet_nan(1)); const T inf = T(FPBits::inf()); const T neg_inf = T(FPBits::neg_inf()); diff --git a/libc/test/src/math/smoke/ILogbTest.h b/libc/test/src/math/smoke/ILogbTest.h index e51a5d7a2544cdc3877c8a93cb7c49d10563ddfd..9f857da5547c7d7847d5e5e1e4843a38466f57f2 100644 --- a/libc/test/src/math/smoke/ILogbTest.h +++ b/libc/test/src/math/smoke/ILogbTest.h @@ -24,15 +24,12 @@ public: template void test_special_numbers(typename ILogbFunc::Func func) { - EXPECT_EQ(FP_ILOGB0, func(T(LIBC_NAMESPACE::fputil::FPBits::zero()))); - EXPECT_EQ(FP_ILOGB0, - func(T(LIBC_NAMESPACE::fputil::FPBits::neg_zero()))); - - EXPECT_EQ(FP_ILOGBNAN, - func(T(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)))); - - EXPECT_EQ(INT_MAX, func(T(LIBC_NAMESPACE::fputil::FPBits::inf()))); - EXPECT_EQ(INT_MAX, func(T(LIBC_NAMESPACE::fputil::FPBits::neg_inf()))); + using FPBits = LIBC_NAMESPACE::fputil::FPBits; + EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero()))); + EXPECT_EQ(FP_ILOGB0, func(T(FPBits::neg_zero()))); + EXPECT_EQ(FP_ILOGBNAN, func(T(FPBits::build_quiet_nan(1)))); + EXPECT_EQ(INT_MAX, func(T(FPBits::inf()))); + EXPECT_EQ(INT_MAX, func(T(FPBits::neg_inf()))); } template @@ -77,12 +74,11 @@ public: template void test_subnormal_range(typename ILogbFunc::Func func) { using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; - constexpr UIntType COUNT = 10'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_SUBNORMAL) - UIntType(FPBits::MIN_SUBNORMAL)) / - COUNT; - for (UIntType v = FPBits::MIN_SUBNORMAL; v <= FPBits::MAX_SUBNORMAL; + using StorageType = typename FPBits::StorageType; + constexpr StorageType COUNT = 10'001; + constexpr StorageType STEP = + (FPBits::MAX_SUBNORMAL - FPBits::MIN_SUBNORMAL) / COUNT; + for (StorageType v = FPBits::MIN_SUBNORMAL; v <= FPBits::MAX_SUBNORMAL; v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0) @@ -97,11 +93,12 @@ public: template void test_normal_range(typename ILogbFunc::Func func) { using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; - constexpr UIntType COUNT = 10'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; - for (UIntType v = FPBits::MIN_NORMAL; v <= FPBits::MAX_NORMAL; v += STEP) { + using StorageType = typename FPBits::StorageType; + constexpr StorageType COUNT = 10'001; + constexpr StorageType STEP = + (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + for (StorageType v = FPBits::MIN_NORMAL; v <= FPBits::MAX_NORMAL; + v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0) continue; diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h index a75c8ef31a2cf83e9e279008eff5ec7553a0919e..5c144add3a4a3d34c5ca32def09c7b840c52ac1d 100644 --- a/libc/test/src/math/smoke/LdExpTest.h +++ b/libc/test/src/math/smoke/LdExpTest.h @@ -22,17 +22,15 @@ template class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat; - using UIntType = typename FPBits::UIntType; - static constexpr UIntType MANTISSA_WIDTH = - LIBC_NAMESPACE::fputil::MantissaWidth::VALUE; + using StorageType = typename FPBits::StorageType; // A normalized mantissa to be used with tests. - static constexpr UIntType MANTISSA = NormalFloat::ONE + 0x1234; + static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234; - const T zero = T(LIBC_NAMESPACE::fputil::FPBits::zero()); - const T neg_zero = T(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); - const T inf = T(LIBC_NAMESPACE::fputil::FPBits::inf()); - const T neg_inf = T(LIBC_NAMESPACE::fputil::FPBits::neg_inf()); - const T nan = T(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)); + const T zero = T(FPBits::zero()); + const T neg_zero = T(FPBits::neg_zero()); + const T inf = T(FPBits::inf()); + const T neg_inf = T(FPBits::neg_inf()); + const T nan = T(FPBits::build_quiet_nan(1)); public: typedef T (*LdExpFunc)(T, int); @@ -70,7 +68,7 @@ public: void testUnderflowToZeroOnNormal(LdExpFunc func) { // In this test, we pass a normal nubmer to func and expect zero // to be returned due to underflow. - int32_t base_exponent = FPBits::EXPONENT_BIAS + int32_t(MANTISSA_WIDTH); + int32_t base_exponent = FPBits::EXP_BIAS + FPBits::FRACTION_LEN; int32_t exp_array[] = {base_exponent + 5, base_exponent + 4, base_exponent + 3, base_exponent + 2, base_exponent + 1}; @@ -83,11 +81,11 @@ public: void testUnderflowToZeroOnSubnormal(LdExpFunc func) { // In this test, we pass a normal nubmer to func and expect zero // to be returned due to underflow. - int32_t base_exponent = FPBits::EXPONENT_BIAS + int32_t(MANTISSA_WIDTH); + int32_t base_exponent = FPBits::EXP_BIAS + FPBits::FRACTION_LEN; int32_t exp_array[] = {base_exponent + 5, base_exponent + 4, base_exponent + 3, base_exponent + 2, base_exponent + 1}; - T x = NormalFloat(-FPBits::EXPONENT_BIAS, MANTISSA, 0); + T x = NormalFloat(-FPBits::EXP_BIAS, MANTISSA, 0); for (int32_t exp : exp_array) { ASSERT_FP_EQ(func(x, -exp), x > 0 ? zero : neg_zero); } @@ -99,9 +97,9 @@ public: NormalFloat(100, MANTISSA, 0), NormalFloat(-100, MANTISSA, 0), NormalFloat(100, MANTISSA, 1), NormalFloat(-100, MANTISSA, 1), // Subnormal numbers - NormalFloat(-FPBits::EXPONENT_BIAS, MANTISSA, 0), - NormalFloat(-FPBits::EXPONENT_BIAS, MANTISSA, 1)}; - for (int32_t exp = 0; exp <= static_cast(MANTISSA_WIDTH); ++exp) { + NormalFloat(-FPBits::EXP_BIAS, MANTISSA, 0), + NormalFloat(-FPBits::EXP_BIAS, MANTISSA, 1)}; + for (int32_t exp = 0; exp <= FPBits::FRACTION_LEN; ++exp) { for (T x : val_array) { // We compare the result of ldexp with the result // of the native multiplication/division instruction. @@ -119,14 +117,14 @@ public: } // Normal which trigger mantissa overflow. - T x = NormalFloat(-FPBits::EXPONENT_BIAS + 1, - UIntType(2) * NormalFloat::ONE - UIntType(1), 0); + T x = NormalFloat(-FPBits::EXP_BIAS + 1, + StorageType(2) * NormalFloat::ONE - StorageType(1), 0); ASSERT_FP_EQ(func(x, -1), x / 2); ASSERT_FP_EQ(func(-x, -1), -x / 2); // Start with a normal number high exponent but pass a very low number for // exp. The result should be a subnormal number. - x = NormalFloat(FPBits::EXPONENT_BIAS, NormalFloat::ONE, 0); + x = NormalFloat(FPBits::EXP_BIAS, NormalFloat::ONE, 0); int exp = -FPBits::MAX_EXPONENT - 5; T result = func(x, exp); FPBits result_bits(result); @@ -135,12 +133,12 @@ public: ASSERT_EQ(result_bits.get_biased_exponent(), uint16_t(0)); // But if the exp is so less that normalization leads to zero, then // the result should be zero. - result = func(x, -FPBits::MAX_EXPONENT - int(MANTISSA_WIDTH) - 5); + result = func(x, -FPBits::MAX_EXPONENT - FPBits::FRACTION_LEN - 5); ASSERT_TRUE(FPBits(result).is_zero()); // Start with a subnormal number but pass a very high number for exponent. // The result should not be infinity. - x = NormalFloat(-FPBits::EXPONENT_BIAS + 1, NormalFloat::ONE >> 10, 0); + x = NormalFloat(-FPBits::EXP_BIAS + 1, NormalFloat::ONE >> 10, 0); exp = FPBits::MAX_EXPONENT + 5; ASSERT_FALSE(FPBits(func(x, exp)).is_inf()); // But if the exp is large enough to oversome than the normalization shift, diff --git a/libc/test/src/math/smoke/LogbTest.h b/libc/test/src/math/smoke/LogbTest.h index 34cf92c19ed8b1b1e7532de7bdd55f00c35cc71a..a0a01a885c104163179cabb3b1f6af27fb888e91 100644 --- a/libc/test/src/math/smoke/LogbTest.h +++ b/libc/test/src/math/smoke/LogbTest.h @@ -16,8 +16,9 @@ template class LogbTest : public LIBC_NAMESPACE::testing::Test { DECLARE_SPECIAL_CONSTANTS(T) - static constexpr UIntType HIDDEN_BIT = - UIntType(1) << LIBC_NAMESPACE::fputil::MantissaWidth::VALUE; + static constexpr StorageType HIDDEN_BIT = + StorageType(1) + << LIBC_NAMESPACE::fputil::FloatProperties::FRACTION_LEN; public: typedef T (*LogbFunc)(T); @@ -68,10 +69,10 @@ public: } void testRange(LogbFunc func) { - using UIntType = typename FPBits::UIntType; - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + using StorageType = typename FPBits::StorageType; + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = static_cast(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0l) continue; diff --git a/libc/test/src/math/smoke/ModfTest.h b/libc/test/src/math/smoke/ModfTest.h index 012a3247f92ead6228495a7ea25bf2b12aecea7a..ea7e36b67d11fa6d42dbc0c5ebcee3e2caf8206b 100644 --- a/libc/test/src/math/smoke/ModfTest.h +++ b/libc/test/src/math/smoke/ModfTest.h @@ -81,9 +81,9 @@ public: } void testRange(ModfFunc func) { - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x) || x == T(0.0)) continue; diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h index 29098e0f49a45755d9000fc12dcddecd3f6b6a1d..c301f5ebe228e12869450e63c3e984c793911d0e 100644 --- a/libc/test/src/math/smoke/NextAfterTest.h +++ b/libc/test/src/math/smoke/NextAfterTest.h @@ -31,21 +31,17 @@ template class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using MantissaWidth = LIBC_NAMESPACE::fputil::MantissaWidth; - using UIntType = typename FPBits::UIntType; - - static constexpr int BIT_WIDTH_OF_TYPE = - LIBC_NAMESPACE::fputil::FloatProperties::BIT_WIDTH; + using StorageType = typename FPBits::StorageType; const T zero = T(FPBits::zero()); const T neg_zero = T(FPBits::neg_zero()); const T inf = T(FPBits::inf()); const T neg_inf = T(FPBits::neg_inf()); const T nan = T(FPBits::build_quiet_nan(1)); - const UIntType min_subnormal = FPBits::MIN_SUBNORMAL; - const UIntType max_subnormal = FPBits::MAX_SUBNORMAL; - const UIntType min_normal = FPBits::MIN_NORMAL; - const UIntType max_normal = FPBits::MAX_NORMAL; + const StorageType min_subnormal = FPBits::MIN_SUBNORMAL; + const StorageType max_subnormal = FPBits::MAX_SUBNORMAL; + const StorageType min_normal = FPBits::MIN_NORMAL; + const StorageType max_normal = FPBits::MAX_NORMAL; public: typedef T (*NextAfterFunc)(T, T); @@ -62,12 +58,12 @@ public: // 'from' is zero|neg_zero. T x = zero; T result = func(x, T(1)); - UIntType expected_bits = 1; + StorageType expected_bits = 1; T expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); result = func(x, T(-1)); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1; + expected_bits = FPBits::SIGN_MASK + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); @@ -78,7 +74,7 @@ public: ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); result = func(x, -1); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1; + expected_bits = FPBits::SIGN_MASK + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); @@ -96,13 +92,12 @@ public: x = -x; result = func(x, -1); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal; + expected_bits = FPBits::SIGN_MASK + min_normal; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); result = func(x, 0); - expected_bits = - (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal - 1; + expected_bits = FPBits::SIGN_MASK + max_subnormal - 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); @@ -116,8 +111,7 @@ public: x = -x; result = func(x, -1); - expected_bits = - (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_subnormal + 1; + expected_bits = FPBits::SIGN_MASK + min_subnormal + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), T(-0.0)); @@ -136,12 +130,12 @@ public: x = -x; result = func(x, 0); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal; + expected_bits = FPBits::SIGN_MASK + max_subnormal; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); result = func(x, -inf); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal + 1; + expected_bits = FPBits::SIGN_MASK + min_normal + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); @@ -163,7 +157,7 @@ public: x = neg_inf; result = func(x, 0); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_normal; + expected_bits = FPBits::SIGN_MASK + max_normal; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); ASSERT_FP_EQ(func(x, neg_inf), neg_inf); @@ -175,13 +169,13 @@ public: FPBits result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), uint16_t(x_bits.get_biased_exponent() - 1)); - ASSERT_EQ(result_bits.get_mantissa(), - (UIntType(1) << MantissaWidth::VALUE) - 1); + ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK); result = func(x, T(33.0)); result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent()); - ASSERT_EQ(result_bits.get_mantissa(), x_bits.get_mantissa() + UIntType(1)); + ASSERT_EQ(result_bits.get_mantissa(), + x_bits.get_mantissa() + StorageType(1)); x = -x; @@ -189,13 +183,13 @@ public: result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), uint16_t(x_bits.get_biased_exponent() - 1)); - ASSERT_EQ(result_bits.get_mantissa(), - (UIntType(1) << MantissaWidth::VALUE) - 1); + ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK); result = func(x, T(-33.0)); result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent()); - ASSERT_EQ(result_bits.get_mantissa(), x_bits.get_mantissa() + UIntType(1)); + ASSERT_EQ(result_bits.get_mantissa(), + x_bits.get_mantissa() + StorageType(1)); } }; diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h index 111d8017e691d36841de58843b062be46f0e0c4b..359d4dea0dbc86d7a921738262c38c7e76b637a7 100644 --- a/libc/test/src/math/smoke/NextTowardTest.h +++ b/libc/test/src/math/smoke/NextTowardTest.h @@ -33,11 +33,7 @@ template class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using ToFPBits = LIBC_NAMESPACE::fputil::FPBits; - using MantissaWidth = LIBC_NAMESPACE::fputil::MantissaWidth; - using UIntType = typename FPBits::UIntType; - - static constexpr int BIT_WIDTH_OF_TYPE = - LIBC_NAMESPACE::fputil::FloatProperties::BIT_WIDTH; + using StorageType = typename FPBits::StorageType; const T zero = T(FPBits::zero()); const T neg_zero = T(FPBits::neg_zero()); @@ -49,10 +45,10 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test { const long double to_neg_zero = ToFPBits::neg_zero(); const long double to_nan = ToFPBits::build_quiet_nan(1); - const UIntType min_subnormal = FPBits::MIN_SUBNORMAL; - const UIntType max_subnormal = FPBits::MAX_SUBNORMAL; - const UIntType min_normal = FPBits::MIN_NORMAL; - const UIntType max_normal = FPBits::MAX_NORMAL; + const StorageType min_subnormal = FPBits::MIN_SUBNORMAL; + const StorageType max_subnormal = FPBits::MAX_SUBNORMAL; + const StorageType min_normal = FPBits::MIN_NORMAL; + const StorageType max_normal = FPBits::MAX_NORMAL; public: typedef T (*NextTowardFunc)(T, long double); @@ -69,12 +65,12 @@ public: // 'from' is zero|neg_zero. T x = zero; T result = func(x, 1); - UIntType expected_bits = 1; + StorageType expected_bits = 1; T expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); result = func(x, -1); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1; + expected_bits = FPBits::SIGN_MASK + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); @@ -85,7 +81,7 @@ public: ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); result = func(x, -1); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1; + expected_bits = FPBits::SIGN_MASK + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); @@ -103,13 +99,12 @@ public: x = -x; result = func(x, -1); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal; + expected_bits = FPBits::SIGN_MASK + min_normal; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); result = func(x, 0); - expected_bits = - (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal - 1; + expected_bits = FPBits::SIGN_MASK + max_subnormal - 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); @@ -123,8 +118,7 @@ public: x = -x; result = func(x, -1); - expected_bits = - (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_subnormal + 1; + expected_bits = FPBits::SIGN_MASK + min_subnormal + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), T(-0.0)); @@ -143,12 +137,12 @@ public: x = -x; result = func(x, 0); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal; + expected_bits = FPBits::SIGN_MASK + max_subnormal; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); result = func(x, -inf); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal + 1; + expected_bits = FPBits::SIGN_MASK + min_normal + 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); @@ -162,7 +156,7 @@ public: x = -x; result = func(x, 0); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_normal - 1; + expected_bits = FPBits::SIGN_MASK + max_normal - 1; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); ASSERT_FP_EQ_WITH_OVERFLOW(func(x, -inf), -inf); @@ -177,7 +171,7 @@ public: x = neg_inf; result = func(x, 0); - expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_normal; + expected_bits = FPBits::SIGN_MASK + max_normal; expected = LIBC_NAMESPACE::cpp::bit_cast(expected_bits); ASSERT_FP_EQ(result, expected); ASSERT_FP_EQ(func(x, neg_inf), neg_inf); @@ -189,13 +183,13 @@ public: FPBits result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), uint16_t(x_bits.get_biased_exponent() - 1)); - ASSERT_EQ(result_bits.get_mantissa(), - (UIntType(1) << MantissaWidth::VALUE) - 1); + ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK); result = func(x, 33.0); result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent()); - ASSERT_EQ(result_bits.get_mantissa(), x_bits.get_mantissa() + UIntType(1)); + ASSERT_EQ(result_bits.get_mantissa(), + x_bits.get_mantissa() + StorageType(1)); x = -x; @@ -203,13 +197,13 @@ public: result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), uint16_t(x_bits.get_biased_exponent() - 1)); - ASSERT_EQ(result_bits.get_mantissa(), - (UIntType(1) << MantissaWidth::VALUE) - 1); + ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK); result = func(x, -33.0); result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent()); - ASSERT_EQ(result_bits.get_mantissa(), x_bits.get_mantissa() + UIntType(1)); + ASSERT_EQ(result_bits.get_mantissa(), + x_bits.get_mantissa() + StorageType(1)); } }; diff --git a/libc/test/src/math/smoke/RIntTest.h b/libc/test/src/math/smoke/RIntTest.h index 839240fa9c98202c67c00c76acff6f590d0a2889..89dc1a59d19d648da8921915af31cb685ea9d5e6 100644 --- a/libc/test/src/math/smoke/RIntTest.h +++ b/libc/test/src/math/smoke/RIntTest.h @@ -28,7 +28,7 @@ public: private: using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; const T zero = T(FPBits::zero()); const T neg_zero = T(FPBits::neg_zero()); diff --git a/libc/test/src/math/smoke/RemQuoTest.h b/libc/test/src/math/smoke/RemQuoTest.h index 5a5d143777502351321ae86d7a97e5f5e4e31b5e..4d4a12717f0bb89c76871534c23da0eb8b02c0e9 100644 --- a/libc/test/src/math/smoke/RemQuoTest.h +++ b/libc/test/src/math/smoke/RemQuoTest.h @@ -18,13 +18,13 @@ template class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; - const T zero = T(LIBC_NAMESPACE::fputil::FPBits::zero()); - const T neg_zero = T(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); - const T inf = T(LIBC_NAMESPACE::fputil::FPBits::inf()); - const T neg_inf = T(LIBC_NAMESPACE::fputil::FPBits::neg_inf()); - const T nan = T(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)); + const T zero = T(FPBits::zero()); + const T neg_zero = T(FPBits::neg_zero()); + const T inf = T(FPBits::inf()); + const T neg_inf = T(FPBits::neg_inf()); + const T nan = T(FPBits::build_quiet_nan(1)); public: typedef T (*RemQuoFunc)(T, T, int *); diff --git a/libc/test/src/math/smoke/RoundToIntegerTest.h b/libc/test/src/math/smoke/RoundToIntegerTest.h index 31ce852fb75df2e1325c4c4e4c6313557ae46fd5..cb1ec280518ee5d83a85ce22f8b6fbef6810ed47 100644 --- a/libc/test/src/math/smoke/RoundToIntegerTest.h +++ b/libc/test/src/math/smoke/RoundToIntegerTest.h @@ -27,7 +27,7 @@ public: private: using FPBits = LIBC_NAMESPACE::fputil::FPBits; - using UIntType = typename FPBits::UIntType; + using StorageType = typename FPBits::StorageType; const F zero = F(LIBC_NAMESPACE::fputil::FPBits::zero()); const F neg_zero = F(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); @@ -109,11 +109,10 @@ public: } void testSubnormalRange(RoundToIntegerFunc func) { - constexpr UIntType COUNT = 1'000'001; - constexpr UIntType STEP = - (UIntType(FPBits::MAX_SUBNORMAL) - UIntType(FPBits::MIN_SUBNORMAL)) / - COUNT; - for (UIntType i = FPBits::MIN_SUBNORMAL; i <= FPBits::MAX_SUBNORMAL; + constexpr StorageType COUNT = 1'000'001; + constexpr StorageType STEP = + (FPBits::MAX_SUBNORMAL - FPBits::MIN_SUBNORMAL) / COUNT; + for (StorageType i = FPBits::MIN_SUBNORMAL; i <= FPBits::MAX_SUBNORMAL; i += STEP) { F x = F(FPBits(i)); if (x == F(0.0)) diff --git a/libc/test/src/math/smoke/SqrtTest.h b/libc/test/src/math/smoke/SqrtTest.h index d4b2f9dd2624f1d1e10ad62bdf93c53bcae621b8..5e8e099f90f54eeaae9d5557b2221aa084586359 100644 --- a/libc/test/src/math/smoke/SqrtTest.h +++ b/libc/test/src/math/smoke/SqrtTest.h @@ -16,8 +16,9 @@ template class SqrtTest : public LIBC_NAMESPACE::testing::Test { DECLARE_SPECIAL_CONSTANTS(T) - static constexpr UIntType HIDDEN_BIT = - UIntType(1) << LIBC_NAMESPACE::fputil::MantissaWidth::VALUE; + static constexpr StorageType HIDDEN_BIT = + StorageType(1) + << LIBC_NAMESPACE::fputil::FloatProperties::FRACTION_LEN; public: typedef T (*SqrtFunc)(T); diff --git a/libc/test/src/math/tan_test.cpp b/libc/test/src/math/tan_test.cpp index b35658cc50f8a8485f4204ee388e3ce9a4688351..8fae425f96f8f2243e9070ea28bc36207c7f2398 100644 --- a/libc/test/src/math/tan_test.cpp +++ b/libc/test/src/math/tan_test.cpp @@ -19,9 +19,9 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr; TEST_F(LlvmLibcTanTest, Range) { static constexpr double _2pi = 6.283185307179586; - constexpr UIntType COUNT = 100'000; - constexpr UIntType STEP = UIntType(-1) / COUNT; - for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + constexpr StorageType COUNT = 100'000; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { double x = double(FPBits(v)); // TODO: Expand the range of testing after range reduction is implemented. if (isnan(x) || isinf(x) || x > _2pi || x < -_2pi) diff --git a/libc/test/src/string/mempcpy_test.cpp b/libc/test/src/string/mempcpy_test.cpp index 43ad5a0f3e1b7e3fdf8bfdfa0c149c7df2c7ff31..877ee8104880eb66881cdfcaa27918c1a776414b 100644 --- a/libc/test/src/string/mempcpy_test.cpp +++ b/libc/test/src/string/mempcpy_test.cpp @@ -14,7 +14,7 @@ // mempcpy behavior (returning the end of what was copied). TEST(LlvmLibcMempcpyTest, Simple) { const char *src = "12345"; - char dest[10]; + char dest[10] = {}; void *result = LIBC_NAMESPACE::mempcpy(dest, src, 6); ASSERT_EQ(static_cast(result), dest + 6); ASSERT_STREQ(src, dest); diff --git a/libc/test/src/sys/resource/getrlimit_setrlimit_test.cpp b/libc/test/src/sys/resource/getrlimit_setrlimit_test.cpp index 7e6bb0aaca92518f0f465c9df7174b2f28d16909..0870deeeb5d801076a8fbe1af489be46dd999cb7 100644 --- a/libc/test/src/sys/resource/getrlimit_setrlimit_test.cpp +++ b/libc/test/src/sys/resource/getrlimit_setrlimit_test.cpp @@ -17,6 +17,7 @@ #include "test/UnitTest/Test.h" #include +#include TEST(LlvmLibcResourceLimitsTest, SetNoFileLimit) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; diff --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt index 4380597e5515799083bb4d90489c8c12a59a4ab8..666dc28c7e4ee199f955b013c645b6fe0e91bd95 100644 --- a/libc/test/src/sys/socket/linux/CMakeLists.txt +++ b/libc/test/src/sys/socket/linux/CMakeLists.txt @@ -12,3 +12,19 @@ add_libc_unittest( libc.src.sys.socket.socket libc.src.unistd.close ) + + +add_libc_unittest( + bind_test + SUITE + libc_sys_socket_unittests + SRCS + bind_test.cpp + DEPENDS + libc.include.sys_socket + libc.src.errno.errno + libc.src.sys.socket.socket + libc.src.sys.socket.bind + libc.src.stdio.remove + libc.src.unistd.close +) diff --git a/libc/test/src/sys/socket/linux/bind_test.cpp b/libc/test/src/sys/socket/linux/bind_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5a3a1c227c9b58efca1851737dad9f317ea614b1 --- /dev/null +++ b/libc/test/src/sys/socket/linux/bind_test.cpp @@ -0,0 +1,55 @@ +//===-- Unittests for bind ------------------------------------------------===// +// +// 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 "src/sys/socket/bind.h" +#include "src/sys/socket/socket.h" + +#include "src/stdio/remove.h" +#include "src/unistd/close.h" + +#include "src/errno/libc_errno.h" +#include "test/UnitTest/LibcTest.h" +#include "test/UnitTest/Test.h" + +#include // For AF_UNIX and SOCK_DGRAM + +TEST(LlvmLibcSocketTest, BindLocalSocket) { + + const char *FILENAME = "bind_file.test"; + auto SOCK_PATH = libc_make_test_file_path(FILENAME); + + int sock = LIBC_NAMESPACE::socket(AF_UNIX, SOCK_DGRAM, 0); + ASSERT_GE(sock, 0); + ASSERT_EQ(libc_errno, 0); + + struct sockaddr_un my_addr; + + my_addr.sun_family = AF_UNIX; + unsigned int i = 0; + for (; + SOCK_PATH[i] != '\0' && (i < sizeof(sockaddr_un) - sizeof(sa_family_t)); + ++i) + my_addr.sun_path[i] = SOCK_PATH[i]; + my_addr.sun_path[i] = '\0'; + + // It's important that the path fits in the struct, if it doesn't then we + // can't try to bind to the file. + ASSERT_LT( + i, static_cast(sizeof(sockaddr_un) - sizeof(sa_family_t))); + + int result = + LIBC_NAMESPACE::bind(sock, reinterpret_cast(&my_addr), + sizeof(struct sockaddr_un)); + + ASSERT_EQ(result, 0); + ASSERT_EQ(libc_errno, 0); + + LIBC_NAMESPACE::close(sock); + + LIBC_NAMESPACE::remove(SOCK_PATH); +} diff --git a/libc/test/src/sys/socket/linux/socket_test.cpp b/libc/test/src/sys/socket/linux/socket_test.cpp index 9037888441a357f674db0a40843e1e9d94a2205f..9d5bfacde0a4099344d186fc5502aacdbcd3d740 100644 --- a/libc/test/src/sys/socket/linux/socket_test.cpp +++ b/libc/test/src/sys/socket/linux/socket_test.cpp @@ -13,10 +13,10 @@ #include "src/errno/libc_errno.h" #include "test/UnitTest/Test.h" -#include // For AF_LOCAL and SOCK_DGRAM +#include // For AF_UNIX and SOCK_DGRAM TEST(LlvmLibcSocketTest, LocalSocket) { - int sock = LIBC_NAMESPACE::socket(AF_LOCAL, SOCK_DGRAM, 0); + int sock = LIBC_NAMESPACE::socket(AF_UNIX, SOCK_DGRAM, 0); ASSERT_GE(sock, 0); ASSERT_EQ(libc_errno, 0); diff --git a/libc/test/src/unistd/access_test.cpp b/libc/test/src/unistd/access_test.cpp index ed1fe96f4f4a1672312168bd678733516f4a4ee9..7d4b3be443fed492146df25d4238e5e0735f8f74 100644 --- a/libc/test/src/unistd/access_test.cpp +++ b/libc/test/src/unistd/access_test.cpp @@ -14,6 +14,7 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include #include TEST(LlvmLibcAccessTest, CreateAndTest) { diff --git a/libc/test/src/unistd/dup2_test.cpp b/libc/test/src/unistd/dup2_test.cpp index ff870db0334c93dca4086650484583a1e5ed5481..d46c4b919ce72cb315ee5bb7b0445d940d2d898c 100644 --- a/libc/test/src/unistd/dup2_test.cpp +++ b/libc/test/src/unistd/dup2_test.cpp @@ -16,6 +16,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcdupTest, ReadAndWriteViaDup) { constexpr int DUPFD = 0xD0; libc_errno = 0; diff --git a/libc/test/src/unistd/dup3_test.cpp b/libc/test/src/unistd/dup3_test.cpp index 279cfbfea1b144be6a3b1e0bcd3f8b28d2cc8f02..d2d544d5d9a12f854b308eeed99f8bdbbbe7e2d2 100644 --- a/libc/test/src/unistd/dup3_test.cpp +++ b/libc/test/src/unistd/dup3_test.cpp @@ -16,6 +16,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + // The tests here are exactly the same as those of dup2. We only test the // plumbing of the dup3 syscall and not the dup3 functionality itself as it is // a simple syscall wrapper. Testing dup3 functionality is beyond the scope of diff --git a/libc/test/src/unistd/dup_test.cpp b/libc/test/src/unistd/dup_test.cpp index 38c439125db3d7bb65bf81f2318f2449abe8f0d7..856b004fbe65d58f74464305a63e051262e5db61 100644 --- a/libc/test/src/unistd/dup_test.cpp +++ b/libc/test/src/unistd/dup_test.cpp @@ -16,6 +16,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcdupTest, ReadAndWriteViaDup) { libc_errno = 0; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; diff --git a/libc/test/src/unistd/ftruncate_test.cpp b/libc/test/src/unistd/ftruncate_test.cpp index ae743b385e220dbe611e230c0f737e61185c760b..fc68348e32ec6672987ceb6090bd47d4fa59dbf1 100644 --- a/libc/test/src/unistd/ftruncate_test.cpp +++ b/libc/test/src/unistd/ftruncate_test.cpp @@ -17,6 +17,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + namespace cpp = LIBC_NAMESPACE::cpp; TEST(LlvmLibcFtruncateTest, CreateAndTruncate) { diff --git a/libc/test/src/unistd/isatty_test.cpp b/libc/test/src/unistd/isatty_test.cpp index fce4a3e5f5062aa383a8ff7ece89cf3644804a92..7bf8dd708bfa6f371523e890cc198c5fd9a6ad01 100644 --- a/libc/test/src/unistd/isatty_test.cpp +++ b/libc/test/src/unistd/isatty_test.cpp @@ -13,6 +13,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; diff --git a/libc/test/src/unistd/link_test.cpp b/libc/test/src/unistd/link_test.cpp index b1b9383cb62ee07f7abcd16f88e51849a498f06b..2d5aa7588b08b902e761755666161f99c98d4ffb 100644 --- a/libc/test/src/unistd/link_test.cpp +++ b/libc/test/src/unistd/link_test.cpp @@ -14,6 +14,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcLinkTest, CreateAndUnlink) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; constexpr const char *TEST_FILE = "testdata/link.test"; diff --git a/libc/test/src/unistd/linkat_test.cpp b/libc/test/src/unistd/linkat_test.cpp index 2ef41cd4e75f6a7840b85ce93a12ed0257518e39..d1ffe37d63b48c71573e57323196ad8eca168fb4 100644 --- a/libc/test/src/unistd/linkat_test.cpp +++ b/libc/test/src/unistd/linkat_test.cpp @@ -14,6 +14,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcLinkatTest, CreateAndUnlink) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; constexpr const char *TEST_DIR = "testdata"; diff --git a/libc/test/src/unistd/pread_pwrite_test.cpp b/libc/test/src/unistd/pread_pwrite_test.cpp index 6819f559424f3e03eea69248552b013ce1e3974b..f90d1341c20108abd955176c9335edd9d6b58e97 100644 --- a/libc/test/src/unistd/pread_pwrite_test.cpp +++ b/libc/test/src/unistd/pread_pwrite_test.cpp @@ -17,6 +17,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcUniStd, PWriteAndPReadBackTest) { // The strategy here is that we first create a file and write to it. Next, // we open that file again and write at an offset. Finally, we open the diff --git a/libc/test/src/unistd/read_write_test.cpp b/libc/test/src/unistd/read_write_test.cpp index 20b51bb8082b1209c84912ecaae3b571f32c98d0..3007d4c38711579e1c99896178fd57cdbc0e5b36 100644 --- a/libc/test/src/unistd/read_write_test.cpp +++ b/libc/test/src/unistd/read_write_test.cpp @@ -15,6 +15,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcUniStd, WriteAndReadBackTest) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; constexpr const char *TEST_FILE = "__unistd_read_write.test"; diff --git a/libc/test/src/unistd/symlink_test.cpp b/libc/test/src/unistd/symlink_test.cpp index 84d963b7a207ce8f86d2a68cdb4bcdc26384c9e4..b25cfa4f857699592808c051c3f19ce1e8523e3b 100644 --- a/libc/test/src/unistd/symlink_test.cpp +++ b/libc/test/src/unistd/symlink_test.cpp @@ -14,6 +14,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcSymlinkTest, CreateAndUnlink) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; constexpr const char *TEST_FILE_BASE = "symlink.test"; diff --git a/libc/test/src/unistd/symlinkat_test.cpp b/libc/test/src/unistd/symlinkat_test.cpp index b0308787f2052a2644fd80648c283f140acf1d78..8aba2daee8cf3830431ad06d12c90adfbf5ad2f2 100644 --- a/libc/test/src/unistd/symlinkat_test.cpp +++ b/libc/test/src/unistd/symlinkat_test.cpp @@ -14,6 +14,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcSymlinkatTest, CreateAndUnlink) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; constexpr const char *TEST_DIR = "testdata"; diff --git a/libc/test/src/unistd/syscall_test.cpp b/libc/test/src/unistd/syscall_test.cpp index 211b27c3188c4d89e06fbdecd11bef497177d8fd..6a5ca47f8d494a8fc19ca58f64db206aab0e1570 100644 --- a/libc/test/src/unistd/syscall_test.cpp +++ b/libc/test/src/unistd/syscall_test.cpp @@ -12,6 +12,7 @@ #include "test/UnitTest/Test.h" #include +#include // For S_* flags. #include // For syscall numbers. #include diff --git a/libc/test/src/unistd/truncate_test.cpp b/libc/test/src/unistd/truncate_test.cpp index 15940321e5ad456a7e12054a4cb9ede727bb88cf..6d8a3b8e53f7281e08b474bf6fcd9138d2b10a27 100644 --- a/libc/test/src/unistd/truncate_test.cpp +++ b/libc/test/src/unistd/truncate_test.cpp @@ -17,6 +17,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + namespace cpp = LIBC_NAMESPACE::cpp; TEST(LlvmLibcTruncateTest, CreateAndTruncate) { diff --git a/libc/test/src/unistd/unlink_test.cpp b/libc/test/src/unistd/unlink_test.cpp index 8a64f88ee6f26db0b59f0a965bd691745f6fc4b2..77f65b5ecc6a1a12d9c00c4e587b0d0f9c5c1da0 100644 --- a/libc/test/src/unistd/unlink_test.cpp +++ b/libc/test/src/unistd/unlink_test.cpp @@ -13,6 +13,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcUnlinkTest, CreateAndUnlink) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; constexpr const char *TEST_FILE = "testdata/unlink.test"; diff --git a/libc/test/src/unistd/unlinkat_test.cpp b/libc/test/src/unistd/unlinkat_test.cpp index 5953085bf12b66ca7379223f511a18378f5bf7f7..22a20bc6ad07bce4cf23cdb3dab45da6a2f2e623 100644 --- a/libc/test/src/unistd/unlinkat_test.cpp +++ b/libc/test/src/unistd/unlinkat_test.cpp @@ -14,6 +14,8 @@ #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" +#include + TEST(LlvmLibcUnlinkatTest, CreateAndDeleteTest) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; constexpr const char *TEST_DIR = "testdata"; diff --git a/libc/utils/HdrGen/Generator.cpp b/libc/utils/HdrGen/Generator.cpp index 24d22680fe525bad1a40a0b64498a66a98320c86..3bcf005adda74fc61e72ea85c3477e9353b6574b 100644 --- a/libc/utils/HdrGen/Generator.cpp +++ b/libc/utils/HdrGen/Generator.cpp @@ -57,7 +57,7 @@ void Generator::parseCommandArgs(llvm::StringRef ArgStr, ArgVector &Args) { ArgStr.split(Args, ","); for (llvm::StringRef &A : Args) { A = A.trim(' '); - if (A.startswith(ParamNamePrefix) && A.endswith(ParamNameSuffix)) { + if (A.starts_with(ParamNamePrefix) && A.ends_with(ParamNameSuffix)) { A = A.drop_front(ParamNamePrefixSize).drop_back(ParamNameSuffixSize); A = ArgMap[std::string(A)]; } @@ -80,7 +80,7 @@ void Generator::generate(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) { Content = P.second; llvm::StringRef Line = P.first.trim(' '); - if (Line.startswith(CommandPrefix)) { + if (Line.starts_with(CommandPrefix)) { Line = Line.drop_front(CommandPrefixSize); P = Line.split("("); @@ -107,7 +107,7 @@ void Generator::generate(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) { Command::ErrorReporter Reporter( llvm::SMLoc::getFromPointer(CommandName.data()), SrcMgr); Cmd->run(OS, Args, StdHeader, Records, Reporter); - } else if (!Line.startswith(CommentPrefix)) { + } else if (!Line.starts_with(CommentPrefix)) { // There is no comment or command on this line so we just write it as is. OS << P.first << "\n"; } diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp index e3dffadf4ed9674fae495f71cebf6927d4366dc0..6b9400ea453ffdf8141f9c0e3f1427b36c0d7683 100644 --- a/libc/utils/MPFRWrapper/MPFRUtils.cpp +++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp @@ -450,17 +450,17 @@ public: return MPFRNumber(0.0); if (is_nan()) { - if (fputil::FPBits(input).is_nan()) + if (FPBits(input).is_nan()) return MPFRNumber(0.0); - return MPFRNumber(static_cast(fputil::FPBits::inf())); + return MPFRNumber(static_cast(FPBits::inf())); } - int thisExponent = fputil::FPBits(thisAsT).get_exponent(); - int inputExponent = fputil::FPBits(input).get_exponent(); + int thisExponent = FPBits(thisAsT).get_exponent(); + int inputExponent = FPBits(input).get_exponent(); // Adjust the exponents for denormal numbers. - if (fputil::FPBits(thisAsT).get_biased_exponent() == 0) + if (FPBits(thisAsT).get_biased_exponent() == 0) ++thisExponent; - if (fputil::FPBits(input).get_biased_exponent() == 0) + if (FPBits(input).get_biased_exponent() == 0) ++inputExponent; if (thisAsT * input < 0 || thisExponent == inputExponent) { @@ -468,8 +468,7 @@ public: mpfr_sub(inputMPFR.value, value, inputMPFR.value, MPFR_RNDN); mpfr_abs(inputMPFR.value, inputMPFR.value, MPFR_RNDN); mpfr_mul_2si(inputMPFR.value, inputMPFR.value, - -thisExponent + int(fputil::MantissaWidth::VALUE), - MPFR_RNDN); + -thisExponent + FPBits::FRACTION_LEN, MPFR_RNDN); return inputMPFR; } @@ -480,12 +479,12 @@ public: input = std::abs(input); T min = thisAsT > input ? input : thisAsT; T max = thisAsT > input ? thisAsT : input; - int minExponent = fputil::FPBits(min).get_exponent(); - int maxExponent = fputil::FPBits(max).get_exponent(); + int minExponent = FPBits(min).get_exponent(); + int maxExponent = FPBits(max).get_exponent(); // Adjust the exponents for denormal numbers. - if (fputil::FPBits(min).get_biased_exponent() == 0) + if (FPBits(min).get_biased_exponent() == 0) ++minExponent; - if (fputil::FPBits(max).get_biased_exponent() == 0) + if (FPBits(max).get_biased_exponent() == 0) ++maxExponent; MPFRNumber minMPFR(min); @@ -496,13 +495,11 @@ public: mpfr_sub(minMPFR.value, pivot.value, minMPFR.value, MPFR_RNDN); mpfr_mul_2si(minMPFR.value, minMPFR.value, - -minExponent + int(fputil::MantissaWidth::VALUE), - MPFR_RNDN); + -minExponent + FPBits::FRACTION_LEN, MPFR_RNDN); mpfr_sub(maxMPFR.value, maxMPFR.value, pivot.value, MPFR_RNDN); mpfr_mul_2si(maxMPFR.value, maxMPFR.value, - -maxExponent + int(fputil::MantissaWidth::VALUE), - MPFR_RNDN); + -maxExponent + FPBits::FRACTION_LEN, MPFR_RNDN); mpfr_add(minMPFR.value, minMPFR.value, maxMPFR.value, MPFR_RNDN); return minMPFR; diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 7751bf1efc59d202427f1a9bc48a490b8e9f1034..75cb63222da35c52aaa5f9b8c084216e143809bf 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -651,6 +651,19 @@ get_sanitizer_flags(SANITIZER_FLAGS "${LLVM_USE_SANITIZER}") add_library(cxx-sanitizer-flags INTERFACE) target_compile_options(cxx-sanitizer-flags INTERFACE ${SANITIZER_FLAGS}) +# _LIBCPP_INSTRUMENTED_WITH_ASAN informs that library was built with ASan. +# Defining _LIBCPP_INSTRUMENTED_WITH_ASAN while building the library with ASan is required. +# Normally, the _LIBCPP_INSTRUMENTED_WITH_ASAN flag is used to keep information whether +# dylibs are built with AddressSanitizer. However, when building libc++, +# this flag needs to be defined so that the resulting dylib has all ASan functionalities guarded by this flag. +# If the _LIBCPP_INSTRUMENTED_WITH_ASAN flag is not defined, then parts of the ASan instrumentation code in libc++ +# will not be compiled into it, resulting in false positives. +# For context, read: https://github.com/llvm/llvm-project/pull/72677#pullrequestreview-1765402800 +string(FIND "${LLVM_USE_SANITIZER}" "Address" building_with_asan) +if (NOT "${building_with_asan}" STREQUAL "-1") + config_define(ON _LIBCPP_INSTRUMENTED_WITH_ASAN) +endif() + # Link system libraries ======================================================= function(cxx_link_system_libraries target) if (NOT MSVC) @@ -664,15 +677,17 @@ function(cxx_link_system_libraries target) target_add_link_flags_if_supported(${target} PRIVATE "--unwindlib=none") endif() - if (LIBCXX_USE_COMPILER_RT) - find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY) - if (LIBCXX_BUILTINS_LIBRARY) - target_link_libraries(${target} PRIVATE "${LIBCXX_BUILTINS_LIBRARY}") + if (MSVC) + if (LIBCXX_USE_COMPILER_RT) + find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY) + if (LIBCXX_BUILTINS_LIBRARY) + target_link_libraries(${target} PRIVATE "${LIBCXX_BUILTINS_LIBRARY}") + endif() + elseif (LIBCXX_HAS_GCC_LIB) + target_link_libraries(${target} PRIVATE gcc) + elseif (LIBCXX_HAS_GCC_S_LIB) + target_link_libraries(${target} PRIVATE gcc_s) endif() - elseif (LIBCXX_HAS_GCC_LIB) - target_link_libraries(${target} PRIVATE gcc) - elseif (LIBCXX_HAS_GCC_S_LIB) - target_link_libraries(${target} PRIVATE gcc_s) endif() if (LIBCXX_HAS_ATOMIC_LIB) diff --git a/libcxx/benchmarks/algorithms/find.bench.cpp b/libcxx/benchmarks/algorithms/find.bench.cpp index b87c575a16b4dcdc8f0d7e0b40407aa0ef10e1c3..6ff2d95ab43533325dd5c331d363f1a1f3c45bf9 100644 --- a/libcxx/benchmarks/algorithms/find.bench.cpp +++ b/libcxx/benchmarks/algorithms/find.bench.cpp @@ -9,12 +9,15 @@ #include #include #include +#include #include #include -template +template static void bm_find(benchmark::State& state) { - std::vector vec1(state.range(), '1'); + using T = Container::value_type; + + Container vec1(state.range(), '1'); std::mt19937_64 rng(std::random_device{}()); for (auto _ : state) { @@ -25,13 +28,18 @@ static void bm_find(benchmark::State& state) { vec1[idx] = '1'; } } -BENCHMARK(bm_find)->DenseRange(1, 8)->Range(16, 1 << 20); -BENCHMARK(bm_find)->DenseRange(1, 8)->Range(16, 1 << 20); -BENCHMARK(bm_find)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_find>)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_find>)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_find>)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_find>)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_find>)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_find>)->DenseRange(1, 8)->Range(16, 1 << 20); -template +template static void bm_ranges_find(benchmark::State& state) { - std::vector vec1(state.range(), '1'); + using T = Container::value_type; + + Container vec1(state.range(), '1'); std::mt19937_64 rng(std::random_device{}()); for (auto _ : state) { @@ -42,9 +50,12 @@ static void bm_ranges_find(benchmark::State& state) { vec1[idx] = '1'; } } -BENCHMARK(bm_ranges_find)->DenseRange(1, 8)->Range(16, 1 << 20); -BENCHMARK(bm_ranges_find)->DenseRange(1, 8)->Range(16, 1 << 20); -BENCHMARK(bm_ranges_find)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_ranges_find>)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_ranges_find>)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_ranges_find>)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_ranges_find>)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_ranges_find>)->DenseRange(1, 8)->Range(16, 1 << 20); +BENCHMARK(bm_ranges_find>)->DenseRange(1, 8)->Range(16, 1 << 20); static void bm_vector_bool_find(benchmark::State& state) { std::vector vec1(state.range(), false); diff --git a/libcxx/cmake/caches/Armv7M-picolibc.cmake b/libcxx/cmake/caches/Armv7M-picolibc.cmake index 9f8863943444b6518a98db29f774c72965499dfa..91cc32fd376e300b3acecf0fef74db415dbb8650 100644 --- a/libcxx/cmake/caches/Armv7M-picolibc.cmake +++ b/libcxx/cmake/caches/Armv7M-picolibc.cmake @@ -13,17 +13,18 @@ set(COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "") set(COMPILER_RT_DEFAULT_TARGET_ONLY ON CACHE BOOL "") set(LIBCXXABI_BAREMETAL ON CACHE BOOL "") set(LIBCXXABI_ENABLE_ASSERTIONS OFF CACHE BOOL "") -set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_EXCEPTIONS ON CACHE BOOL "") set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") set(LIBCXXABI_ENABLE_STATIC ON CACHE BOOL "") +set(LIBCXXABI_ENABLE_STATIC_UNWINDER ON CACHE BOOL "") set(LIBCXXABI_ENABLE_THREADS OFF CACHE BOOL "") set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") -set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "") +set(LIBCXX_ENABLE_EXCEPTIONS ON CACHE BOOL "") set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE STRING "") set(LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "") set(LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "") -set(LIBCXX_ENABLE_RTTI OFF CACHE BOOL "") +set(LIBCXX_ENABLE_RTTI ON CACHE BOOL "") set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") set(LIBCXX_ENABLE_STATIC ON CACHE BOOL "") set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "") diff --git a/libcxx/cmake/caches/Generic-no-tzdb.cmake b/libcxx/cmake/caches/Generic-no-tzdb.cmake index 27c826edfecffbb6bcb38421f70c59d72e66aaa2..c5dc882e584428cb695652a8ffb8059eb092dfe2 100644 --- a/libcxx/cmake/caches/Generic-no-tzdb.cmake +++ b/libcxx/cmake/caches/Generic-no-tzdb.cmake @@ -1 +1,2 @@ +set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_ENABLE_TIME_ZONE_DATABASE OFF CACHE BOOL "") diff --git a/libcxx/cmake/config-ix.cmake b/libcxx/cmake/config-ix.cmake index a365517936e7565abb0db90ac5fc55072eb11f8b..1e8c2f5ce463213b572af12c23be28a4811bbfd8 100644 --- a/libcxx/cmake/config-ix.cmake +++ b/libcxx/cmake/config-ix.cmake @@ -45,7 +45,9 @@ else() endif() endif() -if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) +# Only link against compiler-rt manually if we use -nodefaultlibs, since +# otherwise the compiler will do the right thing on its own. +if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG AND C_SUPPORTS_NODEFAULTLIBS_FLAG) if (LIBCXX_USE_COMPILER_RT) include(HandleCompilerRT) find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY @@ -73,6 +75,9 @@ if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) moldname mingwex msvcrt) list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES}) endif() +endif() + +if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all") endif () diff --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv index 13c126c1ba8be2a5e5638e3b6820ec6ba9c32bf5..d73088687975c27750446cd4d0eb9379bd389113 100644 --- a/libcxx/docs/Status/Cxx20Papers.csv +++ b/libcxx/docs/Status/Cxx20Papers.csv @@ -23,7 +23,7 @@ "`P0754R2 `__","LWG","","Jacksonville","|Complete|","7.0" "`P0809R0 `__","LWG","Comparing Unordered Containers","Jacksonville","|Nothing To Do|","" "`P0858R0 `__","LWG","Constexpr iterator requirements","Jacksonville","|Complete|","12.0" -"`P0905R1 `__","CWG","Symmetry for spaceship","Jacksonville","","" +"`P0905R1 `__","CWG","Symmetry for spaceship","Jacksonville","","","|spaceship|" "`P0966R1 `__","LWG","``string::reserve``\ Should Not Shrink","Jacksonville","|Complete| [#note-P0966]_","12.0" "","","","","","","" "`P0019R8 `__","LWG","Atomic Ref","Rapperswil","","" @@ -48,7 +48,7 @@ "`P0941R2 `__","CWG","Integrating feature-test macros into the C++ WD","Rapperswil","|In Progress|","" "`P1023R0 `__","LWG","constexpr comparison operators for std::array","Rapperswil","|Complete|","8.0" "`P1025R1 `__","CWG","Update The Reference To The Unicode Standard","Rapperswil","","" -"`P1120R0 `__","CWG","Consistency improvements for <=> and other comparison operators","Rapperswil","","" +"`P1120R0 `__","CWG","Consistency improvements for <=> and other comparison operators","Rapperswil","","","|spaceship|" "","","","","","","" "`P0318R1 `__","LWG","unwrap_ref_decay and unwrap_reference","San Diego","|Complete|","8.0" "`P0356R5 `__","LWG","Simplified partial function application","San Diego","|Complete|","13.0" diff --git a/libcxx/docs/Status/SpaceshipPapers.csv b/libcxx/docs/Status/SpaceshipPapers.csv index 26f10080af2b5943e773a1dcdeec2cb5b45fd8d0..09fc67b04c91bec1b148a465311fe2d0a39f3ea6 100644 --- a/libcxx/docs/Status/SpaceshipPapers.csv +++ b/libcxx/docs/Status/SpaceshipPapers.csv @@ -7,3 +7,5 @@ `LWG3360 `_,three_way_comparable_with is inconsistent with similar concepts,|Nothing To Do|, `LWG3380 `_,common_type and comparison categories,|Nothing To Do|, `LWG3395 `_,Definition for three-way comparison needs to be updated,|Nothing To Do|, +`P0905R1 `_,Symmetry for spaceship,, +`P1120R0 `_,Consistency improvements for <=> and other comparison operators,, diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst index e8b4a95dbcffae15126aef3c55072041df8180ec..c7769bae6bb17d809c849c9c08fd337630e56a9b 100644 --- a/libcxx/docs/index.rst +++ b/libcxx/docs/index.rst @@ -202,6 +202,11 @@ Design Documents Build Bots and Test Coverage ============================ +.. image:: https://github.com/llvm/llvm-project/actions/workflows/libcxx-build-and-test.yaml/badge.svg?branch=main&event=schedule + :target: https://github.com/llvm/llvm-project/actions/workflows/libcxx-build-and-test.yaml?query=event%3Aschedule + :alt: Build and Test libc++ + +* `Github Actions CI pipeline `_ * `Buildkite CI pipeline `_ * `LLVM Buildbot Builders `_ * :ref:`Adding New CI Jobs ` diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 533b7ac9103ab01175771e6f4371c78a0dd99d9b..7d0defa26b0f73c9b07ff8e17905bf4a7e87c4b4 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -22,6 +22,7 @@ set(files __algorithm/find_first_of.h __algorithm/find_if.h __algorithm/find_if_not.h + __algorithm/find_segment_if.h __algorithm/for_each.h __algorithm/for_each_n.h __algorithm/for_each_segment.h diff --git a/libcxx/include/__algorithm/binary_search.h b/libcxx/include/__algorithm/binary_search.h index 5a1d49f5f43e27ddb0e9a6b05e1b020652a93a40..7a77d7b5447bda7ce988e7534582d4c9b07919e2 100644 --- a/libcxx/include/__algorithm/binary_search.h +++ b/libcxx/include/__algorithm/binary_search.h @@ -22,22 +22,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) -{ - __first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp); - return __first != __last && !__comp(__value, *__first); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + __first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp); + return __first != __last && !__comp(__value, *__first); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - return std::binary_search(__first, __last, __value, __less<>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::binary_search(__first, __last, __value, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/comp_ref_type.h b/libcxx/include/__algorithm/comp_ref_type.h index 2797e9da6658504349b001ecd0601675b6baa696..15f4a535a30bf0d97c17004537fb2328bdcbcc34 100644 --- a/libcxx/include/__algorithm/comp_ref_type.h +++ b/libcxx/include/__algorithm/comp_ref_type.h @@ -20,52 +20,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -struct __debug_less -{ - _Compare &__comp_; - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {} +struct __debug_less { + _Compare& __comp_; + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {} - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x, const _Up& __y) - { - bool __r = __comp_(__x, __y); - if (__r) - __do_compare_assert(0, __y, __x); - return __r; - } + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Up& __y) { + bool __r = __comp_(__x, __y); + if (__r) + __do_compare_assert(0, __y, __x); + return __r; + } - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(_Tp& __x, _Up& __y) - { - bool __r = __comp_(__x, __y); - if (__r) - __do_compare_assert(0, __y, __x); - return __r; - } + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(_Tp& __x, _Up& __y) { + bool __r = __comp_(__x, __y); + if (__r) + __do_compare_assert(0, __y, __x); + return __r; + } - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 - inline _LIBCPP_HIDE_FROM_ABI - decltype((void)std::declval<_Compare&>()( - std::declval<_LHS &>(), std::declval<_RHS &>())) - __do_compare_assert(int, _LHS & __l, _RHS & __r) { - _LIBCPP_ASSERT_UNCATEGORIZED(!__comp_(__l, __r), - "Comparator does not induce a strict weak ordering"); - (void)__l; - (void)__r; - } + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI decltype((void)std::declval<_Compare&>()( + std::declval<_LHS&>(), std::declval<_RHS&>())) + __do_compare_assert(int, _LHS& __l, _RHS& __r) { + _LIBCPP_ASSERT_UNCATEGORIZED(!__comp_(__l, __r), "Comparator does not induce a strict weak ordering"); + (void)__l; + (void)__r; + } - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 - inline _LIBCPP_HIDE_FROM_ABI - void __do_compare_assert(long, _LHS &, _RHS &) {} + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI void __do_compare_assert(long, _LHS&, _RHS&) {} }; // Pass the comparator by lvalue reference. Or in debug mode, using a // debugging wrapper that stores a reference. -# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG +#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG template using __comp_ref_type = __debug_less<_Comp>; #else diff --git a/libcxx/include/__algorithm/copy_backward.h b/libcxx/include/__algorithm/copy_backward.h index d85d297b3226ccb8e594353968caa5466e4b94c1..3ec88d8bd5cc3a6a6656c3cc0d6f3fc6f4919dac 100644 --- a/libcxx/include/__algorithm/copy_backward.h +++ b/libcxx/include/__algorithm/copy_backward.h @@ -108,8 +108,7 @@ struct __copy_backward_loop { struct __copy_backward_trivial { // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. - template ::value, int> = 0> + template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> operator()(_In* __first, _In* __last, _Out* __result) const { return std::__copy_backward_trivial_impl(__first, __last, __result); @@ -124,16 +123,13 @@ __copy_backward(_BidirectionalIterator1 __first, _Sentinel __last, _Bidirectiona } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_BidirectionalIterator2 -copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, - _BidirectionalIterator2 __result) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2 +copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && - std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); + std::is_copy_constructible<_BidirectionalIterator1>::value, + "Iterators must be copy constructible."); - return std::__copy_backward<_ClassicAlgPolicy>( - std::move(__first), std::move(__last), std::move(__result)).second; + return std::__copy_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/copy_if.h b/libcxx/include/__algorithm/copy_if.h index d68d1dbbadf8acab6f3bca1f3e2e6376cc7bf537..228e4d22323e3c8266df2e7acb6d3804430263d0 100644 --- a/libcxx/include/__algorithm/copy_if.h +++ b/libcxx/include/__algorithm/copy_if.h @@ -17,21 +17,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -copy_if(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, _Predicate __pred) -{ - for (; __first != __last; ++__first) - { - if (__pred(*__first)) - { - *__result = *__first; - ++__result; - } +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { + for (; __first != __last; ++__first) { + if (__pred(*__first)) { + *__result = *__first; + ++__result; } - return __result; + } + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/copy_move_common.h b/libcxx/include/__algorithm/copy_move_common.h index c06892e9e3c7994f187afb7e43d2ff535807acc0..b350507e32bae95c1ed5997541fad83fe60e16bb 100644 --- a/libcxx/include/__algorithm/copy_move_common.h +++ b/libcxx/include/__algorithm/copy_move_common.h @@ -38,22 +38,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD template struct __can_lower_copy_assignment_to_memmove { static const bool value = - // If the types are always bitcastable, it's valid to do a bitwise copy between them. - __is_always_bitcastable<_From, _To>::value && - // Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays). - is_trivially_assignable<_To&, const _From&>::value && - // `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case. - !is_volatile<_From>::value && - !is_volatile<_To>::value; + // If the types are always bitcastable, it's valid to do a bitwise copy between them. + __is_always_bitcastable<_From, _To>::value && + // Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays). + is_trivially_assignable<_To&, const _From&>::value && + // `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case. + !is_volatile<_From>::value && !is_volatile<_To>::value; }; template struct __can_lower_move_assignment_to_memmove { static const bool value = - __is_always_bitcastable<_From, _To>::value && - is_trivially_assignable<_To&, _From&&>::value && - !is_volatile<_From>::value && - !is_volatile<_To>::value; + __is_always_bitcastable<_From, _To>::value && is_trivially_assignable<_To&, _From&&>::value && + !is_volatile<_From>::value && !is_volatile<_To>::value; }; // `memmove` algorithms implementation. @@ -95,8 +92,8 @@ struct __can_rewrap<_InIter, _Sent, _OutIter, // Note that sentinels are always copy-constructible. - __enable_if_t< is_copy_constructible<_InIter>::value && - is_copy_constructible<_OutIter>::value > > : true_type {}; + __enable_if_t< is_copy_constructible<_InIter>::value && is_copy_constructible<_OutIter>::value > > + : true_type {}; template (std::move(__first), std::move(__result.first)), - std::__rewrap_iter(std::move(__out_first), std::move(__result.second))); + std::__rewrap_iter(std::move(__out_first), std::move(__result.second))); } template ::value && - !__has_random_access_iterator_category<_InputIterator>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) -{ - typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; - if (__n > 0) - { - *__result = *__first; - ++__result; - for (--__n; __n > 0; --__n) - { - ++__first; - *__result = *__first; - ++__result; - } +template ::value && + !__has_random_access_iterator_category<_InputIterator>::value, + int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { + typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + if (__n > 0) { + *__result = *__first; + ++__result; + for (--__n; __n > 0; --__n) { + ++__first; + *__result = *__first; + ++__result; } - return __result; + } + return __result; } -template::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) -{ - typedef typename iterator_traits<_InputIterator>::difference_type difference_type; - typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; - return std::copy(__first, __first + difference_type(__n), __result); +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { + typedef typename iterator_traits<_InputIterator>::difference_type difference_type; + typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + return std::copy(__first, __first + difference_type(__n), __result); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h index fb358613e21012bffed20869a95fa2b1104c6cba..f03f010aa51ab3f7fc5dd1a3ed5c1a0e91031631 100644 --- a/libcxx/include/__algorithm/equal.h +++ b/libcxx/include/__algorithm/equal.h @@ -68,8 +68,13 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first #if _LIBCPP_STD_VER >= 14 template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, - _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) { +__equal(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _BinaryPredicate __pred, + input_iterator_tag, + input_iterator_tag) { for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) if (!__pred(*__first1, *__first2)) return false; @@ -104,8 +109,12 @@ __equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, +__equal(_RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _BinaryPredicate __pred, + random_access_iterator_tag, random_access_iterator_tag) { if (std::distance(__first1, __last1) != std::distance(__first2, __last2)) return false; @@ -122,10 +131,18 @@ __equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _Random template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, +equal(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, _BinaryPredicate __pred) { return std::__equal<_BinaryPredicate&>( - __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(), + __first1, + __last1, + __first2, + __last2, + __pred, + typename iterator_traits<_InputIterator1>::iterator_category(), typename iterator_traits<_InputIterator2>::iterator_category()); } diff --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h index dc1268a6ff110c76f4f834d88d920a87f844d5e1..7ce54965fff05fb9e7279e353de8c9aa06f82440 100644 --- a/libcxx/include/__algorithm/equal_range.h +++ b/libcxx/include/__algorithm/equal_range.h @@ -49,9 +49,8 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp __len = __half_len; } else { _Iter __mp1 = __mid; - return pair<_Iter, _Iter>( - std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj), - std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj)); + return pair<_Iter, _Iter>(std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj), + std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj)); } } return pair<_Iter, _Iter>(__first, __first); @@ -60,10 +59,8 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp template _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { - static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, - "The comparator has to be callable"); - static_assert(is_copy_constructible<_ForwardIterator>::value, - "Iterator has to be copy constructible"); + static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable"); + static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible"); return std::__equal_range<_ClassicAlgPolicy>( std::move(__first), std::move(__last), diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h index 360e2c3c3c8582f337da8b16d920c35104bb19b2..1ce3eadb013d05981178f22a898b3d7092c0f643 100644 --- a/libcxx/include/__algorithm/fill.h +++ b/libcxx/include/__algorithm/fill.h @@ -22,28 +22,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD // fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag) -{ - for (; __first != __last; ++__first) - *__first = __value; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag) { + for (; __first != __last; ++__first) + *__first = __value; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag) -{ - std::fill_n(__first, __last - __first, __value); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag) { + std::fill_n(__first, __last - __first, __value); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - std::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + std::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h index 89681a342ea78e6ff5a509c39061ec67d855f623..36f3349d9e7a37d832cf6203afd76013ccd6a6e0 100644 --- a/libcxx/include/__algorithm/fill_n.h +++ b/libcxx/include/__algorithm/fill_n.h @@ -22,21 +22,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD // fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) -{ - for (; __n > 0; ++__first, (void) --__n) - *__first = __value; - return __first; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { + for (; __n > 0; ++__first, (void)--__n) + *__first = __value; + return __first; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) -{ - return std::__fill_n(__first, std::__convert_to_integral(__n), __value); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { + return std::__fill_n(__first, std::__convert_to_integral(__n), __value); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h index 0118489d94699d566ef081461cbb791fec1a98d7..754e597130c5b14fd31eeaa2b688f60288a89697 100644 --- a/libcxx/include/__algorithm/find.h +++ b/libcxx/include/__algorithm/find.h @@ -10,6 +10,7 @@ #ifndef _LIBCPP___ALGORITHM_FIND_H #define _LIBCPP___ALGORITHM_FIND_H +#include <__algorithm/find_segment_if.h> #include <__algorithm/min.h> #include <__algorithm/unwrap_iter.h> #include <__bit/countr.h> @@ -18,8 +19,10 @@ #include <__functional/identity.h> #include <__functional/invoke.h> #include <__fwd/bit_reference.h> +#include <__iterator/segmented_iterator.h> #include <__string/constexpr_c_functions.h> #include <__type_traits/is_same.h> +#include <__utility/move.h> #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS # include @@ -118,6 +121,34 @@ __find_impl(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> return std::__find_bool(__first, static_cast(__last - __first)); } +// segmented iterator implementation + +template +struct __find_segment; + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator +__find_impl(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj& __proj) { + return std::__find_segment_if(std::move(__first), std::move(__last), __find_segment<_Tp>(__value), __proj); +} + +template +struct __find_segment { + const _Tp& __value_; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __find_segment(const _Tp& __value) : __value_(__value) {} + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _InputIterator + operator()(_InputIterator __first, _InputIterator __last, _Proj& __proj) const { + return std::__find_impl(__first, __last, __value_, __proj); + } +}; + +// public API template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find(_InputIterator __first, _InputIterator __last, const _Tp& __value) { diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h index edb9891c66f70f9f8481e7b2965114e1580325c0..4c26891666b2238d731fc8525f232ce0109109b6 100644 --- a/libcxx/include/__algorithm/find_end.h +++ b/libcxx/include/__algorithm/find_end.h @@ -28,15 +28,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template < - class _AlgPolicy, - class _Iter1, - class _Sent1, - class _Iter2, - class _Sent2, - class _Pred, - class _Proj1, - class _Proj2> +template < class _AlgPolicy, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Pred, + class _Proj1, + class _Proj2> _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl( _Iter1 __first1, _Sent1 __last1, @@ -49,7 +48,7 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> forward_iterator_tag) { // modeled after search algorithm _Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer - _Iter1 __match_last = __match_first; + _Iter1 __match_last = __match_first; if (__first2 == __last2) return pair<_Iter1, _Iter1>(__match_last, __match_last); while (true) { @@ -66,15 +65,14 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> while (true) { if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one __match_first = __first1; - __match_last = ++__m1; + __match_last = ++__m1; ++__first1; break; } if (++__m1 == __last1) // Source exhausted, return last answer return pair<_Iter1, _Iter1>(__match_first, __match_last); - // mismatch, restart with a new __first - if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) - { + // mismatch, restart with a new __first + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) { ++__first1; break; } // else there is a match, check next elements @@ -82,15 +80,14 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> } } -template < - class _IterOps, - class _Pred, - class _Iter1, - class _Sent1, - class _Iter2, - class _Sent2, - class _Proj1, - class _Proj2> +template < class _IterOps, + class _Pred, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end( _Iter1 __first1, _Sent1 __sent1, @@ -127,23 +124,21 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end( return __last1; // if there is a mismatch, restart with a new __l1 - if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) - { + if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) { break; } // else there is a match, check next elements } } } -template < - class _AlgPolicy, - class _Pred, - class _Iter1, - class _Sent1, - class _Iter2, - class _Sent2, - class _Proj1, - class _Proj2> +template < class _AlgPolicy, + class _Pred, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end( _Iter1 __first1, _Sent1 __sent1, @@ -165,8 +160,8 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end( if (__len1 < __len2) return __last1; const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here - _Iter1 __l1 = __last1; - _Iter2 __l2 = __last2; + _Iter1 __l1 = __last1; + _Iter2 __l2 = __last2; --__l2; while (true) { while (true) { @@ -189,10 +184,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end( } template -_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_ForwardIterator1 __find_end_classic(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate& __pred) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_end_classic( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate& __pred) { auto __proj = __identity(); return std::__find_end_impl<_ClassicAlgPolicy>( __first1, @@ -208,17 +205,18 @@ _ForwardIterator1 __find_end_classic(_ForwardIterator1 __first1, _ForwardIterato } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred) { return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::find_end(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/find_first_of.h b/libcxx/include/__algorithm/find_first_of.h index 15a147242b0e5206f98c7b5353acbd6303f40fdd..14271cccc42b14254568c86762c8d6d3643c1a17 100644 --- a/libcxx/include/__algorithm/find_first_of.h +++ b/libcxx/include/__algorithm/find_first_of.h @@ -21,12 +21,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1, - _ForwardIterator1 __last1, - _ForwardIterator2 __first2, - _ForwardIterator2 __last2, - _BinaryPredicate&& __pred) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate&& __pred) { for (; __first1 != __last1; ++__first1) for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) if (__pred(*__first1, *__j)) @@ -35,9 +35,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(_ForwardItera } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 -find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred) { return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); } diff --git a/libcxx/include/__algorithm/find_segment_if.h b/libcxx/include/__algorithm/find_segment_if.h new file mode 100644 index 0000000000000000000000000000000000000000..9d6064f3e283a6953c03a983baa4ce467a7f1337 --- /dev/null +++ b/libcxx/include/__algorithm/find_segment_if.h @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H +#define _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H + +#include <__config> +#include <__iterator/segmented_iterator.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// __find_segment_if is a utility function for optimizing iteration over segmented iterators linearly. +// [__first, __last) has to be a segmented range. __pred is expected to take a range of local iterators and the __proj. +// It returns an iterator to the first element that satisfies the predicate, or a one-past-the-end iterator if there was +// no match. __proj may be anything that should be passed to __pred, but is expected to be a projection to support +// ranges algorithms, or __identity for classic algorithms. + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator +__find_segment_if(_SegmentedIterator __first, _SegmentedIterator __last, _Pred __pred, _Proj& __proj) { + using _Traits = __segmented_iterator_traits<_SegmentedIterator>; + + auto __sfirst = _Traits::__segment(__first); + auto __slast = _Traits::__segment(__last); + + // We are in a single segment, so we might not be at the beginning or end + if (__sfirst == __slast) + return _Traits::__compose(__sfirst, __pred(_Traits::__local(__first), _Traits::__local(__last), __proj)); + + { // We have more than one segment. Iterate over the first segment, since we might not start at the beginning + auto __llast = _Traits::__end(__sfirst); + auto __liter = __pred(_Traits::__local(__first), __llast, __proj); + if (__liter != __llast) + return _Traits::__compose(__sfirst, __liter); + } + ++__sfirst; + + // Iterate over the segments which are guaranteed to be completely in the range + while (__sfirst != __slast) { + auto __llast = _Traits::__end(__sfirst); + auto __liter = __pred(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), __proj); + if (__liter != __llast) + return _Traits::__compose(__sfirst, __liter); + ++__sfirst; + } + + // Iterate over the last segment + return _Traits::__compose(__sfirst, __pred(_Traits::__begin(__sfirst), _Traits::__local(__last), __proj)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H diff --git a/libcxx/include/__algorithm/for_each_n.h b/libcxx/include/__algorithm/for_each_n.h index a72a0912cfa52094cf539dbc7d4857834d2f60c5..fce380b49df3e0f0f38ef0dafb3d2bebaa70fa93 100644 --- a/libcxx/include/__algorithm/for_each_n.h +++ b/libcxx/include/__algorithm/for_each_n.h @@ -22,9 +22,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first, - _Size __orig_n, - _Function __f) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; _IntegralSize __n = __orig_n; while (__n > 0) { diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index e2051dc16dc03e65586872f6e17279ee91718927..c95b527402f5db1a89e2517978aae0a60b8cdd62 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -18,12 +18,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) -{ - for (; __first != __last; ++__first) - *__first = __gen(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { + for (; __first != __last; ++__first) + *__first = __gen(); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/generate_n.h b/libcxx/include/__algorithm/generate_n.h index 5719826e93edf2018977cb283971d5049405d083..f36403fd0f94a9fd3c8dac9ba569108ff53ed228 100644 --- a/libcxx/include/__algorithm/generate_n.h +++ b/libcxx/include/__algorithm/generate_n.h @@ -19,15 +19,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) -{ - typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; - for (; __n > 0; ++__first, (void) --__n) - *__first = __gen(); - return __first; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) { + typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + for (; __n > 0; ++__first, (void)--__n) + *__first = __gen(); + return __first; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/half_positive.h b/libcxx/include/__algorithm/half_positive.h index 2315e154fb2ef50588a3241530491a49c5c2b83a..ebda0da372369d5b168673a5f541e5f4a49fb5a5 100644 --- a/libcxx/include/__algorithm/half_positive.h +++ b/libcxx/include/__algorithm/half_positive.h @@ -23,19 +23,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD // Perform division by two quickly for positive integers (llvm.org/PR39129) template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -_Integral -__half_positive(_Integral __value) -{ - return static_cast<_Integral>(static_cast<__make_unsigned_t<_Integral> >(__value) / 2); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Integral __half_positive(_Integral __value) { + return static_cast<_Integral>(static_cast<__make_unsigned_t<_Integral> >(__value) / 2); } template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -_Tp -__half_positive(_Tp __value) -{ - return __value / 2; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp __half_positive(_Tp __value) { + return __value / 2; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/in_found_result.h b/libcxx/include/__algorithm/in_found_result.h index d9ca287f017b64377d096be3e920b349b188a98a..88a0255d169831a7f01f9e7a81e28c2f0c949c92 100644 --- a/libcxx/include/__algorithm/in_found_result.h +++ b/libcxx/include/__algorithm/in_found_result.h @@ -30,7 +30,7 @@ struct in_found_result { template requires convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const & { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const& { return {in, found}; } diff --git a/libcxx/include/__algorithm/in_fun_result.h b/libcxx/include/__algorithm/in_fun_result.h index 33374eddc30d7bdbe2816264b76d5bcd183201f9..6110c1cf86cd52b675e777d88896ed8b01096845 100644 --- a/libcxx/include/__algorithm/in_fun_result.h +++ b/libcxx/include/__algorithm/in_fun_result.h @@ -30,7 +30,7 @@ struct in_fun_result { template requires convertible_to && convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const & { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const& { return {in, fun}; } diff --git a/libcxx/include/__algorithm/in_in_out_result.h b/libcxx/include/__algorithm/in_in_out_result.h index 6b50e0e245643f2fae6f7a49b2472dac35130001..95ce4f4fd5bd44ae2d9ee5214fcedeacc559529a 100644 --- a/libcxx/include/__algorithm/in_in_out_result.h +++ b/libcxx/include/__algorithm/in_in_out_result.h @@ -31,18 +31,16 @@ struct in_in_out_result { _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out; template - requires convertible_to - && convertible_to && convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& { + requires convertible_to && convertible_to && + convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& { return {in1, in2, out}; } template - requires convertible_to<_InIter1, _InIter3> - && convertible_to<_InIter2, _InIter4> && convertible_to<_OutIter1, _OutIter2> - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && { + requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4> && + convertible_to<_OutIter1, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && { return {std::move(in1), std::move(in2), std::move(out)}; } }; diff --git a/libcxx/include/__algorithm/in_in_result.h b/libcxx/include/__algorithm/in_in_result.h index 1eceb9de02334a912e33b546c8b648f29cc46273..d1d62dae7f6703a6a6973db57a91c188a7635a5b 100644 --- a/libcxx/include/__algorithm/in_in_result.h +++ b/libcxx/include/__algorithm/in_in_result.h @@ -31,15 +31,13 @@ struct in_in_result { template requires convertible_to && convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_in_result<_InIter3, _InIter4>() const & { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_result<_InIter3, _InIter4>() const& { return {in1, in2}; } template requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4> - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_in_result<_InIter3, _InIter4>() && { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_result<_InIter3, _InIter4>() && { return {std::move(in1), std::move(in2)}; } }; diff --git a/libcxx/include/__algorithm/in_out_out_result.h b/libcxx/include/__algorithm/in_out_out_result.h index 2f7a09b5c30143de6b5c0f5d12697c3f6d68a059..1436423687508601740a03dfd541e92ffc1b7511 100644 --- a/libcxx/include/__algorithm/in_out_out_result.h +++ b/libcxx/include/__algorithm/in_out_out_result.h @@ -30,18 +30,16 @@ struct in_out_out_result { _LIBCPP_NO_UNIQUE_ADDRESS _OutIter2 out2; template - requires convertible_to - && convertible_to && convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& { + requires convertible_to && convertible_to && + convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& { return {in, out1, out2}; } template - requires convertible_to<_InIter1, _InIter2> - && convertible_to<_OutIter1, _OutIter3> && convertible_to<_OutIter2, _OutIter4> - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && { + requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter3> && + convertible_to<_OutIter2, _OutIter4> + _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && { return {std::move(in), std::move(out1), std::move(out2)}; } }; diff --git a/libcxx/include/__algorithm/in_out_result.h b/libcxx/include/__algorithm/in_out_result.h index e4741cb71f66ba0ce3c14aea678e4fad472ac201..a7a986cf8e6c097112f8dc4a7d3063faee90ba6d 100644 --- a/libcxx/include/__algorithm/in_out_result.h +++ b/libcxx/include/__algorithm/in_out_result.h @@ -27,22 +27,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { -template +template struct in_out_result { _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out; template requires convertible_to && convertible_to - _LIBCPP_HIDE_FROM_ABI - constexpr operator in_out_result<_InIter2, _OutIter2>() const & { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_result<_InIter2, _OutIter2>() const& { return {in, out}; } template requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter2> - _LIBCPP_HIDE_FROM_ABI - constexpr operator in_out_result<_InIter2, _OutIter2>() && { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_result<_InIter2, _OutIter2>() && { return {std::move(in), std::move(out)}; } }; diff --git a/libcxx/include/__algorithm/includes.h b/libcxx/include/__algorithm/includes.h index 88253e2653d27a71c7cffb6a373d0206986d59c3..531752e93175699e36f148ac5013405bdb45deef 100644 --- a/libcxx/include/__algorithm/includes.h +++ b/libcxx/include/__algorithm/includes.h @@ -25,12 +25,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__includes(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Comp&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __includes( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Comp&& __comp, + _Proj1&& __proj1, + _Proj2&& __proj2) { for (; __first2 != __last2; ++__first1) { - if (__first1 == __last1 || std::__invoke( - __comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1))) + if (__first1 == __last1 || + std::__invoke(__comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1))) return false; if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) ++__first2; @@ -39,14 +44,14 @@ __includes(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes( - _InputIterator1 __first1, - _InputIterator1 __last1, - _InputIterator2 __first2, - _InputIterator2 __last2, - _Compare __comp) { - static_assert(__is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value, - "Comparator has to be callable"); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +includes(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _Compare __comp) { + static_assert( + __is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value, "Comparator has to be callable"); return std::__includes( std::move(__first1), diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h index d49c2e5cedda23d1d481ec7c94ec0d2a658750fb..eb3c0bdbc2db7f648ba3da678422f669e6ec634f 100644 --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -42,54 +42,57 @@ template class __invert // invert the sense of a comparison { private: - _Predicate __p_; + _Predicate __p_; + public: - _LIBCPP_HIDE_FROM_ABI __invert() {} + _LIBCPP_HIDE_FROM_ABI __invert() {} - _LIBCPP_HIDE_FROM_ABI - explicit __invert(_Predicate __p) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI explicit __invert(_Predicate __p) : __p_(__p) {} - template - _LIBCPP_HIDE_FROM_ABI - bool operator()(const _T1& __x) {return !__p_(__x);} + template + _LIBCPP_HIDE_FROM_ABI bool operator()(const _T1& __x) { + return !__p_(__x); + } - template - _LIBCPP_HIDE_FROM_ABI - bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} + template + _LIBCPP_HIDE_FROM_ABI bool operator()(const _T1& __x, const _T2& __y) { + return __p_(__y, __x); + } }; -template -_LIBCPP_HIDE_FROM_ABI -void __half_inplace_merge(_InputIterator1 __first1, _Sent1 __last1, - _InputIterator2 __first2, _Sent2 __last2, - _OutputIterator __result, _Compare&& __comp) -{ - for (; __first1 != __last1; ++__result) - { - if (__first2 == __last2) - { - std::__move<_AlgPolicy>(__first1, __last1, __result); - return; - } +template +_LIBCPP_HIDE_FROM_ABI void __half_inplace_merge( + _InputIterator1 __first1, + _Sent1 __last1, + _InputIterator2 __first2, + _Sent2 __last2, + _OutputIterator __result, + _Compare&& __comp) { + for (; __first1 != __last1; ++__result) { + if (__first2 == __last2) { + std::__move<_AlgPolicy>(__first1, __last1, __result); + return; + } - if (__comp(*__first2, *__first1)) - { - *__result = _IterOps<_AlgPolicy>::__iter_move(__first2); - ++__first2; - } - else - { - *__result = _IterOps<_AlgPolicy>::__iter_move(__first1); - ++__first1; - } + if (__comp(*__first2, *__first1)) { + *__result = _IterOps<_AlgPolicy>::__iter_move(__first2); + ++__first2; + } else { + *__result = _IterOps<_AlgPolicy>::__iter_move(__first1); + ++__first1; } - // __first2 through __last2 are already in the right spot. + } + // __first2 through __last2 are already in the right spot. } template -_LIBCPP_HIDE_FROM_ABI -void __buffered_inplace_merge( +_LIBCPP_HIDE_FROM_ABI void __buffered_inplace_merge( _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, @@ -98,27 +101,25 @@ void __buffered_inplace_merge( typename iterator_traits<_BidirectionalIterator>::difference_type __len2, typename iterator_traits<_BidirectionalIterator>::value_type* __buff) { typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - __destruct_n __d(0); - unique_ptr __h2(__buff, __d); - if (__len1 <= __len2) - { - value_type* __p = __buff; - for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr(), (void) ++__i, (void) ++__p) - ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); - std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp); - } - else - { - value_type* __p = __buff; - for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr(), (void) ++__i, (void) ++__p) - ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); - typedef __unconstrained_reverse_iterator<_BidirectionalIterator> _RBi; - typedef __unconstrained_reverse_iterator _Rv; - typedef __invert<_Compare> _Inverted; - std::__half_inplace_merge<_AlgPolicy>(_Rv(__p), _Rv(__buff), - _RBi(__middle), _RBi(__first), - _RBi(__last), _Inverted(__comp)); - } + __destruct_n __d(0); + unique_ptr __h2(__buff, __d); + if (__len1 <= __len2) { + value_type* __p = __buff; + for (_BidirectionalIterator __i = __first; __i != __middle; + __d.template __incr(), (void)++__i, (void)++__p) + ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); + std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp); + } else { + value_type* __p = __buff; + for (_BidirectionalIterator __i = __middle; __i != __last; + __d.template __incr(), (void)++__i, (void)++__p) + ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); + typedef __unconstrained_reverse_iterator<_BidirectionalIterator> _RBi; + typedef __unconstrained_reverse_iterator _Rv; + typedef __invert<_Compare> _Inverted; + std::__half_inplace_merge<_AlgPolicy>( + _Rv(__p), _Rv(__buff), _RBi(__middle), _RBi(__first), _RBi(__last), _Inverted(__comp)); + } } template @@ -131,107 +132,92 @@ void __inplace_merge( typename iterator_traits<_BidirectionalIterator>::difference_type __len2, typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size) { - using _Ops = _IterOps<_AlgPolicy>; - - typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; - while (true) - { - // if __middle == __last, we're done - if (__len2 == 0) - return; - if (__len1 <= __buff_size || __len2 <= __buff_size) - return std::__buffered_inplace_merge<_AlgPolicy> - (__first, __middle, __last, __comp, __len1, __len2, __buff); - // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 - for (; true; ++__first, (void) --__len1) - { - if (__len1 == 0) - return; - if (__comp(*__middle, *__first)) - break; - } - // __first < __middle < __last - // *__first > *__middle - // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that - // all elements in: - // [__first, __m1) <= [__middle, __m2) - // [__middle, __m2) < [__m1, __middle) - // [__m1, __middle) <= [__m2, __last) - // and __m1 or __m2 is in the middle of its range - _BidirectionalIterator __m1; // "median" of [__first, __middle) - _BidirectionalIterator __m2; // "median" of [__middle, __last) - difference_type __len11; // distance(__first, __m1) - difference_type __len21; // distance(__middle, __m2) - // binary search smaller range - if (__len1 < __len2) - { // __len >= 1, __len2 >= 2 - __len21 = __len2 / 2; - __m2 = __middle; - _Ops::advance(__m2, __len21); - __m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity()); - __len11 = _Ops::distance(__first, __m1); - } - else - { - if (__len1 == 1) - { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 - // It is known *__first > *__middle - _Ops::iter_swap(__first, __middle); - return; - } - // __len1 >= 2, __len2 >= 1 - __len11 = __len1 / 2; - __m1 = __first; - _Ops::advance(__m1, __len11); - __m2 = std::lower_bound(__middle, __last, *__m1, __comp); - __len21 = _Ops::distance(__middle, __m2); - } - difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) - difference_type __len22 = __len2 - __len21; // distance(__m2, __last) - // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) - // swap middle two partitions - __middle = std::__rotate<_AlgPolicy>(__m1, __middle, __m2).first; - // __len12 and __len21 now have swapped meanings - // merge smaller range with recursive call and larger with tail recursion elimination - if (__len11 + __len21 < __len12 + __len22) - { - std::__inplace_merge<_AlgPolicy>( - __first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); - __first = __middle; - __middle = __m2; - __len1 = __len12; - __len2 = __len22; - } - else - { - std::__inplace_merge<_AlgPolicy>( - __middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); - __last = __middle; - __middle = __m1; - __len1 = __len11; - __len2 = __len21; - } + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + while (true) { + // if __middle == __last, we're done + if (__len2 == 0) + return; + if (__len1 <= __buff_size || __len2 <= __buff_size) + return std::__buffered_inplace_merge<_AlgPolicy>(__first, __middle, __last, __comp, __len1, __len2, __buff); + // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 + for (; true; ++__first, (void)--__len1) { + if (__len1 == 0) + return; + if (__comp(*__middle, *__first)) + break; } + // __first < __middle < __last + // *__first > *__middle + // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that + // all elements in: + // [__first, __m1) <= [__middle, __m2) + // [__middle, __m2) < [__m1, __middle) + // [__m1, __middle) <= [__m2, __last) + // and __m1 or __m2 is in the middle of its range + _BidirectionalIterator __m1; // "median" of [__first, __middle) + _BidirectionalIterator __m2; // "median" of [__middle, __last) + difference_type __len11; // distance(__first, __m1) + difference_type __len21; // distance(__middle, __m2) + // binary search smaller range + if (__len1 < __len2) { // __len >= 1, __len2 >= 2 + __len21 = __len2 / 2; + __m2 = __middle; + _Ops::advance(__m2, __len21); + __m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity()); + __len11 = _Ops::distance(__first, __m1); + } else { + if (__len1 == 1) { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 + // It is known *__first > *__middle + _Ops::iter_swap(__first, __middle); + return; + } + // __len1 >= 2, __len2 >= 1 + __len11 = __len1 / 2; + __m1 = __first; + _Ops::advance(__m1, __len11); + __m2 = std::lower_bound(__middle, __last, *__m1, __comp); + __len21 = _Ops::distance(__middle, __m2); + } + difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) + difference_type __len22 = __len2 - __len21; // distance(__m2, __last) + // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) + // swap middle two partitions + __middle = std::__rotate<_AlgPolicy>(__m1, __middle, __m2).first; + // __len12 and __len21 now have swapped meanings + // merge smaller range with recursive call and larger with tail recursion elimination + if (__len11 + __len21 < __len12 + __len22) { + std::__inplace_merge<_AlgPolicy>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); + __first = __middle; + __middle = __m2; + __len1 = __len12; + __len2 = __len22; + } else { + std::__inplace_merge<_AlgPolicy>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); + __last = __middle; + __middle = __m1; + __len1 = __len11; + __len2 = __len21; + } + } } template -_LIBCPP_HIDE_FROM_ABI -void -__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, - _Compare&& __comp) -{ - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; - difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); - difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); - difference_type __buf_size = std::min(__len1, __len2); -// TODO: Remove the use of std::get_temporary_buffer -_LIBCPP_SUPPRESS_DEPRECATED_PUSH - pair __buf = std::get_temporary_buffer(__buf_size); -_LIBCPP_SUPPRESS_DEPRECATED_POP - unique_ptr __h(__buf.first); - return std::__inplace_merge<_AlgPolicy>( - std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second); +_LIBCPP_HIDE_FROM_ABI void __inplace_merge( + _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare&& __comp) { + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); + difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); + difference_type __buf_size = std::min(__len1, __len2); + // TODO: Remove the use of std::get_temporary_buffer + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + pair __buf = std::get_temporary_buffer(__buf_size); + _LIBCPP_SUPPRESS_DEPRECATED_POP + unique_ptr __h(__buf.first); + return std::__inplace_merge<_AlgPolicy>( + std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second); } template @@ -242,11 +228,9 @@ inline _LIBCPP_HIDE_FROM_ABI void inplace_merge( } template -inline _LIBCPP_HIDE_FROM_ABI -void -inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) -{ - std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>()); +inline _LIBCPP_HIDE_FROM_ABI void +inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) { + std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/is_heap.h b/libcxx/include/__algorithm/is_heap.h index dd78031579ec9f247ee98dd03586b8c6bc4df09b..0d2d43c2c3abd626edb194ca86a0a413dbe830f6 100644 --- a/libcxx/include/__algorithm/is_heap.h +++ b/libcxx/include/__algorithm/is_heap.h @@ -22,21 +22,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last; +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last; } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - return std::is_heap(__first, __last, __less<>()); +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + return std::is_heap(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/is_heap_until.h b/libcxx/include/__algorithm/is_heap_until.h index 85f70e649f568db8e76723aef88809df409f9b23..1eae3b86b90dfbd34521fc0f7c5bb86d1a34c89c 100644 --- a/libcxx/include/__algorithm/is_heap_until.h +++ b/libcxx/include/__algorithm/is_heap_until.h @@ -22,43 +22,39 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator -__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) -{ - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - difference_type __len = __last - __first; - difference_type __p = 0; - difference_type __c = 1; - _RandomAccessIterator __pp = __first; - while (__c < __len) - { - _RandomAccessIterator __cp = __first + __c; - if (__comp(*__pp, *__cp)) - return __cp; - ++__c; - ++__cp; - if (__c == __len) - return __last; - if (__comp(*__pp, *__cp)) - return __cp; - ++__p; - ++__pp; - __c = 2 * __p + 1; - } - return __last; +__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __len = __last - __first; + difference_type __p = 0; + difference_type __c = 1; + _RandomAccessIterator __pp = __first; + while (__c < __len) { + _RandomAccessIterator __cp = __first + __c; + if (__comp(*__pp, *__cp)) + return __cp; + ++__c; + ++__cp; + if (__c == __len) + return __last; + if (__comp(*__pp, *__cp)) + return __cp; + ++__p; + ++__pp; + __c = 2 * __p + 1; + } + return __last; } template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator -is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); } -template +template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator -is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - return std::__is_heap_until(__first, __last, __less<>()); +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) { + return std::__is_heap_until(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/is_partitioned.h b/libcxx/include/__algorithm/is_partitioned.h index ab59d3cce58235de5a0306eb8a0b01d61bc06c4a..71feed33206058aff15294b2955e6a109ba7a093 100644 --- a/libcxx/include/__algorithm/is_partitioned.h +++ b/libcxx/include/__algorithm/is_partitioned.h @@ -19,18 +19,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) -{ - for (; __first != __last; ++__first) - if (!__pred(*__first)) - break; - if ( __first == __last ) - return true; - ++__first; - for (; __first != __last; ++__first) - if (__pred(*__first)) - return false; +is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (!__pred(*__first)) + break; + if (__first == __last) return true; + ++__first; + for (; __first != __last; ++__first) + if (__pred(*__first)) + return false; + return true; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/is_permutation.h b/libcxx/include/__algorithm/is_permutation.h index 105a0732283c9020af7166e9e64263b2abd6f1ab..4226151222bbde9efc007bbef86f870f9bac7d94 100644 --- a/libcxx/include/__algorithm/is_permutation.h +++ b/libcxx/include/__algorithm/is_permutation.h @@ -37,18 +37,24 @@ struct _ConstTimeDistance : false_type {}; #if _LIBCPP_STD_VER >= 20 template -struct _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2, __enable_if_t< - sized_sentinel_for<_Sent1, _Iter1> && - sized_sentinel_for<_Sent2, _Iter2> ->> : true_type {}; +struct _ConstTimeDistance<_Iter1, + _Sent1, + _Iter2, + _Sent2, + __enable_if_t< sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2> >> + : true_type {}; #else template -struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t< - is_same::iterator_category, random_access_iterator_tag>::value && - is_same::iterator_category, random_access_iterator_tag>::value -> > : true_type {}; +struct _ConstTimeDistance< + _Iter1, + _Iter1, + _Iter2, + _Iter2, + __enable_if_t< is_same::iterator_category, random_access_iterator_tag>::value && + is_same::iterator_category, random_access_iterator_tag>::value > > + : true_type {}; #endif // _LIBCPP_STD_VER >= 20 @@ -56,11 +62,21 @@ struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t< // For each element in [f1, l1) see if there are the same number of equal elements in [f2, l2) template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__is_permutation_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) { + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2, + class _Pred> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred&& __pred, + _Proj1&& __proj1, + _Proj2&& __proj2) { using _D1 = __iter_diff_t<_Iter1>; for (auto __i = __first1; __i != __last1; ++__i) { @@ -97,9 +113,8 @@ __is_permutation_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 _ // 2+1 iterators, predicate. Not used by range algorithms. template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__is_permutation(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, - _BinaryPredicate&& __pred) { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( + _ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _BinaryPredicate&& __pred) { // Shorten sequences as much as possible by lopping of any equal prefix. for (; __first1 != __last1; ++__first1, (void)++__first2) { if (!__pred(*__first1, *__first2)) @@ -111,24 +126,39 @@ __is_permutation(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterato // __first1 != __last1 && *__first1 != *__first2 using _D1 = __iter_diff_t<_ForwardIterator1>; - _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); + _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); if (__l1 == _D1(1)) return false; auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __l1); return std::__is_permutation_impl<_AlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __identity(), __identity()); + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __pred, + __identity(), + __identity()); } // 2+2 iterators, predicate, non-constant time `distance`. template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2, - /*_ConstTimeDistance=*/false_type) { + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2, + class _Pred> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred&& __pred, + _Proj1&& __proj1, + _Proj2&& __proj2, + /*_ConstTimeDistance=*/false_type) { // Shorten sequences as much as possible by lopping of any equal prefix. while (__first1 != __last1 && __first2 != __last2) { if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) @@ -143,44 +173,73 @@ __is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last return false; using _D1 = __iter_diff_t<_Iter1>; - _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); + _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); using _D2 = __iter_diff_t<_Iter2>; - _D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2); + _D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2); if (__l1 != __l2) return false; return std::__is_permutation_impl<_AlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __proj1, __proj2); + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); } // 2+2 iterators, predicate, specialization for constant-time `distance` call. template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2, - /*_ConstTimeDistance=*/true_type) { + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2, + class _Pred> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred&& __pred, + _Proj1&& __proj1, + _Proj2&& __proj2, + /*_ConstTimeDistance=*/true_type) { if (std::distance(__first1, __last1) != std::distance(__first2, __last2)) return false; return std::__is_permutation<_AlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __proj1, __proj2, + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __pred, + __proj1, + __proj2, /*_ConstTimeDistance=*/false_type()); } // 2+2 iterators, predicate template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) { + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2, + class _Pred> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred&& __pred, + _Proj1&& __proj1, + _Proj2&& __proj2) { return std::__is_permutation<_AlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __proj1, __proj2, + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __pred, + __proj1, + __proj2, _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2>()); } @@ -188,14 +247,12 @@ __is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last // 2+1 iterators, predicate template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _BinaryPredicate __pred) { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( + _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) { static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, - "The predicate has to be callable"); + "The predicate has to be callable"); - return std::__is_permutation<_ClassicAlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), __pred); + return std::__is_permutation<_ClassicAlgPolicy>(std::move(__first1), std::move(__last1), std::move(__first2), __pred); } // 2+1 iterators @@ -223,15 +280,23 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 // 2+2 iterators, predicate template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred) { static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, - "The predicate has to be callable"); + "The predicate has to be callable"); return std::__is_permutation<_ClassicAlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __identity(), __identity()); + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __pred, + __identity(), + __identity()); } #endif // _LIBCPP_STD_VER >= 14 diff --git a/libcxx/include/__algorithm/is_sorted.h b/libcxx/include/__algorithm/is_sorted.h index 0003097b362c5105f02f0292e9f0ea3fce0c8a3a..1874cace882c1edf368166c0099257d3a4b8806b 100644 --- a/libcxx/include/__algorithm/is_sorted.h +++ b/libcxx/include/__algorithm/is_sorted.h @@ -22,21 +22,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last; +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last; } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -is_sorted(_ForwardIterator __first, _ForwardIterator __last) -{ - return std::is_sorted(__first, __last, __less<>()); +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_sorted(_ForwardIterator __first, _ForwardIterator __last) { + return std::is_sorted(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/is_sorted_until.h b/libcxx/include/__algorithm/is_sorted_until.h index aeb3f1c8be98970b66405e1318627eab4a01fa7f..7450440df2d8b8c52b5d244c969bd782818509a6 100644 --- a/libcxx/include/__algorithm/is_sorted_until.h +++ b/libcxx/include/__algorithm/is_sorted_until.h @@ -22,33 +22,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - if (__first != __last) - { - _ForwardIterator __i = __first; - while (++__i != __last) - { - if (__comp(*__i, *__first)) - return __i; - __first = __i; - } +__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + if (__first != __last) { + _ForwardIterator __i = __first; + while (++__i != __last) { + if (__comp(*__i, *__first)) + return __i; + __first = __i; } - return __last; + } + return __last; } template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp); +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp); } -template +template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) -{ - return std::is_sorted_until(__first, __last, __less<>()); +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) { + return std::is_sorted_until(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/iter_swap.h b/libcxx/include/__algorithm/iter_swap.h index f647e74324674e61d6e8e50257ca4b36593548f8..a1412e5d8720bedd45c6d79508507f2ae993b592 100644 --- a/libcxx/include/__algorithm/iter_swap.h +++ b/libcxx/include/__algorithm/iter_swap.h @@ -20,8 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a, - _ForwardIterator2 __b) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) _NOEXCEPT_(_NOEXCEPT_(swap(*std::declval<_ForwardIterator1>(), *std::declval<_ForwardIterator2>()))) { swap(*__a, *__b); diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h index e6176da4f5606d846985f6c99413b5203bc41a15..5cf13f0a3f292624ad2ac0b1598dc125767b2b85 100644 --- a/libcxx/include/__algorithm/iterator_operations.h +++ b/libcxx/include/__algorithm/iterator_operations.h @@ -38,14 +38,14 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -template struct _IterOps; +template +struct _IterOps; #if _LIBCPP_STD_VER >= 20 struct _RangeAlgPolicy {}; template <> struct _IterOps<_RangeAlgPolicy> { - template using __value_type = iter_value_t<_Iter>; @@ -55,12 +55,12 @@ struct _IterOps<_RangeAlgPolicy> { template using __difference_type = iter_difference_t<_Iter>; - static constexpr auto advance = ranges::advance; - static constexpr auto distance = ranges::distance; - static constexpr auto __iter_move = ranges::iter_move; - static constexpr auto iter_swap = ranges::iter_swap; - static constexpr auto next = ranges::next; - static constexpr auto prev = ranges::prev; + static constexpr auto advance = ranges::advance; + static constexpr auto distance = ranges::distance; + static constexpr auto __iter_move = ranges::iter_move; + static constexpr auto iter_swap = ranges::iter_swap; + static constexpr auto next = ranges::next; + static constexpr auto prev = ranges::prev; static constexpr auto __advance_to = ranges::advance; }; @@ -70,7 +70,6 @@ struct _ClassicAlgPolicy {}; template <> struct _IterOps<_ClassicAlgPolicy> { - template using __value_type = typename iterator_traits<_Iter>::value_type; @@ -82,15 +81,14 @@ struct _IterOps<_ClassicAlgPolicy> { // advance template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - static void advance(_Iter& __iter, _Distance __count) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void advance(_Iter& __iter, _Distance __count) { std::advance(__iter, __count); } // distance template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - static typename iterator_traits<_Iter>::difference_type distance(_Iter __first, _Iter __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static typename iterator_traits<_Iter>::difference_type + distance(_Iter __first, _Iter __last) { return std::distance(__first, __last); } @@ -101,9 +99,9 @@ struct _IterOps<_ClassicAlgPolicy> { using __move_t = decltype(std::move(*std::declval<_Iter&>())); template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - static void __validate_iter_reference() { - static_assert(is_same<__deref_t<_Iter>, typename iterator_traits<__remove_cvref_t<_Iter> >::reference>::value, + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void __validate_iter_reference() { + static_assert( + is_same<__deref_t<_Iter>, typename iterator_traits<__remove_cvref_t<_Iter> >::reference>::value, "It looks like your iterator's `iterator_traits::reference` does not match the return type of " "dereferencing the iterator, i.e., calling `*it`. This is undefined behavior according to [input.iterators] " "and can lead to dangling reference issues at runtime, so we are flagging this."); @@ -112,10 +110,10 @@ struct _IterOps<_ClassicAlgPolicy> { // iter_move template >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static - // If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it. Note - // that the C++03 mode doesn't support `decltype(auto)` as the return type. - __move_t<_Iter> - __iter_move(_Iter&& __i) { + // If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it. + // Note that the C++03 mode doesn't support `decltype(auto)` as the return type. + __move_t<_Iter> + __iter_move(_Iter&& __i) { __validate_iter_reference<_Iter>(); return std::move(*std::forward<_Iter>(__i)); @@ -123,11 +121,11 @@ struct _IterOps<_ClassicAlgPolicy> { template >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static - // If the result of dereferencing `_Iter` is a value type, deduce the return value of this function to also be a - // value -- otherwise, after `operator*` returns a temporary, this function would return a dangling reference to that - // temporary. Note that the C++03 mode doesn't support `auto` as the return type. - __deref_t<_Iter> - __iter_move(_Iter&& __i) { + // If the result of dereferencing `_Iter` is a value type, deduce the return value of this function to also be a + // value -- otherwise, after `operator*` returns a temporary, this function would return a dangling reference to + // that temporary. Note that the C++03 mode doesn't support `auto` as the return type. + __deref_t<_Iter> + __iter_move(_Iter&& __i) { __validate_iter_reference<_Iter>(); return *std::forward<_Iter>(__i); @@ -135,36 +133,31 @@ struct _IterOps<_ClassicAlgPolicy> { // iter_swap template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - static void iter_swap(_Iter1&& __a, _Iter2&& __b) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void iter_swap(_Iter1&& __a, _Iter2&& __b) { std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b)); } // next template - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 - _Iterator next(_Iterator, _Iterator __last) { + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iterator next(_Iterator, _Iterator __last) { return __last; } template - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 - __remove_cvref_t<_Iter> next(_Iter&& __it, - typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 __remove_cvref_t<_Iter> + next(_Iter&& __it, typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { return std::next(std::forward<_Iter>(__it), __n); } // prev template - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 - __remove_cvref_t<_Iter> prev(_Iter&& __iter, - typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 __remove_cvref_t<_Iter> + prev(_Iter&& __iter, typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { return std::prev(std::forward<_Iter>(__iter), __n); } template - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 - void __advance_to(_Iter& __first, _Iter __last) { + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 void __advance_to(_Iter& __first, _Iter __last) { __first = __last; } }; diff --git a/libcxx/include/__algorithm/lexicographical_compare.h b/libcxx/include/__algorithm/lexicographical_compare.h index 1ee189a259025943e8ea68dadcac2ac6a63c368c..3efd8e24bf6c9c3df0711982b962525de70f3e8d 100644 --- a/libcxx/include/__algorithm/lexicographical_compare.h +++ b/libcxx/include/__algorithm/lexicographical_compare.h @@ -21,38 +21,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) -{ - for (; __first2 != __last2; ++__first1, (void) ++__first2) - { - if (__first1 == __last1 || __comp(*__first1, *__first2)) - return true; - if (__comp(*__first2, *__first1)) - return false; - } - return false; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __lexicographical_compare( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _Compare __comp) { + for (; __first2 != __last2; ++__first1, (void)++__first2) { + if (__first1 == __last1 || __comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return false; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) -{ - return std::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _Compare __comp) { + return std::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2) -{ - return std::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( + _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { + return std::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h index 91c3bdaafd0cfdad65b1f0f96a9257669b2f02dd..8f57f3592c4b24aa5601d451e7211d8a4ce73015 100644 --- a/libcxx/include/__algorithm/lower_bound.h +++ b/libcxx/include/__algorithm/lower_bound.h @@ -28,8 +28,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_Iter __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter +__lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); while (__len != 0) { @@ -47,17 +47,16 @@ _Iter __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __ } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { - static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, - "The comparator has to be callable"); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable"); auto __proj = std::__identity(); return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { return std::lower_bound(__first, __last, __value, __less<>()); } diff --git a/libcxx/include/__algorithm/make_heap.h b/libcxx/include/__algorithm/make_heap.h index eaf9259c0b3150a0b9a20028717809a1cba23ad2..e8f0cdb27333a44b1ac9e0185c917db8d01f3d56 100644 --- a/libcxx/include/__algorithm/make_heap.h +++ b/libcxx/include/__algorithm/make_heap.h @@ -27,29 +27,29 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { __comp_ref_type<_Compare> __comp_ref = __comp; using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; - difference_type __n = __last - __first; + difference_type __n = __last - __first; if (__n > 1) { // start from the first parent, there is no need to consider children for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) { - std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start); + std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start); } } } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { std::__make_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { std::make_heap(std::move(__first), std::move(__last), __less<>()); } diff --git a/libcxx/include/__algorithm/make_projected.h b/libcxx/include/__algorithm/make_projected.h index 3a86701118146e508b5f7236f7b1a5419e54a968..bb7bc7e8c0b58df82c2368ce0a36a25bc4e42f59 100644 --- a/libcxx/include/__algorithm/make_projected.h +++ b/libcxx/include/__algorithm/make_projected.h @@ -36,44 +36,38 @@ struct _ProjectedPred { : __pred(__pred_arg), __proj(__proj_arg) {} template - typename __invoke_of<_Pred&, - decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>())) - >::type - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_Tp&& __v) const { + typename __invoke_of<_Pred&, decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>())) >:: + type _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI + operator()(_Tp&& __v) const { return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v))); } template typename __invoke_of<_Pred&, decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())), - decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>())) - >::type - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_T1&& __lhs, _T2&& __rhs) const { - return std::__invoke(__pred, - std::__invoke(__proj, std::forward<_T1>(__lhs)), - std::__invoke(__proj, std::forward<_T2>(__rhs))); + decltype(std::__invoke(std::declval<_Proj&>(), + std::declval<_T2>())) >::type _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI + operator()(_T1&& __lhs, _T2&& __rhs) const { + return std::__invoke( + __pred, std::__invoke(__proj, std::forward<_T1>(__lhs)), std::__invoke(__proj, std::forward<_T2>(__rhs))); } - }; -template >::value && - __is_identity<__decay_t<_Proj> >::value), - int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj> -__make_projected(_Pred& __pred, _Proj& __proj) { +template < + class _Pred, + class _Proj, + __enable_if_t >::value && __is_identity<__decay_t<_Proj> >::value), int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj> __make_projected(_Pred& __pred, _Proj& __proj) { return _ProjectedPred<_Pred, _Proj>(__pred, __proj); } // Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable // optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in // the call stack when the comparator is invoked, even in an unoptimized build. -template >::value && - __is_identity<__decay_t<_Proj> >::value, - int> = 0> +template < + class _Pred, + class _Proj, + __enable_if_t >::value && __is_identity<__decay_t<_Proj> >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) { return __pred; } @@ -87,8 +81,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template -_LIBCPP_HIDE_FROM_ABI constexpr -decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) { +_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) { if constexpr (__is_identity>::value && __is_identity>::value && !is_member_pointer_v>) { // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable @@ -98,8 +91,8 @@ decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __p } else { return [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, - std::invoke(__proj1, std::forward(__lhs)), - std::invoke(__proj2, std::forward(__rhs))); + std::invoke(__proj1, std::forward(__lhs)), + std::invoke(__proj2, std::forward(__rhs))); }; } } diff --git a/libcxx/include/__algorithm/max.h b/libcxx/include/__algorithm/max.h index 183a4e9cac062996544b87b599e3f3261b14b8cc..8171677f155c9ce765932d9af90bbb955da514fa 100644 --- a/libcxx/include/__algorithm/max.h +++ b/libcxx/include/__algorithm/max.h @@ -25,41 +25,28 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp& -max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) -{ - return __comp(__a, __b) ? __b : __a; +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { + return __comp(__a, __b) ? __b : __a; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp& -max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) -{ - return std::max(__a, __b, __less<>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { + return std::max(__a, __b, __less<>()); } #ifndef _LIBCPP_CXX03_LANG -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp -max(initializer_list<_Tp> __t, _Compare __comp) -{ - return *std::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp +max(initializer_list<_Tp> __t, _Compare __comp) { + return *std::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp -max(initializer_list<_Tp> __t) -{ - return *std::max_element(__t.begin(), __t.end(), __less<>()); +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t) { + return *std::max_element(__t.begin(), __t.end(), __less<>()); } #endif // _LIBCPP_CXX03_LANG diff --git a/libcxx/include/__algorithm/max_element.h b/libcxx/include/__algorithm/max_element.h index a2dc9707c00b83a54c785d11ff3310b62e3e7176..f1d4f1cd0938c11081fb978fe3534ef20be86b48 100644 --- a/libcxx/include/__algorithm/max_element.h +++ b/libcxx/include/__algorithm/max_element.h @@ -22,33 +22,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - static_assert(__has_forward_iterator_category<_ForwardIterator>::value, - "std::max_element requires a ForwardIterator"); - if (__first != __last) - { - _ForwardIterator __i = __first; - while (++__i != __last) - if (__comp(*__first, *__i)) - __first = __i; - } - return __first; +__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + static_assert( + __has_forward_iterator_category<_ForwardIterator>::value, "std::max_element requires a ForwardIterator"); + if (__first != __last) { + _ForwardIterator __i = __first; + while (++__i != __last) + if (__comp(*__first, *__i)) + __first = __i; + } + return __first; } template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - return std::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp); +max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + return std::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp); } - template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -max_element(_ForwardIterator __first, _ForwardIterator __last) -{ - return std::max_element(__first, __last, __less<>()); +max_element(_ForwardIterator __first, _ForwardIterator __last) { + return std::max_element(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/merge.h b/libcxx/include/__algorithm/merge.h index 8a6021f1880b2a8c03931dd374bc3cca856d7526..bad663c4b9f1024805c71ede00db864526466a24 100644 --- a/libcxx/include/__algorithm/merge.h +++ b/libcxx/include/__algorithm/merge.h @@ -22,45 +22,46 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -__merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - for (; __first1 != __last1; ++__result) - { - if (__first2 == __last2) - return std::copy(__first1, __last1, __result); - if (__comp(*__first2, *__first1)) - { - *__result = *__first2; - ++__first2; - } - else - { - *__result = *__first1; - ++__first1; - } +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator __merge( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + for (; __first1 != __last1; ++__result) { + if (__first2 == __last2) + return std::copy(__first1, __last1, __result); + if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + } else { + *__result = *__first1; + ++__first1; } - return std::copy(__first2, __last2, __result); + } + return std::copy(__first2, __last2, __result); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - return std::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +merge(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + return std::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) -{ - return std::merge(__first1, __last1, __first2, __last2, __result, __less<>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +merge(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result) { + return std::merge(__first1, __last1, __first2, __last2, __result, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/min.h b/libcxx/include/__algorithm/min.h index 58574517132f25cd66b44af8ab02970d04951256..919508486fd5b39e2d4ea6ae356e4255ce878233 100644 --- a/libcxx/include/__algorithm/min.h +++ b/libcxx/include/__algorithm/min.h @@ -25,41 +25,28 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp& -min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) -{ - return __comp(__b, __a) ? __b : __a; +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { + return __comp(__b, __a) ? __b : __a; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp& -min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) -{ - return std::min(__a, __b, __less<>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { + return std::min(__a, __b, __less<>()); } #ifndef _LIBCPP_CXX03_LANG -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp -min(initializer_list<_Tp> __t, _Compare __comp) -{ - return *std::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp +min(initializer_list<_Tp> __t, _Compare __comp) { + return *std::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp -min(initializer_list<_Tp> __t) -{ - return *std::min_element(__t.begin(), __t.end(), __less<>()); +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t) { + return *std::min_element(__t.begin(), __t.end(), __less<>()); } #endif // _LIBCPP_CXX03_LANG diff --git a/libcxx/include/__algorithm/min_element.h b/libcxx/include/__algorithm/min_element.h index 0ce7af69333ffa48b6ba2883ce69ae7c683c3046..c576d665601db3bf9a198a2fca54ba1cd32e433c 100644 --- a/libcxx/include/__algorithm/min_element.h +++ b/libcxx/include/__algorithm/min_element.h @@ -28,8 +28,8 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter +__min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) { if (__first == __last) return __first; @@ -42,29 +42,26 @@ _Iter __min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) { } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter __min_element(_Iter __first, _Sent __last, _Comp __comp) { auto __proj = __identity(); return std::__min_element<_Comp>(std::move(__first), std::move(__last), __comp, __proj); } template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - static_assert(__has_forward_iterator_category<_ForwardIterator>::value, - "std::min_element requires a ForwardIterator"); - static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, - "The comparator has to be callable"); +min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + static_assert( + __has_forward_iterator_category<_ForwardIterator>::value, "std::min_element requires a ForwardIterator"); + static_assert( + __is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, "The comparator has to be callable"); return std::__min_element<__comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp); } template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -min_element(_ForwardIterator __first, _ForwardIterator __last) -{ - return std::min_element(__first, __last, __less<>()); +min_element(_ForwardIterator __first, _ForwardIterator __last) { + return std::min_element(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/min_max_result.h b/libcxx/include/__algorithm/min_max_result.h index ef2d99038087b5e7e4f3f4924bf9ada2d2b41977..e988df7c114ee5baaa91696690a77511c66405ae 100644 --- a/libcxx/include/__algorithm/min_max_result.h +++ b/libcxx/include/__algorithm/min_max_result.h @@ -34,7 +34,7 @@ struct min_max_result { template requires convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const & { + _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const& { return {min, max}; } diff --git a/libcxx/include/__algorithm/minmax.h b/libcxx/include/__algorithm/minmax.h index 115bf93f90bad8603263167de35f9e87cdec9d4b..5227b885717542384dd36fdd3e6b517014898282 100644 --- a/libcxx/include/__algorithm/minmax.h +++ b/libcxx/include/__algorithm/minmax.h @@ -23,43 +23,33 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair -minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) -{ - return __comp(__b, __a) ? pair(__b, __a) : - pair(__a, __b); +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair +minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { + return __comp(__b, __a) ? pair(__b, __a) : pair(__a, __b); } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair -minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) -{ - return std::minmax(__a, __b, __less<>()); +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair +minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { + return std::minmax(__a, __b, __less<>()); } #ifndef _LIBCPP_CXX03_LANG -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t, _Compare __comp) { - static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); - __identity __proj; - auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj); - return pair<_Tp, _Tp>(*__ret.first, *__ret.second); +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> +minmax(initializer_list<_Tp> __t, _Compare __comp) { + static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); + __identity __proj; + auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj); + return pair<_Tp, _Tp>(*__ret.first, *__ret.second); } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Tp, _Tp> -minmax(initializer_list<_Tp> __t) -{ - return std::minmax(__t, __less<>()); +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> +minmax(initializer_list<_Tp> __t) { + return std::minmax(__t, __less<>()); } #endif // _LIBCPP_CXX03_LANG diff --git a/libcxx/include/__algorithm/minmax_element.h b/libcxx/include/__algorithm/minmax_element.h index 5bcaf8354d9ffb6f83545e8030416d9386f085c0..ff8cda321cef47df7e3d467709d2a01f6aba9afb 100644 --- a/libcxx/include/__algorithm/minmax_element.h +++ b/libcxx/include/__algorithm/minmax_element.h @@ -29,19 +29,18 @@ class _MinmaxElementLessFunc { _Proj& __proj_; public: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - _MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj) : __comp_(__comp), __proj_(__proj) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj) + : __comp_(__comp), __proj_(__proj) {} template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - bool operator()(_Iter& __it1, _Iter& __it2) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(_Iter& __it1, _Iter& __it2) { return std::__invoke(__comp_, std::__invoke(__proj_, *__it1), std::__invoke(__proj_, *__it2)); } }; template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> +__minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj); pair<_Iter, _Iter> __result(__first, __first); @@ -66,8 +65,8 @@ pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __c if (__less(__first, __i)) { if (__less(__first, __result.first)) __result.first = __first; - if (!__less(__i, __result.second)) - __result.second = __i; + if (!__less(__i, __result.second)) + __result.second = __i; } else { if (__less(__i, __result.first)) __result.first = __i; @@ -80,21 +79,21 @@ pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __c } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - static_assert(__has_forward_iterator_category<_ForwardIterator>::value, - "std::minmax_element requires a ForwardIterator"); - static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, - "The comparator has to be callable"); + static_assert( + __has_forward_iterator_category<_ForwardIterator>::value, "std::minmax_element requires a ForwardIterator"); + static_assert( + __is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, "The comparator has to be callable"); auto __proj = __identity(); return std::__minmax_element_impl(__first, __last, __comp, __proj); } template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) { - return std::minmax_element(__first, __last, __less<>()); + pair<_ForwardIterator, _ForwardIterator> + minmax_element(_ForwardIterator __first, _ForwardIterator __last) { + return std::minmax_element(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h index 8330d21d56f3bdc60d847d4d7d556ba0cdfe1843..d345b6048a7e9be1bb4b244099ea440aecae68b3 100644 --- a/libcxx/include/__algorithm/mismatch.h +++ b/libcxx/include/__algorithm/mismatch.h @@ -22,9 +22,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> - mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { for (; __first1 != __last1; ++__first1, (void)++__first2) if (!__pred(*__first1, *__first2)) break; @@ -32,18 +31,19 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> - mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { return std::mismatch(__first1, __last1, __first2, __equal_to()); } #if _LIBCPP_STD_VER >= 14 template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> - mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, - _BinaryPredicate __pred) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _BinaryPredicate __pred) { for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) if (!__pred(*__first1, *__first2)) break; @@ -51,9 +51,8 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> - mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::mismatch(__first1, __last1, __first2, __last2, __equal_to()); } #endif diff --git a/libcxx/include/__algorithm/move.h b/libcxx/include/__algorithm/move.h index e0da07117e66c9f10bfe11ecc5f6c14bc8c95793..dba6d487fff77ed7ece7fefe234d239822bf19fa 100644 --- a/libcxx/include/__algorithm/move.h +++ b/libcxx/include/__algorithm/move.h @@ -99,8 +99,7 @@ struct __move_loop { struct __move_trivial { // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. - template ::value, int> = 0> + template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> operator()(_In* __first, _In* __last, _Out* __result) const { return std::__copy_trivial_impl(__first, __last, __result); diff --git a/libcxx/include/__algorithm/move_backward.h b/libcxx/include/__algorithm/move_backward.h index 8151e4ef3243f4f4c715a0ce01a67e738c682ce6..aeedf4241dce9cbc4635a27fa228adb4d464db7a 100644 --- a/libcxx/include/__algorithm/move_backward.h +++ b/libcxx/include/__algorithm/move_backward.h @@ -108,8 +108,7 @@ struct __move_backward_loop { struct __move_backward_trivial { // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. - template ::value, int> = 0> + template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> operator()(_In* __first, _In* __last, _Out* __result) const { return std::__copy_backward_trivial_impl(__first, __last, __result); @@ -120,7 +119,8 @@ template __move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) { static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && - std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); + std::is_copy_constructible<_BidirectionalIterator1>::value, + "Iterators must be copy constructible."); return std::__dispatch_copy_or_move<_AlgPolicy, __move_backward_loop<_AlgPolicy>, __move_backward_trivial>( std::move(__first), std::move(__last), std::move(__result)); diff --git a/libcxx/include/__algorithm/next_permutation.h b/libcxx/include/__algorithm/next_permutation.h index ebaed15ae2ad06d1352a9f5953a972b980a1e35b..d66ea9b973453f6c7be9c0af3fbb4dbabff8648d 100644 --- a/libcxx/include/__algorithm/next_permutation.h +++ b/libcxx/include/__algorithm/next_permutation.h @@ -26,50 +26,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool> -__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) -{ - using _Result = pair<_BidirectionalIterator, bool>; +__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) { + using _Result = pair<_BidirectionalIterator, bool>; - _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); - _BidirectionalIterator __i = __last_iter; - if (__first == __last || __first == --__i) - return _Result(std::move(__last_iter), false); + _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + _BidirectionalIterator __i = __last_iter; + if (__first == __last || __first == --__i) + return _Result(std::move(__last_iter), false); - while (true) - { - _BidirectionalIterator __ip1 = __i; - if (__comp(*--__i, *__ip1)) - { - _BidirectionalIterator __j = __last_iter; - while (!__comp(*__i, *--__j)) - ; - _IterOps<_AlgPolicy>::iter_swap(__i, __j); - std::__reverse<_AlgPolicy>(__ip1, __last_iter); - return _Result(std::move(__last_iter), true); - } - if (__i == __first) - { - std::__reverse<_AlgPolicy>(__first, __last_iter); - return _Result(std::move(__last_iter), false); - } + while (true) { + _BidirectionalIterator __ip1 = __i; + if (__comp(*--__i, *__ip1)) { + _BidirectionalIterator __j = __last_iter; + while (!__comp(*__i, *--__j)) + ; + _IterOps<_AlgPolicy>::iter_swap(__i, __j); + std::__reverse<_AlgPolicy>(__ip1, __last_iter); + return _Result(std::move(__last_iter), true); } + if (__i == __first) { + std::__reverse<_AlgPolicy>(__first, __last_iter); + return _Result(std::move(__last_iter), false); + } + } } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { return std::__next_permutation<_ClassicAlgPolicy>( - std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; + std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)) + .second; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) -{ - return std::next_permutation(__first, __last, __less<>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { + return std::next_permutation(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/nth_element.h b/libcxx/include/__algorithm/nth_element.h index 6b3b2bb434d5fb3ccdb0220e6b1635f3dcb44cc4..a059705125951819953a46088ae49357bd5e8a65 100644 --- a/libcxx/include/__algorithm/nth_element.h +++ b/libcxx/include/__algorithm/nth_element.h @@ -25,224 +25,207 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool -__nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j, - _RandomAccessIterator __m, _Compare __comp) -{ - // manually guard downward moving __j against __i - while (true) { - if (__i == --__j) { - return false; - } - if (__comp(*__j, *__m)) { - return true; // found guard for downward moving __j, now use unguarded partition - } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __nth_element_find_guard( + _RandomAccessIterator& __i, _RandomAccessIterator& __j, _RandomAccessIterator __m, _Compare __comp) { + // manually guard downward moving __j against __i + while (true) { + if (__i == --__j) { + return false; } + if (__comp(*__j, *__m)) { + return true; // found guard for downward moving __j, now use unguarded partition + } + } } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void // NOLINTNEXTLINE(readability-function-cognitive-complexity) -__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) -{ - using _Ops = _IterOps<_AlgPolicy>; +__nth_element( + _RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; - // _Compare is known to be a reference type - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - const difference_type __limit = 7; - while (true) + // _Compare is known to be a reference type + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + const difference_type __limit = 7; + while (true) { + if (__nth == __last) + return; + difference_type __len = __last - __first; + switch (__len) { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + _Ops::iter_swap(__first, __last); + return; + case 3: { + _RandomAccessIterator __m = __first; + std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp); + return; + } + } + if (__len <= __limit) { + std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp); + return; + } + // __len > __limit >= 3 + _RandomAccessIterator __m = __first + __len / 2; + _RandomAccessIterator __lm1 = __last; + unsigned __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, --__lm1, __comp); + // *__m is median + // partition [__first, __m) < *__m and *__m <= [__m, __last) + // (this inhibits tossing elements equivalent to __m around unnecessarily) + _RandomAccessIterator __i = __first; + _RandomAccessIterator __j = __lm1; + // j points beyond range to be tested, *__lm1 is known to be <= *__m + // The search going up is known to be guarded but the search coming down isn't. + // Prime the downward search with a guard. + if (!__comp(*__i, *__m)) // if *__first == *__m { - if (__nth == __last) - return; - difference_type __len = __last - __first; - switch (__len) - { - case 0: - case 1: - return; - case 2: - if (__comp(*--__last, *__first)) - _Ops::iter_swap(__first, __last); - return; - case 3: - { - _RandomAccessIterator __m = __first; - std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp); - return; + // *__first == *__m, *__first doesn't go in first part + if (std::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) { + _Ops::iter_swap(__i, __j); + ++__n_swaps; + } else { + // *__first == *__m, *__m <= all other elements + // Partition instead into [__first, __i) == *__first and *__first < [__i, __last) + ++__i; // __first + 1 + __j = __last; + if (!__comp(*__first, *--__j)) { // we need a guard if *__first == *(__last-1) + while (true) { + if (__i == __j) { + return; // [__first, __last) all equivalent elements + } else if (__comp(*__first, *__i)) { + _Ops::iter_swap(__i, __j); + ++__n_swaps; + ++__i; + break; } + ++__i; + } } - if (__len <= __limit) - { - std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp); - return; + // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 + if (__i == __j) { + return; } - // __len > __limit >= 3 - _RandomAccessIterator __m = __first + __len/2; - _RandomAccessIterator __lm1 = __last; - unsigned __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, --__lm1, __comp); - // *__m is median - // partition [__first, __m) < *__m and *__m <= [__m, __last) - // (this inhibits tossing elements equivalent to __m around unnecessarily) - _RandomAccessIterator __i = __first; - _RandomAccessIterator __j = __lm1; - // j points beyond range to be tested, *__lm1 is known to be <= *__m - // The search going up is known to be guarded but the search coming down isn't. - // Prime the downward search with a guard. - if (!__comp(*__i, *__m)) // if *__first == *__m - { - // *__first == *__m, *__first doesn't go in first part - if (std::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) { - _Ops::iter_swap(__i, __j); - ++__n_swaps; - } else { - // *__first == *__m, *__m <= all other elements - // Partition instead into [__first, __i) == *__first and *__first < [__i, __last) - ++__i; // __first + 1 - __j = __last; - if (!__comp(*__first, *--__j)) { // we need a guard if *__first == *(__last-1) - while (true) { - if (__i == __j) { - return; // [__first, __last) all equivalent elements - } else if (__comp(*__first, *__i)) { - _Ops::iter_swap(__i, __j); - ++__n_swaps; - ++__i; - break; - } - ++__i; - } - } - // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 - if (__i == __j) { - return; - } - while (true) { - while (!__comp(*__first, *__i)) { - ++__i; - _LIBCPP_ASSERT_UNCATEGORIZED( - __i != __last, - "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); - } - do { - _LIBCPP_ASSERT_UNCATEGORIZED( - __j != __first, - "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); - --__j; - } while (__comp(*__first, *__j)); - if (__i >= __j) - break; - _Ops::iter_swap(__i, __j); - ++__n_swaps; - ++__i; - } - // [__first, __i) == *__first and *__first < [__i, __last) - // The first part is sorted, - if (__nth < __i) { - return; - } - // __nth_element the second part - // std::__nth_element<_Compare>(__i, __nth, __last, __comp); - __first = __i; - continue; - } + while (true) { + while (!__comp(*__first, *__i)) { + ++__i; + _LIBCPP_ASSERT_UNCATEGORIZED( + __i != __last, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + } + do { + _LIBCPP_ASSERT_UNCATEGORIZED( + __j != __first, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + --__j; + } while (__comp(*__first, *__j)); + if (__i >= __j) + break; + _Ops::iter_swap(__i, __j); + ++__n_swaps; + ++__i; } - ++__i; - // j points beyond range to be tested, *__lm1 is known to be <= *__m - // if not yet partitioned... - if (__i < __j) - { - // known that *(__i - 1) < *__m - while (true) - { - // __m still guards upward moving __i - while (__comp(*__i, *__m)) { - ++__i; - _LIBCPP_ASSERT_UNCATEGORIZED( - __i != __last, - "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); - } - // It is now known that a guard exists for downward moving __j - do { - _LIBCPP_ASSERT_UNCATEGORIZED( - __j != __first, - "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); - --__j; - } while (!__comp(*__j, *__m)); - if (__i >= __j) - break; - _Ops::iter_swap(__i, __j); - ++__n_swaps; - // It is known that __m != __j - // If __m just moved, follow it - if (__m == __i) - __m = __j; - ++__i; - } + // [__first, __i) == *__first and *__first < [__i, __last) + // The first part is sorted, + if (__nth < __i) { + return; } - // [__first, __i) < *__m and *__m <= [__i, __last) - if (__i != __m && __comp(*__m, *__i)) - { - _Ops::iter_swap(__i, __m); - ++__n_swaps; + // __nth_element the second part + // std::__nth_element<_Compare>(__i, __nth, __last, __comp); + __first = __i; + continue; + } + } + ++__i; + // j points beyond range to be tested, *__lm1 is known to be <= *__m + // if not yet partitioned... + if (__i < __j) { + // known that *(__i - 1) < *__m + while (true) { + // __m still guards upward moving __i + while (__comp(*__i, *__m)) { + ++__i; + _LIBCPP_ASSERT_UNCATEGORIZED( + __i != __last, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); } - // [__first, __i) < *__i and *__i <= [__i+1, __last) - if (__nth == __i) + // It is now known that a guard exists for downward moving __j + do { + _LIBCPP_ASSERT_UNCATEGORIZED( + __j != __first, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + --__j; + } while (!__comp(*__j, *__m)); + if (__i >= __j) + break; + _Ops::iter_swap(__i, __j); + ++__n_swaps; + // It is known that __m != __j + // If __m just moved, follow it + if (__m == __i) + __m = __j; + ++__i; + } + } + // [__first, __i) < *__m and *__m <= [__i, __last) + if (__i != __m && __comp(*__m, *__i)) { + _Ops::iter_swap(__i, __m); + ++__n_swaps; + } + // [__first, __i) < *__i and *__i <= [__i+1, __last) + if (__nth == __i) + return; + if (__n_swaps == 0) { + // We were given a perfectly partitioned sequence. Coincidence? + if (__nth < __i) { + // Check for [__first, __i) already sorted + __j = __m = __first; + while (true) { + if (++__j == __i) { + // [__first, __i) sorted return; - if (__n_swaps == 0) - { - // We were given a perfectly partitioned sequence. Coincidence? - if (__nth < __i) - { - // Check for [__first, __i) already sorted - __j = __m = __first; - while (true) { - if (++__j == __i) { - // [__first, __i) sorted - return; - } - if (__comp(*__j, *__m)) { - // not yet sorted, so sort - break; - } - __m = __j; - } - } - else - { - // Check for [__i, __last) already sorted - __j = __m = __i; - while (true) { - if (++__j == __last) { - // [__i, __last) sorted - return; - } - if (__comp(*__j, *__m)) { - // not yet sorted, so sort - break; - } - __m = __j; - } - } - } - // __nth_element on range containing __nth - if (__nth < __i) - { - // std::__nth_element<_Compare>(__first, __nth, __i, __comp); - __last = __i; + } + if (__comp(*__j, *__m)) { + // not yet sorted, so sort + break; + } + __m = __j; } - else - { - // std::__nth_element<_Compare>(__i+1, __nth, __last, __comp); - __first = ++__i; + } else { + // Check for [__i, __last) already sorted + __j = __m = __i; + while (true) { + if (++__j == __last) { + // [__i, __last) sorted + return; + } + if (__comp(*__j, *__m)) { + // not yet sorted, so sort + break; + } + __m = __j; } + } + } + // __nth_element on range containing __nth + if (__nth < __i) { + // std::__nth_element<_Compare>(__first, __nth, __i, __comp); + __last = __i; + } else { + // std::__nth_element<_Compare>(__i+1, __nth, __last, __comp); + __first = ++__i; } + } } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, - _Compare& __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __nth_element_impl( + _RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare& __comp) { if (__nth == __last) return; @@ -257,15 +240,14 @@ void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __n } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, - _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { std::__nth_element_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__nth), std::move(__last), __comp); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) { std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>()); } diff --git a/libcxx/include/__algorithm/partial_sort.h b/libcxx/include/__algorithm/partial_sort.h index de4ebfcbd85876564b8128c9c71a538cc438864a..27511a124229bbae070a3a636ff65db5e568aa61 100644 --- a/libcxx/include/__algorithm/partial_sort.h +++ b/libcxx/include/__algorithm/partial_sort.h @@ -29,8 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_RandomAccessIterator __partial_sort_impl( +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator __partial_sort_impl( _RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) { if (__first == __middle) { return _IterOps<_AlgPolicy>::next(__middle, __last); @@ -39,14 +38,12 @@ _RandomAccessIterator __partial_sort_impl( std::__make_heap<_AlgPolicy>(__first, __middle, __comp); typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; - _RandomAccessIterator __i = __middle; - for (; __i != __last; ++__i) - { - if (__comp(*__i, *__first)) - { - _IterOps<_AlgPolicy>::iter_swap(__i, __first); - std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first); - } + _RandomAccessIterator __i = __middle; + for (; __i != __last; ++__i) { + if (__comp(*__i, *__first)) { + _IterOps<_AlgPolicy>::iter_swap(__i, __first); + std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first); + } } std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp); @@ -54,11 +51,10 @@ _RandomAccessIterator __partial_sort_impl( } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, - _Compare& __comp) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare& __comp) { if (__first == __middle) - return _IterOps<_AlgPolicy>::next(__middle, __last); + return _IterOps<_AlgPolicy>::next(__middle, __last); std::__debug_randomize_range<_AlgPolicy>(__first, __last); @@ -71,11 +67,8 @@ _RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAcces } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, - _Compare __comp) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void partial_sort( + _RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); @@ -83,11 +76,9 @@ partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ran } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) -{ - std::partial_sort(__first, __middle, __last, __less<>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) { + std::partial_sort(__first, __middle, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/partial_sort_copy.h b/libcxx/include/__algorithm/partial_sort_copy.h index 2c1e786d030eb0f9e5e2fe05986865d6a79ce713..e7d8df4de89f95e62dc1780f38f96f3999124c79 100644 --- a/libcxx/include/__algorithm/partial_sort_copy.h +++ b/libcxx/include/__algorithm/partial_sort_copy.h @@ -30,56 +30,70 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator> -__partial_sort_copy(_InputIterator __first, _Sentinel1 __last, - _RandomAccessIterator __result_first, _Sentinel2 __result_last, - _Compare&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) -{ - _RandomAccessIterator __r = __result_first; - auto&& __projected_comp = std::__make_projected(__comp, __proj2); +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator> __partial_sort_copy( + _InputIterator __first, + _Sentinel1 __last, + _RandomAccessIterator __result_first, + _Sentinel2 __result_last, + _Compare&& __comp, + _Proj1&& __proj1, + _Proj2&& __proj2) { + _RandomAccessIterator __r = __result_first; + auto&& __projected_comp = std::__make_projected(__comp, __proj2); - if (__r != __result_last) - { - for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) - *__r = *__first; - std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp); - typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; - for (; __first != __last; ++__first) - if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) { - *__result_first = *__first; - std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first); - } - std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp); - } + if (__r != __result_last) { + for (; __first != __last && __r != __result_last; ++__first, (void)++__r) + *__r = *__first; + std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp); + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; + for (; __first != __last; ++__first) + if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) { + *__result_first = *__first; + std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first); + } + std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp); + } - return pair<_InputIterator, _RandomAccessIterator>( - _IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r)); + return pair<_InputIterator, _RandomAccessIterator>( + _IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r)); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_RandomAccessIterator -partial_sort_copy(_InputIterator __first, _InputIterator __last, - _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) -{ - static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, - "Comparator has to be callable"); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy( + _InputIterator __first, + _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last, + _Compare __comp) { + static_assert( + __is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, "Comparator has to be callable"); - auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(__first, __last, __result_first, __result_last, - static_cast<__comp_ref_type<_Compare> >(__comp), __identity(), __identity()); + auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>( + __first, + __last, + __result_first, + __result_last, + static_cast<__comp_ref_type<_Compare> >(__comp), + __identity(), + __identity()); return __result.second; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_RandomAccessIterator -partial_sort_copy(_InputIterator __first, _InputIterator __last, - _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) -{ - return std::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy( + _InputIterator __first, + _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last) { + return std::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/partition.h b/libcxx/include/__algorithm/partition.h index a6aaf634aaa5b5637acd6b3a6ef4a6b471647f80..e2ceb07bf19588b04c521fc512efdf00b160dd95 100644 --- a/libcxx/include/__algorithm/partition.h +++ b/libcxx/include/__algorithm/partition.h @@ -23,70 +23,58 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> -__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) -{ - while (true) - { - if (__first == __last) - return std::make_pair(std::move(__first), std::move(__first)); - if (!__pred(*__first)) - break; - ++__first; - } +__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) { + while (true) { + if (__first == __last) + return std::make_pair(std::move(__first), std::move(__first)); + if (!__pred(*__first)) + break; + ++__first; + } - _ForwardIterator __p = __first; - while (++__p != __last) - { - if (__pred(*__p)) - { - _IterOps<_AlgPolicy>::iter_swap(__first, __p); - ++__first; - } + _ForwardIterator __p = __first; + while (++__p != __last) { + if (__pred(*__p)) { + _IterOps<_AlgPolicy>::iter_swap(__first, __p); + ++__first; } - return std::make_pair(std::move(__first), std::move(__p)); + } + return std::make_pair(std::move(__first), std::move(__p)); } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator> -__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, - bidirectional_iterator_tag) -{ - _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel); - _BidirectionalIterator __last = __original_last; +__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, bidirectional_iterator_tag) { + _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel); + _BidirectionalIterator __last = __original_last; - while (true) - { - while (true) - { - if (__first == __last) - return std::make_pair(std::move(__first), std::move(__original_last)); - if (!__pred(*__first)) - break; - ++__first; - } - do - { - if (__first == --__last) - return std::make_pair(std::move(__first), std::move(__original_last)); - } while (!__pred(*__last)); - _IterOps<_AlgPolicy>::iter_swap(__first, __last); - ++__first; + while (true) { + while (true) { + if (__first == __last) + return std::make_pair(std::move(__first), std::move(__original_last)); + if (!__pred(*__first)) + break; + ++__first; } + do { + if (__first == --__last) + return std::make_pair(std::move(__first), std::move(__original_last)); + } while (!__pred(*__last)); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + ++__first; + } } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -pair<_ForwardIterator, _ForwardIterator> __partition( - _ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +__partition(_ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) { return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>( std::move(__first), std::move(__last), __pred, __iter_category); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator -partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory()); return __result.first; diff --git a/libcxx/include/__algorithm/partition_copy.h b/libcxx/include/__algorithm/partition_copy.h index ff8826a9371250c410c2ed81c617a2629199cbb9..147b45c7882a517ec94824df9c5d3908ddf2c9a8 100644 --- a/libcxx/include/__algorithm/partition_copy.h +++ b/libcxx/include/__algorithm/partition_copy.h @@ -19,27 +19,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2> -partition_copy(_InputIterator __first, _InputIterator __last, - _OutputIterator1 __out_true, _OutputIterator2 __out_false, - _Predicate __pred) -{ - for (; __first != __last; ++__first) - { - if (__pred(*__first)) - { - *__out_true = *__first; - ++__out_true; - } - else - { - *__out_false = *__first; - ++__out_false; - } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2> partition_copy( + _InputIterator __first, + _InputIterator __last, + _OutputIterator1 __out_true, + _OutputIterator2 __out_false, + _Predicate __pred) { + for (; __first != __last; ++__first) { + if (__pred(*__first)) { + *__out_true = *__first; + ++__out_true; + } else { + *__out_false = *__first; + ++__out_false; } - return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); + } + return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/partition_point.h b/libcxx/include/__algorithm/partition_point.h index a61ed5ec5b41bfee5e04a8b4ee088348f0dc00ae..504dbf1d1a0556a8a7e6d1301f4397a71a806b6f 100644 --- a/libcxx/include/__algorithm/partition_point.h +++ b/libcxx/include/__algorithm/partition_point.h @@ -21,26 +21,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template +template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ - typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; - difference_type __len = std::distance(__first, __last); - while (__len != 0) - { - difference_type __l2 = std::__half_positive(__len); - _ForwardIterator __m = __first; - std::advance(__m, __l2); - if (__pred(*__m)) - { - __first = ++__m; - __len -= __l2 + 1; - } - else - __len = __l2; - } - return __first; +partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + difference_type __len = std::distance(__first, __last); + while (__len != 0) { + difference_type __l2 = std::__half_positive(__len); + _ForwardIterator __m = __first; + std::advance(__m, __l2); + if (__pred(*__m)) { + __first = ++__m; + __len -= __l2 + 1; + } else + __len = __l2; + } + return __first; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/pop_heap.h b/libcxx/include/__algorithm/pop_heap.h index 033af6f2f80fdcc26d20fa76cb32b9a8cab2c712..a93a9875f70581400047e13b4edc5dc4774fed3e 100644 --- a/libcxx/include/__algorithm/pop_heap.h +++ b/libcxx/include/__algorithm/pop_heap.h @@ -31,16 +31,18 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) { _LIBCPP_ASSERT_UNCATEGORIZED(__len > 0, "The heap given to pop_heap must be non-empty"); __comp_ref_type<_Compare> __comp_ref = __comp; using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; if (__len > 1) { - value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first + value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first _RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len); --__last; @@ -56,8 +58,8 @@ void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); @@ -66,8 +68,8 @@ void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { std::pop_heap(std::move(__first), std::move(__last), __less<>()); } diff --git a/libcxx/include/__algorithm/prev_permutation.h b/libcxx/include/__algorithm/prev_permutation.h index 4a6bf4a664399258e3352f9d3cc7f9a8709a1926..3e4bbb3fbb1670e809523ff2b053d99fd78ba821 100644 --- a/libcxx/include/__algorithm/prev_permutation.h +++ b/libcxx/include/__algorithm/prev_permutation.h @@ -25,52 +25,44 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -pair<_BidirectionalIterator, bool> -__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) -{ - using _Result = pair<_BidirectionalIterator, bool>; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool> +__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) { + using _Result = pair<_BidirectionalIterator, bool>; - _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); - _BidirectionalIterator __i = __last_iter; - if (__first == __last || __first == --__i) - return _Result(std::move(__last_iter), false); + _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + _BidirectionalIterator __i = __last_iter; + if (__first == __last || __first == --__i) + return _Result(std::move(__last_iter), false); - while (true) - { - _BidirectionalIterator __ip1 = __i; - if (__comp(*__ip1, *--__i)) - { - _BidirectionalIterator __j = __last_iter; - while (!__comp(*--__j, *__i)) - ; - _IterOps<_AlgPolicy>::iter_swap(__i, __j); - std::__reverse<_AlgPolicy>(__ip1, __last_iter); - return _Result(std::move(__last_iter), true); - } - if (__i == __first) - { - std::__reverse<_AlgPolicy>(__first, __last_iter); - return _Result(std::move(__last_iter), false); - } + while (true) { + _BidirectionalIterator __ip1 = __i; + if (__comp(*__ip1, *--__i)) { + _BidirectionalIterator __j = __last_iter; + while (!__comp(*--__j, *__i)) + ; + _IterOps<_AlgPolicy>::iter_swap(__i, __j); + std::__reverse<_AlgPolicy>(__ip1, __last_iter); + return _Result(std::move(__last_iter), true); } + if (__i == __first) { + std::__reverse<_AlgPolicy>(__first, __last_iter); + return _Result(std::move(__last_iter), false); + } + } } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { return std::__prev_permutation<_ClassicAlgPolicy>( - std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; + std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)) + .second; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) -{ - return std::prev_permutation(__first, __last, __less<>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { + return std::prev_permutation(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/push_heap.h b/libcxx/include/__algorithm/push_heap.h index 82b571e44bd4dd9bf060ab5fcc48419df05d67e8..7d8720e3a93d44855c89912e68ab696c79b53040 100644 --- a/libcxx/include/__algorithm/push_heap.h +++ b/libcxx/include/__algorithm/push_heap.h @@ -28,20 +28,22 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__sift_up(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare&& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) { using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; if (__len > 1) { - __len = (__len - 2) / 2; + __len = (__len - 2) / 2; _RandomAccessIterator __ptr = __first + __len; if (__comp(*__ptr, *--__last)) { value_type __t(_IterOps<_AlgPolicy>::__iter_move(__last)); do { *__last = _IterOps<_AlgPolicy>::__iter_move(__ptr); - __last = __ptr; + __last = __ptr; if (__len == 0) break; __len = (__len - 1) / 2; @@ -54,15 +56,15 @@ void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first; std::__sift_up<_AlgPolicy, __comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp, __len); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); @@ -70,8 +72,8 @@ void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { std::push_heap(std::move(__first), std::move(__last), __less<>()); } diff --git a/libcxx/include/__algorithm/remove.h b/libcxx/include/__algorithm/remove.h index eff22757186e3c8de6608ebe3807aea6008ef43f..2b9d4ff26ed2a54f5cd1d7650cc2b41174938198 100644 --- a/libcxx/include/__algorithm/remove.h +++ b/libcxx/include/__algorithm/remove.h @@ -22,22 +22,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - __first = std::find(__first, __last, __value); - if (__first != __last) - { - _ForwardIterator __i = __first; - while (++__i != __last) - { - if (!(*__i == __value)) - { - *__first = std::move(*__i); - ++__first; - } - } +remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + __first = std::find(__first, __last, __value); + if (__first != __last) { + _ForwardIterator __i = __first; + while (++__i != __last) { + if (!(*__i == __value)) { + *__first = std::move(*__i); + ++__first; + } } - return __first; + } + return __first; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/remove_copy.h b/libcxx/include/__algorithm/remove_copy.h index 060833813d211b80467fd832f4acad9455c5a824..7be4c166ce3d7171a521ff5cb79e8417a5d5be85 100644 --- a/libcxx/include/__algorithm/remove_copy.h +++ b/libcxx/include/__algorithm/remove_copy.h @@ -18,19 +18,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value) -{ - for (; __first != __last; ++__first) - { - if (!(*__first == __value)) - { - *__result = *__first; - ++__result; - } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value) { + for (; __first != __last; ++__first) { + if (!(*__first == __value)) { + *__result = *__first; + ++__result; } - return __result; + } + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/remove_copy_if.h b/libcxx/include/__algorithm/remove_copy_if.h index 9858d43c043f586b84f2fe2015545f1b6344e6af..dcafed169157d9740ba1038b5c25771adf15628d 100644 --- a/libcxx/include/__algorithm/remove_copy_if.h +++ b/libcxx/include/__algorithm/remove_copy_if.h @@ -18,19 +18,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) -{ - for (; __first != __last; ++__first) - { - if (!__pred(*__first)) - { - *__result = *__first; - ++__result; - } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { + for (; __first != __last; ++__first) { + if (!__pred(*__first)) { + *__result = *__first; + ++__result; } - return __result; + } + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/remove_if.h b/libcxx/include/__algorithm/remove_if.h index 8197e4fc2f8ef3a5bda7128c357877390494b202..6eceddce8d56b41760e9ee7b8248a58f3db09e2b 100644 --- a/libcxx/include/__algorithm/remove_if.h +++ b/libcxx/include/__algorithm/remove_if.h @@ -21,22 +21,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ - __first = std::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); - if (__first != __last) - { - _ForwardIterator __i = __first; - while (++__i != __last) - { - if (!__pred(*__i)) - { - *__first = std::move(*__i); - ++__first; - } - } +remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + __first = std::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); + if (__first != __last) { + _ForwardIterator __i = __first; + while (++__i != __last) { + if (!__pred(*__i)) { + *__first = std::move(*__i); + ++__first; + } } - return __first; + } + return __first; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/replace.h b/libcxx/include/__algorithm/replace.h index 09b1dac79b70840b48069467d3c61c962f4aa373..8057c78686e111e5dc5e3a4ff6af99245b9cb4c9 100644 --- a/libcxx/include/__algorithm/replace.h +++ b/libcxx/include/__algorithm/replace.h @@ -18,13 +18,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) -{ - for (; __first != __last; ++__first) - if (*__first == __old_value) - *__first = __new_value; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) { + for (; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/replace_copy.h b/libcxx/include/__algorithm/replace_copy.h index 107e92968944f01e78c0db879f7c84c10865d423..9a2258d9f58eddd80d1fde2f24bcf7e89fada86a 100644 --- a/libcxx/include/__algorithm/replace_copy.h +++ b/libcxx/include/__algorithm/replace_copy.h @@ -18,17 +18,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, - const _Tp& __old_value, const _Tp& __new_value) -{ - for (; __first != __last; ++__first, (void) ++__result) - if (*__first == __old_value) - *__result = __new_value; - else - *__result = *__first; - return __result; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator replace_copy( + _InputIterator __first, + _InputIterator __last, + _OutputIterator __result, + const _Tp& __old_value, + const _Tp& __new_value) { + for (; __first != __last; ++__first, (void)++__result) + if (*__first == __old_value) + *__result = __new_value; + else + *__result = *__first; + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/replace_copy_if.h b/libcxx/include/__algorithm/replace_copy_if.h index a77b1caa805a2e11035dfacca8f87023155f320c..c2ed30f08d598b4dd5f30b37e638c1ce8d1ae545 100644 --- a/libcxx/include/__algorithm/replace_copy_if.h +++ b/libcxx/include/__algorithm/replace_copy_if.h @@ -18,17 +18,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, - _Predicate __pred, const _Tp& __new_value) -{ - for (; __first != __last; ++__first, (void) ++__result) - if (__pred(*__first)) - *__result = __new_value; - else - *__result = *__first; - return __result; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator replace_copy_if( + _InputIterator __first, + _InputIterator __last, + _OutputIterator __result, + _Predicate __pred, + const _Tp& __new_value) { + for (; __first != __last; ++__first, (void)++__result) + if (__pred(*__first)) + *__result = __new_value; + else + *__result = *__first; + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/replace_if.h b/libcxx/include/__algorithm/replace_if.h index 05269065f025aec855e2e335072801362be0ae19..78487e3deed70929da486b5013dcff09656deb0b 100644 --- a/libcxx/include/__algorithm/replace_if.h +++ b/libcxx/include/__algorithm/replace_if.h @@ -18,13 +18,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) -{ - for (; __first != __last; ++__first) - if (__pred(*__first)) - *__first = __new_value; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/reverse.h b/libcxx/include/__algorithm/reverse.h index 86634520aa261a2e4148668461af262c3eed6d78..6bd0aa393280689e749753cd9641b14c7bf9f8fc 100644 --- a/libcxx/include/__algorithm/reverse.h +++ b/libcxx/include/__algorithm/reverse.h @@ -22,41 +22,33 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -__reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) -{ - while (__first != __last) - { - if (__first == --__last) - break; - _IterOps<_AlgPolicy>::iter_swap(__first, __last); - ++__first; - } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) { + while (__first != __last) { + if (__first == --__last) + break; + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + ++__first; + } } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -__reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) -{ - if (__first != __last) - for (; __first < --__last; ++__first) - _IterOps<_AlgPolicy>::iter_swap(__first, __last); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { + if (__first != __last) + for (; __first < --__last; ++__first) + _IterOps<_AlgPolicy>::iter_swap(__first, __last); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void __reverse(_BidirectionalIterator __first, _Sentinel __last) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __reverse(_BidirectionalIterator __first, _Sentinel __last) { using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_BidirectionalIterator>; std::__reverse_impl<_AlgPolicy>(std::move(__first), std::move(__last), _IterCategory()); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) { std::__reverse<_ClassicAlgPolicy>(std::move(__first), std::move(__last)); } diff --git a/libcxx/include/__algorithm/reverse_copy.h b/libcxx/include/__algorithm/reverse_copy.h index 7672fc86686befdc9b7c2b06c678fcea18af2ec8..0fcecc3923268172ad0d325e4c7c5ed4d4e13332 100644 --- a/libcxx/include/__algorithm/reverse_copy.h +++ b/libcxx/include/__algorithm/reverse_copy.h @@ -18,13 +18,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) -{ - for (; __first != __last; ++__result) - *__result = *--__last; - return __result; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) { + for (; __first != __last; ++__result) + *__result = *--__last; + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/rotate.h b/libcxx/include/__algorithm/rotate.h index f9236fcaafb2adbc1f4df1006f383467e5aa8f43..d8162b1a94b27245617d20a4faa27129e70ee48a 100644 --- a/libcxx/include/__algorithm/rotate.h +++ b/libcxx/include/__algorithm/rotate.h @@ -27,193 +27,165 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -__rotate_left(_ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - using _Ops = _IterOps<_AlgPolicy>; - - value_type __tmp = _Ops::__iter_move(__first); - _ForwardIterator __lm1 = std::__move<_AlgPolicy>( - _Ops::next(__first), __last, __first).second; - *__lm1 = std::move(__tmp); - return __lm1; +__rotate_left(_ForwardIterator __first, _ForwardIterator __last) { + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + using _Ops = _IterOps<_AlgPolicy>; + + value_type __tmp = _Ops::__iter_move(__first); + _ForwardIterator __lm1 = std::__move<_AlgPolicy>(_Ops::next(__first), __last, __first).second; + *__lm1 = std::move(__tmp); + return __lm1; } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator -__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) -{ - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - using _Ops = _IterOps<_AlgPolicy>; - - _BidirectionalIterator __lm1 = _Ops::prev(__last); - value_type __tmp = _Ops::__iter_move(__lm1); - _BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second; - *__first = std::move(__tmp); - return __fp1; +__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) { + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + using _Ops = _IterOps<_AlgPolicy>; + + _BidirectionalIterator __lm1 = _Ops::prev(__last); + value_type __tmp = _Ops::__iter_move(__lm1); + _BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second; + *__first = std::move(__tmp); + return __fp1; } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _ForwardIterator -__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) -{ - _ForwardIterator __i = __middle; - while (true) - { - _IterOps<_AlgPolicy>::iter_swap(__first, __i); - ++__first; - if (++__i == __last) - break; +__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { + _ForwardIterator __i = __middle; + while (true) { + _IterOps<_AlgPolicy>::iter_swap(__first, __i); + ++__first; + if (++__i == __last) + break; + if (__first == __middle) + __middle = __i; + } + _ForwardIterator __r = __first; + if (__first != __middle) { + __i = __middle; + while (true) { + _IterOps<_AlgPolicy>::iter_swap(__first, __i); + ++__first; + if (++__i == __last) { if (__first == __middle) - __middle = __i; - } - _ForwardIterator __r = __first; - if (__first != __middle) - { + break; __i = __middle; - while (true) - { - _IterOps<_AlgPolicy>::iter_swap(__first, __i); - ++__first; - if (++__i == __last) - { - if (__first == __middle) - break; - __i = __middle; - } - else if (__first == __middle) - __middle = __i; - } + } else if (__first == __middle) + __middle = __i; } - return __r; + } + return __r; } -template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral -__algo_gcd(_Integral __x, _Integral __y) -{ - do - { - _Integral __t = __x % __y; - __x = __y; - __y = __t; - } while (__y); - return __x; +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral __algo_gcd(_Integral __x, _Integral __y) { + do { + _Integral __t = __x % __y; + __x = __y; + __y = __t; + } while (__y); + return __x; } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator -__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) -{ - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - using _Ops = _IterOps<_AlgPolicy>; - - const difference_type __m1 = __middle - __first; - const difference_type __m2 = _Ops::distance(__middle, __last); - if (__m1 == __m2) - { - std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last); - return __middle; - } - const difference_type __g = std::__algo_gcd(__m1, __m2); - for (_RandomAccessIterator __p = __first + __g; __p != __first;) - { - value_type __t(_Ops::__iter_move(--__p)); - _RandomAccessIterator __p1 = __p; - _RandomAccessIterator __p2 = __p1 + __m1; - do - { - *__p1 = _Ops::__iter_move(__p2); - __p1 = __p2; - const difference_type __d = _Ops::distance(__p2, __last); - if (__m1 < __d) - __p2 += __m1; - else - __p2 = __first + (__m1 - __d); - } while (__p2 != __p); - *__p1 = std::move(__t); - } - return __first + __m2; +__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + using _Ops = _IterOps<_AlgPolicy>; + + const difference_type __m1 = __middle - __first; + const difference_type __m2 = _Ops::distance(__middle, __last); + if (__m1 == __m2) { + std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last); + return __middle; + } + const difference_type __g = std::__algo_gcd(__m1, __m2); + for (_RandomAccessIterator __p = __first + __g; __p != __first;) { + value_type __t(_Ops::__iter_move(--__p)); + _RandomAccessIterator __p1 = __p; + _RandomAccessIterator __p2 = __p1 + __m1; + do { + *__p1 = _Ops::__iter_move(__p2); + __p1 = __p2; + const difference_type __d = _Ops::distance(__p2, __last); + if (__m1 < __d) + __p2 += __m1; + else + __p2 = __first + (__m1 - __d); + } while (__p2 != __p); + *__p1 = std::move(__t); + } + return __first + __m2; } template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -__rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, - std::forward_iterator_tag) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - if (is_trivially_move_assignable::value) - { - if (_IterOps<_AlgPolicy>::next(__first) == __middle) - return std::__rotate_left<_AlgPolicy>(__first, __last); - } - return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +__rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, std::forward_iterator_tag) { + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + if (is_trivially_move_assignable::value) { + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + } + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); } template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator -__rotate_impl(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, - bidirectional_iterator_tag) -{ - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - if (is_trivially_move_assignable::value) - { - if (_IterOps<_AlgPolicy>::next(__first) == __middle) - return std::__rotate_left<_AlgPolicy>(__first, __last); - if (_IterOps<_AlgPolicy>::next(__middle) == __last) - return std::__rotate_right<_AlgPolicy>(__first, __last); - } - return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator __rotate_impl( + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + bidirectional_iterator_tag) { + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + if (is_trivially_move_assignable::value) { + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + if (_IterOps<_AlgPolicy>::next(__middle) == __last) + return std::__rotate_right<_AlgPolicy>(__first, __last); + } + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); } template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator -__rotate_impl(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, - random_access_iterator_tag) -{ - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - if (is_trivially_move_assignable::value) - { - if (_IterOps<_AlgPolicy>::next(__first) == __middle) - return std::__rotate_left<_AlgPolicy>(__first, __last); - if (_IterOps<_AlgPolicy>::next(__middle) == __last) - return std::__rotate_right<_AlgPolicy>(__first, __last); - return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last); - } - return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator __rotate_impl( + _RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + random_access_iterator_tag) { + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + if (is_trivially_move_assignable::value) { + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + if (_IterOps<_AlgPolicy>::next(__middle) == __last) + return std::__rotate_right<_AlgPolicy>(__first, __last); + return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last); + } + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iterator, _Iterator> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iterator, _Iterator> __rotate(_Iterator __first, _Iterator __middle, _Sentinel __last) { - using _Ret = pair<_Iterator, _Iterator>; + using _Ret = pair<_Iterator, _Iterator>; _Iterator __last_iter = _IterOps<_AlgPolicy>::next(__middle, __last); if (__first == __middle) - return _Ret(__last_iter, __last_iter); + return _Ret(__last_iter, __last_iter); if (__middle == __last) - return _Ret(std::move(__first), std::move(__last_iter)); + return _Ret(std::move(__first), std::move(__last_iter)); using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_Iterator>; - auto __result = std::__rotate_impl<_AlgPolicy>( - std::move(__first), std::move(__middle), __last_iter, _IterCategory()); + auto __result = std::__rotate_impl<_AlgPolicy>(std::move(__first), std::move(__middle), __last_iter, _IterCategory()); return _Ret(std::move(__result), std::move(__last_iter)); } template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) -{ - return std::__rotate<_ClassicAlgPolicy>( - std::move(__first), std::move(__middle), std::move(__last)).first; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { + return std::__rotate<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last)).first; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/rotate_copy.h b/libcxx/include/__algorithm/rotate_copy.h index 6e886cb73cfc5fe01737a4d950f9781d72052257..cddcadd237d902970497a7cf9fbf808875a095b3 100644 --- a/libcxx/include/__algorithm/rotate_copy.h +++ b/libcxx/include/__algorithm/rotate_copy.h @@ -19,11 +19,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) -{ - return std::copy(__first, __middle, std::copy(__middle, __last, __result)); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) { + return std::copy(__first, __middle, std::copy(__middle, __last, __result)); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/sample.h b/libcxx/include/__algorithm/sample.h index 100b0a466863d1856ac39dbb38c8d9a0b0de3e13..cc29dd686f6be8dcc1d147f5c300ecb9ee164630 100644 --- a/libcxx/include/__algorithm/sample.h +++ b/libcxx/include/__algorithm/sample.h @@ -29,20 +29,23 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI -_SampleIterator __sample(_PopulationIterator __first, - _PopulationSentinel __last, _SampleIterator __output_iter, - _Distance __n, - _UniformRandomNumberGenerator& __g, - input_iterator_tag) { - +_LIBCPP_HIDE_FROM_ABI _SampleIterator __sample( + _PopulationIterator __first, + _PopulationSentinel __last, + _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator& __g, + input_iterator_tag) { _Distance __k = 0; - for (; __first != __last && __k < __n; ++__first, (void) ++__k) + for (; __first != __last && __k < __n; ++__first, (void)++__k) __output_iter[__k] = *__first; _Distance __sz = __k; - for (; __first != __last; ++__first, (void) ++__k) { + for (; __first != __last; ++__first, (void)++__k) { _Distance __r = uniform_int_distribution<_Distance>(0, __k)(__g); if (__r < __sz) __output_iter[__r] = *__first; @@ -51,14 +54,18 @@ _SampleIterator __sample(_PopulationIterator __first, } template -_LIBCPP_HIDE_FROM_ABI -_SampleIterator __sample(_PopulationIterator __first, - _PopulationSentinel __last, _SampleIterator __output_iter, - _Distance __n, - _UniformRandomNumberGenerator& __g, - forward_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _SampleIterator __sample( + _PopulationIterator __first, + _PopulationSentinel __last, + _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator& __g, + forward_iterator_tag) { _Distance __unsampled_sz = _IterOps<_AlgPolicy>::distance(__first, __last); for (__n = std::min(__n, __unsampled_sz); __n != 0; ++__first) { _Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); @@ -71,36 +78,40 @@ _SampleIterator __sample(_PopulationIterator __first, } template -_LIBCPP_HIDE_FROM_ABI -_SampleIterator __sample(_PopulationIterator __first, - _PopulationSentinel __last, _SampleIterator __output_iter, - _Distance __n, _UniformRandomNumberGenerator& __g) { +_LIBCPP_HIDE_FROM_ABI _SampleIterator __sample( + _PopulationIterator __first, + _PopulationSentinel __last, + _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator& __g) { _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "N must be a positive number."); using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>; - using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>; - using _CommonType = typename common_type<_Distance, _Difference>::type; + using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>; + using _CommonType = typename common_type<_Distance, _Difference>::type; return std::__sample<_AlgPolicy>( - std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n), - __g, _PopIterCategory()); + std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n), __g, _PopIterCategory()); } #if _LIBCPP_STD_VER >= 17 -template -inline _LIBCPP_HIDE_FROM_ABI -_SampleIterator sample(_PopulationIterator __first, - _PopulationIterator __last, _SampleIterator __output_iter, - _Distance __n, _UniformRandomNumberGenerator&& __g) { +template +inline _LIBCPP_HIDE_FROM_ABI _SampleIterator +sample(_PopulationIterator __first, + _PopulationIterator __last, + _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator&& __g) { static_assert(__has_forward_iterator_category<_PopulationIterator>::value || - __has_random_access_iterator_category<_SampleIterator>::value, + __has_random_access_iterator_category<_SampleIterator>::value, "SampleIterator must meet the requirements of RandomAccessIterator"); - return std::__sample<_ClassicAlgPolicy>( - std::move(__first), std::move(__last), std::move(__output_iter), __n, __g); + return std::__sample<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__output_iter), __n, __g); } #endif // _LIBCPP_STD_VER >= 17 diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h index 544e127f7d4c1d7c99585c76b4afb396ef8d2b6a..75f936d0f217efa9f0bc01b0b7d3047eb21c0cef 100644 --- a/libcxx/include/__algorithm/search.h +++ b/libcxx/include/__algorithm/search.h @@ -29,17 +29,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred& __pred, - _Proj1& __proj1, - _Proj2& __proj2) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_forward_impl( + _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { if (__first2 == __last2) return std::make_pair(__first1, __first1); // Everything matches an empty sequence while (true) { @@ -64,8 +62,7 @@ pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1, } // if there is a mismatch, restart with a new __first1 - if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) - { + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) { ++__first1; break; } // else there is a match, check next elements @@ -74,21 +71,25 @@ pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1, } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred& __pred, - _Proj1& __proj1, - _Proj2& __proj2, - _DiffT1 __size1, - _DiffT2 __size2) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_random_access_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + _DiffT1 __size1, + _DiffT2 __size2) { const _Iter1 __s = __first1 + __size1 - _DiffT1(__size2 - 1); // Start of pattern match can't go beyond here while (true) { @@ -116,20 +117,17 @@ pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1 } } -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred& __pred, - _Proj1& __proj1, - _Proj2& __proj2, - __enable_if_t<__has_random_access_iterator_category<_Iter1>::value - && __has_random_access_iterator_category<_Iter2>::value>* = nullptr) { - +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + __enable_if_t<__has_random_access_iterator_category<_Iter1>::value && + __has_random_access_iterator_category<_Iter2>::value>* = nullptr) { auto __size2 = __last2 - __first2; if (__size2 == 0) return std::make_pair(__first1, __first1); @@ -139,42 +137,32 @@ pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, return std::make_pair(__last1, __last1); } - return std::__search_random_access_impl<_ClassicAlgPolicy>(__first1, __last1, - __first2, __last2, - __pred, - __proj1, - __proj2, - __size1, - __size2); + return std::__search_random_access_impl<_ClassicAlgPolicy>( + __first1, __last1, __first2, __last2, __pred, __proj1, __proj2, __size1, __size2); } -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred& __pred, - _Proj1& __proj1, - _Proj2& __proj2, - __enable_if_t<__has_forward_iterator_category<_Iter1>::value - && __has_forward_iterator_category<_Iter2>::value - && !(__has_random_access_iterator_category<_Iter1>::value - && __has_random_access_iterator_category<_Iter2>::value)>* = nullptr) { - return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, - __first2, __last2, - __pred, - __proj1, - __proj2); +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + __enable_if_t<__has_forward_iterator_category<_Iter1>::value && __has_forward_iterator_category<_Iter2>::value && + !(__has_random_access_iterator_category<_Iter1>::value && + __has_random_access_iterator_category<_Iter2>::value)>* = nullptr) { + return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +search(_ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred) { static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, "BinaryPredicate has to be callable"); auto __proj = __identity(); @@ -182,9 +170,8 @@ _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::search(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h index 7e3ddf48a2b6c00c7863777e900c3bac5d6e313f..c3c01e700bf6adb42f326a7a3ccec4f9b0ee3fea 100644 --- a/libcxx/include/__algorithm/search_n.h +++ b/libcxx/include/__algorithm/search_n.h @@ -31,12 +31,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last, - _SizeT __count, - const _Type& __value, - _Pred& __pred, - _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_n_forward_impl( + _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) { if (__count <= 0) return std::make_pair(__first, __first); while (true) { @@ -62,8 +58,7 @@ pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last, } // if there is a mismatch, restart with a new __first - if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) - { + if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) { __first = __m; ++__first; break; @@ -73,13 +68,8 @@ pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last, } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __last, - _SizeT __count, - const _Type& __value, - _Pred& __pred, - _Proj& __proj, - _DiffT __size1) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 std::pair<_Iter, _Iter> __search_n_random_access_impl( + _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj, _DiffT __size1) { using difference_type = typename iterator_traits<_Iter>::difference_type; if (__count == 0) return std::make_pair(__first, __first); @@ -109,8 +99,7 @@ std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __las ++__m; // no need to check range on __m because __s guarantees we have enough source // if there is a mismatch, restart with a new __first - if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) - { + if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) { __first = __m; ++__first; break; @@ -119,61 +108,44 @@ std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __las } } -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter, _Iter> __search_n_impl(_Iter __first, _Sent __last, - _DiffT __count, - const _Type& __value, - _Pred& __pred, - _Proj& __proj, - __enable_if_t<__has_random_access_iterator_category<_Iter>::value>* = nullptr) { - return std::__search_n_random_access_impl<_ClassicAlgPolicy>(__first, __last, - __count, - __value, - __pred, - __proj, - __last - __first); +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_n_impl( + _Iter __first, + _Sent __last, + _DiffT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj, + __enable_if_t<__has_random_access_iterator_category<_Iter>::value>* = nullptr) { + return std::__search_n_random_access_impl<_ClassicAlgPolicy>( + __first, __last, __count, __value, __pred, __proj, __last - __first); } -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter1, _Iter1> __search_n_impl(_Iter1 __first, _Sent1 __last, - _DiffT __count, - const _Type& __value, - _Pred& __pred, - _Proj& __proj, - __enable_if_t<__has_forward_iterator_category<_Iter1>::value - && !__has_random_access_iterator_category<_Iter1>::value>* = nullptr) { - return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last, - __count, - __value, - __pred, - __proj); +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_n_impl( + _Iter1 __first, + _Sent1 __last, + _DiffT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj, + __enable_if_t<__has_forward_iterator_category<_Iter1>::value && + !__has_random_access_iterator_category<_Iter1>::value>* = nullptr) { + return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last, __count, __value, __pred, __proj); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, - _Size __count, - const _Tp& __value, - _BinaryPredicate __pred) { - static_assert(__is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, - "BinaryPredicate has to be callable"); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search_n( + _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) { + static_assert( + __is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, "BinaryPredicate has to be callable"); auto __proj = __identity(); return std::__search_n_impl(__first, __last, std::__convert_to_integral(__count), __value, __pred, __proj).first; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to()); } diff --git a/libcxx/include/__algorithm/set_difference.h b/libcxx/include/__algorithm/set_difference.h index 26a300092c91f0d5ea6c2546c33997241c4bbe12..a924702ce5f26c62bada87834064c6bb885866aa 100644 --- a/libcxx/include/__algorithm/set_difference.h +++ b/libcxx/include/__algorithm/set_difference.h @@ -55,7 +55,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d _OutputIterator __result, _Compare __comp) { return std::__set_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( - __first1, __last1, __first2, __last2, __result, __comp) + __first1, __last1, __first2, __last2, __result, __comp) .second; } diff --git a/libcxx/include/__algorithm/shift_left.h b/libcxx/include/__algorithm/shift_left.h index c9f2cbb9f7b6fa35f7cc53b30dab62cd793700f9..645c58c2911924221f8c716739dbe691c8b3118a 100644 --- a/libcxx/include/__algorithm/shift_left.h +++ b/libcxx/include/__algorithm/shift_left.h @@ -22,30 +22,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -inline _LIBCPP_HIDE_FROM_ABI constexpr -_ForwardIterator -shift_left(_ForwardIterator __first, _ForwardIterator __last, - typename iterator_traits<_ForwardIterator>::difference_type __n) -{ - if (__n == 0) { - return __last; +inline _LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator +shift_left(_ForwardIterator __first, + _ForwardIterator __last, + typename iterator_traits<_ForwardIterator>::difference_type __n) { + if (__n == 0) { + return __last; + } + + _ForwardIterator __m = __first; + if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { + if (__n >= __last - __first) { + return __first; } - - _ForwardIterator __m = __first; - if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { - if (__n >= __last - __first) { - return __first; - } - __m += __n; - } else { - for (; __n > 0; --__n) { - if (__m == __last) { - return __first; - } - ++__m; - } + __m += __n; + } else { + for (; __n > 0; --__n) { + if (__m == __last) { + return __first; + } + ++__m; } - return std::move(__m, __last, __first); + } + return std::move(__m, __last, __first); } #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__algorithm/shift_right.h b/libcxx/include/__algorithm/shift_right.h index 70983e327bcb96750319c830e8ac7a24196ad6d6..73ef98bd39deda3003b59528c522a22760959b40 100644 --- a/libcxx/include/__algorithm/shift_right.h +++ b/libcxx/include/__algorithm/shift_right.h @@ -25,73 +25,72 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -inline _LIBCPP_HIDE_FROM_ABI constexpr -_ForwardIterator -shift_right(_ForwardIterator __first, _ForwardIterator __last, - typename iterator_traits<_ForwardIterator>::difference_type __n) -{ - if (__n == 0) { - return __first; - } +inline _LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator +shift_right(_ForwardIterator __first, + _ForwardIterator __last, + typename iterator_traits<_ForwardIterator>::difference_type __n) { + if (__n == 0) { + return __first; + } - if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { - decltype(__n) __d = __last - __first; - if (__n >= __d) { - return __last; - } - _ForwardIterator __m = __first + (__d - __n); - return std::move_backward(__first, __m, __last); - } else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) { - _ForwardIterator __m = __last; - for (; __n > 0; --__n) { - if (__m == __first) { - return __last; - } - --__m; - } - return std::move_backward(__first, __m, __last); - } else { - _ForwardIterator __ret = __first; - for (; __n > 0; --__n) { - if (__ret == __last) { - return __last; - } - ++__ret; - } + if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { + decltype(__n) __d = __last - __first; + if (__n >= __d) { + return __last; + } + _ForwardIterator __m = __first + (__d - __n); + return std::move_backward(__first, __m, __last); + } else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) { + _ForwardIterator __m = __last; + for (; __n > 0; --__n) { + if (__m == __first) { + return __last; + } + --__m; + } + return std::move_backward(__first, __m, __last); + } else { + _ForwardIterator __ret = __first; + for (; __n > 0; --__n) { + if (__ret == __last) { + return __last; + } + ++__ret; + } - // We have an __n-element scratch space from __first to __ret. - // Slide an __n-element window [__trail, __lead) from left to right. - // We're essentially doing swap_ranges(__first, __ret, __trail, __lead) - // over and over; but once __lead reaches __last we needn't bother - // to save the values of elements [__trail, __last). + // We have an __n-element scratch space from __first to __ret. + // Slide an __n-element window [__trail, __lead) from left to right. + // We're essentially doing swap_ranges(__first, __ret, __trail, __lead) + // over and over; but once __lead reaches __last we needn't bother + // to save the values of elements [__trail, __last). - auto __trail = __first; - auto __lead = __ret; - while (__trail != __ret) { - if (__lead == __last) { - std::move(__first, __trail, __ret); - return __ret; - } - ++__trail; - ++__lead; - } + auto __trail = __first; + auto __lead = __ret; + while (__trail != __ret) { + if (__lead == __last) { + std::move(__first, __trail, __ret); + return __ret; + } + ++__trail; + ++__lead; + } - _ForwardIterator __mid = __first; - while (true) { - if (__lead == __last) { - __trail = std::move(__mid, __ret, __trail); - std::move(__first, __mid, __trail); - return __ret; - } - swap(*__mid, *__trail); - ++__mid; - ++__trail; - ++__lead; - if (__mid == __ret) { - __mid = __first; - } - } + _ForwardIterator __mid = __first; + while (true) { + if (__lead == __last) { + __trail = std::move(__mid, __ret, __trail); + std::move(__first, __mid, __trail); + return __ret; + } + swap(*__mid, *__trail); + ++__mid; + ++__trail; + ++__lead; + if (__mid == __ret) { + __mid = __first; + } } + } } #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__algorithm/shuffle.h b/libcxx/include/__algorithm/shuffle.h index 6fee88ca6ff25d1530ffa8ac5945f2fca7d734de..c9c56ce8c2c0b1e81b047ff56ce8718cf9173992 100644 --- a/libcxx/include/__algorithm/shuffle.h +++ b/libcxx/include/__algorithm/shuffle.h @@ -32,8 +32,8 @@ class _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_randomizer { public: _LIBCPP_HIDE_FROM_ABI __libcpp_debug_randomizer() { __state_ = __seed(); - __inc_ = __state_ + 0xda3e39cb94b95bdbULL; - __inc_ = (__inc_ << 1) | 1; + __inc_ = __state_ + 0xda3e39cb94b95bdbULL; + __inc_ = (__inc_ << 1) | 1; } typedef uint_fast32_t result_type; @@ -42,7 +42,7 @@ public: _LIBCPP_HIDE_FROM_ABI result_type operator()() { uint_fast64_t __oldstate = __state_; - __state_ = __oldstate * 6364136223846793005ULL + __inc_; + __state_ = __oldstate * 6364136223846793005ULL + __inc_; return __oldstate >> 32; } @@ -62,102 +62,95 @@ private: } }; -#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \ - || defined(_LIBCPP_BUILDING_LIBRARY) +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) || defined(_LIBCPP_BUILDING_LIBRARY) class _LIBCPP_EXPORTED_FROM_ABI __rs_default; _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); -class _LIBCPP_EXPORTED_FROM_ABI __rs_default -{ - static unsigned __c_; +class _LIBCPP_EXPORTED_FROM_ABI __rs_default { + static unsigned __c_; + + __rs_default(); - __rs_default(); public: - typedef uint_fast32_t result_type; + typedef uint_fast32_t result_type; - static const result_type _Min = 0; - static const result_type _Max = 0xFFFFFFFF; + static const result_type _Min = 0; + static const result_type _Max = 0xFFFFFFFF; - __rs_default(const __rs_default&); - ~__rs_default(); + __rs_default(const __rs_default&); + ~__rs_default(); - result_type operator()(); + result_type operator()(); - static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() {return _Min;} - static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() {return _Max;} + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() { return _Min; } + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() { return _Max; } - friend _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); + friend _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); }; _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); template _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void -random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - typedef uniform_int_distribution _Dp; - typedef typename _Dp::param_type _Pp; - difference_type __d = __last - __first; - if (__d > 1) - { - _Dp __uid; - __rs_default __g = __rs_get(); - for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) - { - difference_type __i = __uid(__g, _Pp(0, __d)); - if (__i != difference_type(0)) - swap(*__first, *(__first + __i)); - } +random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef uniform_int_distribution _Dp; + typedef typename _Dp::param_type _Pp; + difference_type __d = __last - __first; + if (__d > 1) { + _Dp __uid; + __rs_default __g = __rs_get(); + for (--__last, (void)--__d; __first < __last; ++__first, (void)--__d) { + difference_type __i = __uid(__g, _Pp(0, __d)); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); } + } } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void -random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, -#ifndef _LIBCPP_CXX03_LANG +random_shuffle(_RandomAccessIterator __first, + _RandomAccessIterator __last, +# ifndef _LIBCPP_CXX03_LANG _RandomNumberGenerator&& __rand) -#else +# else _RandomNumberGenerator& __rand) -#endif +# endif { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - difference_type __d = __last - __first; - if (__d > 1) - { - for (--__last; __first < __last; ++__first, (void) --__d) - { - difference_type __i = __rand(__d); - if (__i != difference_type(0)) - swap(*__first, *(__first + __i)); - } + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __d = __last - __first; + if (__d > 1) { + for (--__last; __first < __last; ++__first, (void)--__d) { + difference_type __i = __rand(__d); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); } + } } #endif template -_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator __shuffle( - _RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - typedef uniform_int_distribution _Dp; - typedef typename _Dp::param_type _Pp; - - auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel); - auto __last = __original_last; - difference_type __d = __last - __first; - if (__d > 1) - { - _Dp __uid; - for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) - { - difference_type __i = __uid(__g, _Pp(0, __d)); - if (__i != difference_type(0)) - _IterOps<_AlgPolicy>::iter_swap(__first, __first + __i); - } +_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator +__shuffle(_RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef uniform_int_distribution _Dp; + typedef typename _Dp::param_type _Pp; + + auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel); + auto __last = __original_last; + difference_type __d = __last - __first; + if (__d > 1) { + _Dp __uid; + for (--__last, (void)--__d; __first < __last; ++__first, (void)--__d) { + difference_type __i = __uid(__g, _Pp(0, __d)); + if (__i != difference_type(0)) + _IterOps<_AlgPolicy>::iter_swap(__first, __first + __i); } + } - return __original_last; + return __original_last; } template diff --git a/libcxx/include/__algorithm/sift_down.h b/libcxx/include/__algorithm/sift_down.h index 3a222f7c7f1b64cc1b525a349371844a00a2e7b1..7f152e4dbd7f343571e61421baa82c6befb4216c 100644 --- a/libcxx/include/__algorithm/sift_down.h +++ b/libcxx/include/__algorithm/sift_down.h @@ -26,90 +26,89 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void -__sift_down(_RandomAccessIterator __first, _Compare&& __comp, +__sift_down(_RandomAccessIterator __first, + _Compare&& __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len, - _RandomAccessIterator __start) -{ - using _Ops = _IterOps<_AlgPolicy>; + _RandomAccessIterator __start) { + using _Ops = _IterOps<_AlgPolicy>; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - // left-child of __start is at 2 * __start + 1 - // right-child of __start is at 2 * __start + 2 - difference_type __child = __start - __first; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + // left-child of __start is at 2 * __start + 1 + // right-child of __start is at 2 * __start + 2 + difference_type __child = __start - __first; - if (__len < 2 || (__len - 2) / 2 < __child) - return; + if (__len < 2 || (__len - 2) / 2 < __child) + return; - __child = 2 * __child + 1; - _RandomAccessIterator __child_i = __first + __child; + __child = 2 * __child + 1; + _RandomAccessIterator __child_i = __first + __child; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; + } + + // check if we are in heap-order + if (__comp(*__child_i, *__start)) + // we are, __start is larger than its largest child + return; + + value_type __top(_Ops::__iter_move(__start)); + do { + // we are not in heap-order, swap the parent with its largest child + *__start = _Ops::__iter_move(__child_i); + __start = __child_i; + + if ((__len - 2) / 2 < __child) + break; + + // recompute the child based off of the updated parent + __child = 2 * __child + 1; + __child_i = __first + __child; if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { - // right-child exists and is greater than left-child - ++__child_i; - ++__child; + // right-child exists and is greater than left-child + ++__child_i; + ++__child; } // check if we are in heap-order - if (__comp(*__child_i, *__start)) - // we are, __start is larger than its largest child - return; - - value_type __top(_Ops::__iter_move(__start)); - do - { - // we are not in heap-order, swap the parent with its largest child - *__start = _Ops::__iter_move(__child_i); - __start = __child_i; - - if ((__len - 2) / 2 < __child) - break; - - // recompute the child based off of the updated parent - __child = 2 * __child + 1; - __child_i = __first + __child; - - if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { - // right-child exists and is greater than left-child - ++__child_i; - ++__child; - } - - // check if we are in heap-order - } while (!__comp(*__child_i, __top)); - *__start = std::move(__top); + } while (!__comp(*__child_i, __top)); + *__start = std::move(__top); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator -__floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len) -{ - using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; - _LIBCPP_ASSERT_UNCATEGORIZED(__len >= 2, "shouldn't be called unless __len >= 2"); - - _RandomAccessIterator __hole = __first; - _RandomAccessIterator __child_i = __first; - difference_type __child = 0; - - while (true) { - __child_i += difference_type(__child + 1); - __child = 2 * __child + 1; - - if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { - // right-child exists and is greater than left-child - ++__child_i; - ++__child; - } - - // swap __hole with its largest child - *__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i); - __hole = __child_i; - - // if __hole is now a leaf, we're done - if (__child > (__len - 2) / 2) - return __hole; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator __floyd_sift_down( + _RandomAccessIterator __first, + _Compare&& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) { + using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; + _LIBCPP_ASSERT_UNCATEGORIZED(__len >= 2, "shouldn't be called unless __len >= 2"); + + _RandomAccessIterator __hole = __first; + _RandomAccessIterator __child_i = __first; + difference_type __child = 0; + + while (true) { + __child_i += difference_type(__child + 1); + __child = 2 * __child + 1; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; } + + // swap __hole with its largest child + *__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i); + __hole = __child_i; + + // if __hole is now a leaf, we're done + if (__child > (__len - 2) / 2) + return __hole; + } } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h index 567c988ff0d3ced462f0a327441cde0d93e6898c..1b878c33c7a16f12a5dce9c8c89eb2350975e02a 100644 --- a/libcxx/include/__algorithm/sort.h +++ b/libcxx/include/__algorithm/sort.h @@ -44,49 +44,47 @@ _LIBCPP_BEGIN_NAMESPACE_STD // stable, 2-3 compares, 0-2 swaps template -_LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned __sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, - _Compare __c) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned +__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c) { using _Ops = _IterOps<_AlgPolicy>; unsigned __r = 0; - if (!__c(*__y, *__x)) // if x <= y + if (!__c(*__y, *__x)) // if x <= y { - if (!__c(*__z, *__y)) // if y <= z - return __r; // x <= y && y <= z - // x <= y && y > z - _Ops::iter_swap(__y, __z); // x <= z && y < z + if (!__c(*__z, *__y)) // if y <= z + return __r; // x <= y && y <= z + // x <= y && y > z + _Ops::iter_swap(__y, __z); // x <= z && y < z __r = 1; - if (__c(*__y, *__x)) // if x > y + if (__c(*__y, *__x)) // if x > y { - _Ops::iter_swap(__x, __y); // x < y && y <= z + _Ops::iter_swap(__x, __y); // x < y && y <= z __r = 2; } - return __r; // x <= y && y < z + return __r; // x <= y && y < z } - if (__c(*__z, *__y)) // x > y, if y > z + if (__c(*__z, *__y)) // x > y, if y > z { - _Ops::iter_swap(__x, __z); // x < y && y < z + _Ops::iter_swap(__x, __z); // x < y && y < z __r = 1; return __r; } - _Ops::iter_swap(__x, __y); // x > y && y <= z - __r = 1; // x < y && x <= z - if (__c(*__z, *__y)) // if y > z + _Ops::iter_swap(__x, __y); // x > y && y <= z + __r = 1; // x < y && x <= z + if (__c(*__z, *__y)) // if y > z { - _Ops::iter_swap(__y, __z); // x <= y && y < z + _Ops::iter_swap(__y, __z); // x <= y && y < z __r = 2; } return __r; -} // x <= y && y <= z +} // x <= y && y <= z // stable, 3-6 compares, 0-5 swaps template -_LIBCPP_HIDE_FROM_ABI -void __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, - _Compare __c) { - using _Ops = _IterOps<_AlgPolicy>; +_LIBCPP_HIDE_FROM_ABI void +__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, _Compare __c) { + using _Ops = _IterOps<_AlgPolicy>; std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); if (__c(*__x4, *__x3)) { _Ops::iter_swap(__x3, __x4); @@ -102,8 +100,13 @@ void __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3 // stable, 4-10 compares, 0-9 swaps template -_LIBCPP_HIDE_FROM_ABI void __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, - _ForwardIterator __x4, _ForwardIterator __x5, _Comp __comp) { +_LIBCPP_HIDE_FROM_ABI void +__sort5(_ForwardIterator __x1, + _ForwardIterator __x2, + _ForwardIterator __x3, + _ForwardIterator __x4, + _ForwardIterator __x5, + _Comp __comp) { using _Ops = _IterOps<_AlgPolicy>; std::__sort4<_AlgPolicy, _Comp>(__x1, __x2, __x3, __x4, __comp); @@ -139,8 +142,9 @@ struct __is_simple_comparator : true_type {}; template ::value_type> using __use_branchless_sort = - integral_constant::value && sizeof(_Tp) <= sizeof(void*) && - is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>; + integral_constant::value && sizeof(_Tp) <= sizeof(void*) && + is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>; namespace __detail { @@ -154,49 +158,56 @@ template inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) { // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`). using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; - bool __r = __c(*__x, *__y); + bool __r = __c(*__x, *__y); value_type __tmp = __r ? *__x : *__y; - *__y = __r ? *__y : *__x; - *__x = __tmp; + *__y = __r ? *__y : *__x; + *__x = __tmp; } // Ensures that *__x, *__y and *__z are ordered according to the comparator __c, // under the assumption that *__y and *__z are already ordered. template -inline _LIBCPP_HIDE_FROM_ABI void __partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, - _RandomAccessIterator __z, _Compare __c) { +inline _LIBCPP_HIDE_FROM_ABI void +__partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _RandomAccessIterator __z, _Compare __c) { // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`). using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; - bool __r = __c(*__z, *__x); + bool __r = __c(*__z, *__x); value_type __tmp = __r ? *__z : *__x; - *__z = __r ? *__x : *__z; - __r = __c(__tmp, *__y); - *__x = __r ? *__x : *__y; - *__y = __r ? *__y : __tmp; + *__z = __r ? *__x : *__z; + __r = __c(__tmp, *__y); + *__x = __r ? *__x : *__y; + *__y = __r ? *__y : __tmp; } -template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI void -__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, - _Compare __c) { +inline _LIBCPP_HIDE_FROM_ABI void __sort3_maybe_branchless( + _RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _Compare __c) { std::__cond_swap<_Compare>(__x2, __x3, __c); std::__partially_sorted_swap<_Compare>(__x1, __x2, __x3, __c); } -template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI void -__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, - _Compare __c) { +inline _LIBCPP_HIDE_FROM_ABI void __sort3_maybe_branchless( + _RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _Compare __c) { std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); } -template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI void -__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, - _RandomAccessIterator __x4, _Compare __c) { +inline _LIBCPP_HIDE_FROM_ABI void __sort4_maybe_branchless( + _RandomAccessIterator __x1, + _RandomAccessIterator __x2, + _RandomAccessIterator __x3, + _RandomAccessIterator __x4, + _Compare __c) { std::__cond_swap<_Compare>(__x1, __x3, __c); std::__cond_swap<_Compare>(__x2, __x4, __c); std::__cond_swap<_Compare>(__x1, __x2, __c); @@ -204,18 +215,24 @@ __sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, std::__cond_swap<_Compare>(__x2, __x3, __c); } -template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI void -__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, - _RandomAccessIterator __x4, _Compare __c) { +inline _LIBCPP_HIDE_FROM_ABI void __sort4_maybe_branchless( + _RandomAccessIterator __x1, + _RandomAccessIterator __x2, + _RandomAccessIterator __x3, + _RandomAccessIterator __x4, + _Compare __c) { std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c); } -template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI void -__sort5_maybe_branchless( +inline _LIBCPP_HIDE_FROM_ABI void __sort5_maybe_branchless( _RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, @@ -230,20 +247,25 @@ __sort5_maybe_branchless( std::__partially_sorted_swap<_Compare>(__x2, __x3, __x4, __c); } -template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI void -__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, - _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) { +inline _LIBCPP_HIDE_FROM_ABI void __sort5_maybe_branchless( + _RandomAccessIterator __x1, + _RandomAccessIterator __x2, + _RandomAccessIterator __x3, + _RandomAccessIterator __x4, + _RandomAccessIterator __x5, + _Compare __c) { std::__sort5<_AlgPolicy, _Compare, _RandomAccessIterator>( std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __c); } // Assumes size > 0 template -_LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, - _Compare __comp) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { _BidirectionalIterator __lm1 = __last; for (--__lm1; __first != __lm1; ++__first) { _BidirectionalIterator __i = std::__min_element<_Compare>(__first, __last, __comp); @@ -255,8 +277,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __fir // Sort the iterator range [__first, __last) using the comparator __comp using // the insertion sort algorithm. template -_LIBCPP_HIDE_FROM_ABI -void __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { +_LIBCPP_HIDE_FROM_ABI void +__insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { using _Ops = _IterOps<_AlgPolicy>; typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; @@ -292,16 +314,17 @@ __insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIte typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; if (__first == __last) return; - const _RandomAccessIterator __leftmost = __first - difference_type(1); (void)__leftmost; // can be unused when assertions are disabled + const _RandomAccessIterator __leftmost = __first - difference_type(1); + (void)__leftmost; // can be unused when assertions are disabled for (_RandomAccessIterator __i = __first + difference_type(1); __i != __last; ++__i) { _RandomAccessIterator __j = __i - difference_type(1); if (__comp(*__i, *__j)) { value_type __t(_Ops::__iter_move(__i)); _RandomAccessIterator __k = __j; - __j = __i; + __j = __i; do { *__j = _Ops::__iter_move(__k); - __j = __k; + __j = __k; _LIBCPP_ASSERT_UNCATEGORIZED( __k != __leftmost, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); @@ -312,8 +335,8 @@ __insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIte } template -_LIBCPP_HIDE_FROM_ABI bool __insertion_sort_incomplete( - _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { +_LIBCPP_HIDE_FROM_ABI bool +__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { using _Ops = _IterOps<_AlgPolicy>; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; @@ -334,23 +357,27 @@ _LIBCPP_HIDE_FROM_ABI bool __insertion_sort_incomplete( return true; case 5: std::__sort5_maybe_branchless<_AlgPolicy, _Comp>( - __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), - --__last, __comp); + __first, + __first + difference_type(1), + __first + difference_type(2), + __first + difference_type(3), + --__last, + __comp); return true; } typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; _RandomAccessIterator __j = __first + difference_type(2); std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), __j, __comp); const unsigned __limit = 8; - unsigned __count = 0; + unsigned __count = 0; for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { if (__comp(*__i, *__j)) { value_type __t(_Ops::__iter_move(__i)); _RandomAccessIterator __k = __j; - __j = __i; + __j = __i; do { *__j = _Ops::__iter_move(__k); - __j = __k; + __j = __k; } while (__j != __first && __comp(__t, *--__k)); *__j = std::move(__t); if (++__count == __limit) @@ -507,8 +534,9 @@ __bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), ""); - const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around - const _RandomAccessIterator __end = __last; (void)__end; // + const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around + const _RandomAccessIterator __end = __last; + (void)__end; // value_type __pivot(_Ops::__iter_move(__first)); // Find the first element greater than the pivot. @@ -598,8 +626,9 @@ __partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIte typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), ""); - const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around - const _RandomAccessIterator __end = __last; (void)__end; // + const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around + const _RandomAccessIterator __end = __last; + (void)__end; // value_type __pivot(_Ops::__iter_move(__first)); // Find the first element greater or equal to the pivot. It will be always // guarded because __introsort will do the median-of-three before calling @@ -665,8 +694,9 @@ __partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIter typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; // TODO(LLVM18): Make __begin const, see https://reviews.llvm.org/D147089#4349748 - _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around - const _RandomAccessIterator __end = __last; (void)__end; // + _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around + const _RandomAccessIterator __end = __last; + (void)__end; // value_type __pivot(_Ops::__iter_move(__first)); if (__comp(__pivot, *(__last - difference_type(1)))) { // Guarded. @@ -753,8 +783,12 @@ void __introsort(_RandomAccessIterator __first, return; case 5: std::__sort5_maybe_branchless<_AlgPolicy, _Compare>( - __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), - --__last, __comp); + __first, + __first + difference_type(1), + __first + difference_type(2), + __first + difference_type(3), + --__last, + __comp); return; } // Use insertion sort if the length of the range is below the specified limit. @@ -803,10 +837,10 @@ void __introsort(_RandomAccessIterator __first, continue; } // Use bitset partition only if asked for. - auto __ret = - _UseBitSetPartition - ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp) - : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp); + auto __ret = _UseBitSetPartition + ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp) + : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>( + __first, __last, __comp); _RandomAccessIterator __i = __ret.first; // [__first, __i) < *__i and *__i <= [__i+1, __last) // If we were given a perfect partition, see if insertion sort is quick... @@ -858,19 +892,27 @@ extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, char*>(char #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&); #endif -extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, signed char*>(signed char*, signed char*, __less&); -extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, signed char*>(signed char*, signed char*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, short*>(short*, short*, __less&); -extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, int*>(int*, int*, __less&); -extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, unsigned*>(unsigned*, unsigned*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, unsigned*>(unsigned*, unsigned*, __less&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, long*>(long*, long*, __less&); -extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&); -extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, long long*>(long long*, long long*, __less&); -extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, long long*>(long long*, long long*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, unsigned long long*>( + unsigned long long*, unsigned long long*, __less&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, float*>(float*, float*, __less&); extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, double*>(double*, double*, __less&); -extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, long double*>(long double*, long double*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, long double*>(long double*, long double*, __less&); template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void @@ -884,8 +926,7 @@ __sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co std::__introsort<_AlgPolicy, _Comp&, _RandomAccessIterator, - __use_branchless_sort<_Comp, _RandomAccessIterator>::value>( - __first, __last, __comp, __depth_limit); + __use_branchless_sort<_Comp, _RandomAccessIterator>::value>(__first, __last, __comp, __depth_limit); } template @@ -941,8 +982,8 @@ _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, ranges #endif template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { std::__debug_randomize_range<_AlgPolicy>(__first, __last); if (__libcpp_is_constant_evaluated()) { @@ -955,14 +996,14 @@ void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _C } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { std::__sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { std::sort(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/sort_heap.h b/libcxx/include/__algorithm/sort_heap.h index a82926ed1ccac485720ef093fc858935b08f0196..0a6d992d0090e34119b355920c533a13ed027d8d 100644 --- a/libcxx/include/__algorithm/sort_heap.h +++ b/libcxx/include/__algorithm/sort_heap.h @@ -27,20 +27,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { - _RandomAccessIterator __saved_last = __last; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { + _RandomAccessIterator __saved_last = __last; __comp_ref_type<_Compare> __comp_ref = __comp; using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; - for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) + for (difference_type __n = __last - __first; __n > 1; --__last, (void)--__n) std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n); std::__check_strict_weak_ordering_sorted(__first, __saved_last, __comp_ref); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); @@ -48,8 +48,8 @@ void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { std::sort_heap(std::move(__first), std::move(__last), __less<>()); } diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h index 0e92a0a5f73d9ef931121d51521542623337c62d..8762abcf18e150de5a12d163f641ce45823e9d06 100644 --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -29,296 +29,269 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _ForwardIterator -__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - _Distance __len, _Pair __p, forward_iterator_tag __fit) -{ - using _Ops = _IterOps<_AlgPolicy>; +_LIBCPP_HIDE_FROM_ABI _ForwardIterator __stable_partition_impl( + _ForwardIterator __first, + _ForwardIterator __last, + _Predicate __pred, + _Distance __len, + _Pair __p, + forward_iterator_tag __fit) { + using _Ops = _IterOps<_AlgPolicy>; - // *__first is known to be false - // __len >= 1 - if (__len == 1) - return __first; - if (__len == 2) - { - _ForwardIterator __m = __first; - if (__pred(*++__m)) - { - _Ops::iter_swap(__first, __m); - return __m; - } - return __first; + // *__first is known to be false + // __len >= 1 + if (__len == 1) + return __first; + if (__len == 2) { + _ForwardIterator __m = __first; + if (__pred(*++__m)) { + _Ops::iter_swap(__first, __m); + return __m; } - if (__len <= __p.second) - { // The buffer is big enough to use - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - __destruct_n __d(0); - unique_ptr __h(__p.first, __d); - // Move the falses into the temporary buffer, and the trues to the front of the line - // Update __first to always point to the end of the trues - value_type* __t = __p.first; - ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); + return __first; + } + if (__len <= __p.second) { // The buffer is big enough to use + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__p.first, __d); + // Move the falses into the temporary buffer, and the trues to the front of the line + // Update __first to always point to the end of the trues + value_type* __t = __p.first; + ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); + __d.template __incr(); + ++__t; + _ForwardIterator __i = __first; + while (++__i != __last) { + if (__pred(*__i)) { + *__first = _Ops::__iter_move(__i); + ++__first; + } else { + ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); __d.template __incr(); ++__t; - _ForwardIterator __i = __first; - while (++__i != __last) - { - if (__pred(*__i)) - { - *__first = _Ops::__iter_move(__i); - ++__first; - } - else - { - ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); - __d.template __incr(); - ++__t; - } - } - // All trues now at start of range, all falses in buffer - // Move falses back into range, but don't mess up __first which points to first false - __i = __first; - for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) - *__i = _Ops::__iter_move(__t2); - // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer - return __first; - } - // Else not enough buffer, do in place - // __len >= 3 - _ForwardIterator __m = __first; - _Distance __len2 = __len / 2; // __len2 >= 2 - _Ops::advance(__m, __len2); - // recurse on [__first, __m), *__first know to be false - // F????????????????? - // f m l - _ForwardIterator __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - __first, __m, __pred, __len2, __p, __fit); - // TTTFFFFF?????????? - // f ff m l - // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true - _ForwardIterator __m1 = __m; - _ForwardIterator __second_false = __last; - _Distance __len_half = __len - __len2; - while (__pred(*__m1)) - { - if (++__m1 == __last) - goto __second_half_done; - --__len_half; + } } - // TTTFFFFFTTTF?????? - // f ff m m1 l - __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - __m1, __last, __pred, __len_half, __p, __fit); + // All trues now at start of range, all falses in buffer + // Move falses back into range, but don't mess up __first which points to first false + __i = __first; + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void)++__i) + *__i = _Ops::__iter_move(__t2); + // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer + return __first; + } + // Else not enough buffer, do in place + // __len >= 3 + _ForwardIterator __m = __first; + _Distance __len2 = __len / 2; // __len2 >= 2 + _Ops::advance(__m, __len2); + // recurse on [__first, __m), *__first know to be false + // F????????????????? + // f m l + _ForwardIterator __first_false = + std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__first, __m, __pred, __len2, __p, __fit); + // TTTFFFFF?????????? + // f ff m l + // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true + _ForwardIterator __m1 = __m; + _ForwardIterator __second_false = __last; + _Distance __len_half = __len - __len2; + while (__pred(*__m1)) { + if (++__m1 == __last) + goto __second_half_done; + --__len_half; + } + // TTTFFFFFTTTF?????? + // f ff m m1 l + __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__m1, __last, __pred, __len_half, __p, __fit); __second_half_done: - // TTTFFFFFTTTTTFFFFF - // f ff m sf l - return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; - // TTTTTTTTFFFFFFFFFF - // | + // TTTFFFFFTTTTTFFFFF + // f ff m sf l + return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; + // TTTTTTTTFFFFFFFFFF + // | } template _LIBCPP_HIDE_FROM_ABI _ForwardIterator -__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - forward_iterator_tag) -{ - typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; +__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) { + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - const difference_type __alloc_limit = 3; // might want to make this a function of trivial assignment - // Either prove all true and return __first or point to first false - while (true) - { - if (__first == __last) - return __first; - if (!__pred(*__first)) - break; - ++__first; - } - // We now have a reduced range [__first, __last) - // *__first is known to be false - difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); - pair __p(0, 0); - unique_ptr __h; - if (__len >= __alloc_limit) - { -// TODO: Remove the use of std::get_temporary_buffer -_LIBCPP_SUPPRESS_DEPRECATED_PUSH - __p = std::get_temporary_buffer(__len); -_LIBCPP_SUPPRESS_DEPRECATED_POP - __h.reset(__p.first); - } - return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag()); + const difference_type __alloc_limit = 3; // might want to make this a function of trivial assignment + // Either prove all true and return __first or point to first false + while (true) { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + // We now have a reduced range [__first, __last) + // *__first is known to be false + difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); + pair __p(0, 0); + unique_ptr __h; + if (__len >= __alloc_limit) { + // TODO: Remove the use of std::get_temporary_buffer + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + __p = std::get_temporary_buffer(__len); + _LIBCPP_SUPPRESS_DEPRECATED_POP + __h.reset(__p.first); + } + return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag()); } template -_BidirectionalIterator -__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, - _Distance __len, _Pair __p, bidirectional_iterator_tag __bit) -{ - using _Ops = _IterOps<_AlgPolicy>; +_BidirectionalIterator __stable_partition_impl( + _BidirectionalIterator __first, + _BidirectionalIterator __last, + _Predicate __pred, + _Distance __len, + _Pair __p, + bidirectional_iterator_tag __bit) { + using _Ops = _IterOps<_AlgPolicy>; - // *__first is known to be false - // *__last is known to be true - // __len >= 2 - if (__len == 2) - { - _Ops::iter_swap(__first, __last); - return __last; - } - if (__len == 3) - { - _BidirectionalIterator __m = __first; - if (__pred(*++__m)) - { - _Ops::iter_swap(__first, __m); - _Ops::iter_swap(__m, __last); - return __last; - } - _Ops::iter_swap(__m, __last); - _Ops::iter_swap(__first, __m); - return __m; + // *__first is known to be false + // *__last is known to be true + // __len >= 2 + if (__len == 2) { + _Ops::iter_swap(__first, __last); + return __last; + } + if (__len == 3) { + _BidirectionalIterator __m = __first; + if (__pred(*++__m)) { + _Ops::iter_swap(__first, __m); + _Ops::iter_swap(__m, __last); + return __last; } - if (__len <= __p.second) - { // The buffer is big enough to use - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - __destruct_n __d(0); - unique_ptr __h(__p.first, __d); - // Move the falses into the temporary buffer, and the trues to the front of the line - // Update __first to always point to the end of the trues - value_type* __t = __p.first; - ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); + _Ops::iter_swap(__m, __last); + _Ops::iter_swap(__first, __m); + return __m; + } + if (__len <= __p.second) { // The buffer is big enough to use + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__p.first, __d); + // Move the falses into the temporary buffer, and the trues to the front of the line + // Update __first to always point to the end of the trues + value_type* __t = __p.first; + ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); + __d.template __incr(); + ++__t; + _BidirectionalIterator __i = __first; + while (++__i != __last) { + if (__pred(*__i)) { + *__first = _Ops::__iter_move(__i); + ++__first; + } else { + ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); __d.template __incr(); ++__t; - _BidirectionalIterator __i = __first; - while (++__i != __last) - { - if (__pred(*__i)) - { - *__first = _Ops::__iter_move(__i); - ++__first; - } - else - { - ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); - __d.template __incr(); - ++__t; - } - } - // move *__last, known to be true - *__first = _Ops::__iter_move(__i); - __i = ++__first; - // All trues now at start of range, all falses in buffer - // Move falses back into range, but don't mess up __first which points to first false - for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) - *__i = _Ops::__iter_move(__t2); - // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer - return __first; - } - // Else not enough buffer, do in place - // __len >= 4 - _BidirectionalIterator __m = __first; - _Distance __len2 = __len / 2; // __len2 >= 2 - _Ops::advance(__m, __len2); - // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false - // F????????????????T - // f m l - _BidirectionalIterator __m1 = __m; - _BidirectionalIterator __first_false = __first; - _Distance __len_half = __len2; - while (!__pred(*--__m1)) - { - if (__m1 == __first) - goto __first_half_done; - --__len_half; + } } - // F???TFFF?????????T - // f m1 m l - __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - __first, __m1, __pred, __len_half, __p, __bit); + // move *__last, known to be true + *__first = _Ops::__iter_move(__i); + __i = ++__first; + // All trues now at start of range, all falses in buffer + // Move falses back into range, but don't mess up __first which points to first false + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void)++__i) + *__i = _Ops::__iter_move(__t2); + // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer + return __first; + } + // Else not enough buffer, do in place + // __len >= 4 + _BidirectionalIterator __m = __first; + _Distance __len2 = __len / 2; // __len2 >= 2 + _Ops::advance(__m, __len2); + // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false + // F????????????????T + // f m l + _BidirectionalIterator __m1 = __m; + _BidirectionalIterator __first_false = __first; + _Distance __len_half = __len2; + while (!__pred(*--__m1)) { + if (__m1 == __first) + goto __first_half_done; + --__len_half; + } + // F???TFFF?????????T + // f m1 m l + __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__first, __m1, __pred, __len_half, __p, __bit); __first_half_done: - // TTTFFFFF?????????T - // f ff m l - // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true - __m1 = __m; - _BidirectionalIterator __second_false = __last; - ++__second_false; - __len_half = __len - __len2; - while (__pred(*__m1)) - { - if (++__m1 == __last) - goto __second_half_done; - --__len_half; - } - // TTTFFFFFTTTF?????T - // f ff m m1 l - __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - __m1, __last, __pred, __len_half, __p, __bit); + // TTTFFFFF?????????T + // f ff m l + // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true + __m1 = __m; + _BidirectionalIterator __second_false = __last; + ++__second_false; + __len_half = __len - __len2; + while (__pred(*__m1)) { + if (++__m1 == __last) + goto __second_half_done; + --__len_half; + } + // TTTFFFFFTTTF?????T + // f ff m m1 l + __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__m1, __last, __pred, __len_half, __p, __bit); __second_half_done: - // TTTFFFFFTTTTTFFFFF - // f ff m sf l - return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; - // TTTTTTTTFFFFFFFFFF - // | + // TTTFFFFFTTTTTFFFFF + // f ff m sf l + return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; + // TTTTTTTTFFFFFFFFFF + // | } template -_LIBCPP_HIDE_FROM_ABI _BidirectionalIterator -__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, - bidirectional_iterator_tag) -{ - typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment - // Either prove all true and return __first or point to first false - while (true) - { - if (__first == __last) - return __first; - if (!__pred(*__first)) - break; - ++__first; - } - // __first points to first false, everything prior to __first is already set. - // Either prove [__first, __last) is all false and return __first, or point __last to last true - do - { - if (__first == --__last) - return __first; - } while (!__pred(*__last)); - // We now have a reduced range [__first, __last] - // *__first is known to be false - // *__last is known to be true - // __len >= 2 - difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; - pair __p(0, 0); - unique_ptr __h; - if (__len >= __alloc_limit) - { -// TODO: Remove the use of std::get_temporary_buffer -_LIBCPP_SUPPRESS_DEPRECATED_PUSH - __p = std::get_temporary_buffer(__len); -_LIBCPP_SUPPRESS_DEPRECATED_POP - __h.reset(__p.first); - } - return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag()); +_LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl( + _BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, bidirectional_iterator_tag) { + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment + // Either prove all true and return __first or point to first false + while (true) { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + // __first points to first false, everything prior to __first is already set. + // Either prove [__first, __last) is all false and return __first, or point __last to last true + do { + if (__first == --__last) + return __first; + } while (!__pred(*__last)); + // We now have a reduced range [__first, __last] + // *__first is known to be false + // *__last is known to be true + // __len >= 2 + difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; + pair __p(0, 0); + unique_ptr __h; + if (__len >= __alloc_limit) { + // TODO: Remove the use of std::get_temporary_buffer + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + __p = std::get_temporary_buffer(__len); + _LIBCPP_SUPPRESS_DEPRECATED_POP + __h.reset(__p.first); + } + return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag()); } template -_LIBCPP_HIDE_FROM_ABI -_ForwardIterator __stable_partition( +_LIBCPP_HIDE_FROM_ABI _ForwardIterator __stable_partition( _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred, _IterCategory __iter_category) { return std::__stable_partition_impl<_AlgPolicy, __remove_cvref_t<_Predicate>&>( std::move(__first), std::move(__last), __pred, __iter_category); } template -inline _LIBCPP_HIDE_FROM_ABI -_ForwardIterator -stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ +inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator +stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; return std::__stable_partition<_ClassicAlgPolicy, _Predicate&>( std::move(__first), std::move(__last), __pred, _IterCategory()); diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h index 175393fc47779162d9ef15e80452ea7b71caa209..ffc6e4ce281888a1482fb9dd7b21c8fb5003e37e 100644 --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -32,9 +32,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI -void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1, - typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) { +_LIBCPP_HIDE_FROM_ABI void __insertion_sort_move( + _BidirectionalIterator __first1, + _BidirectionalIterator __last1, + typename iterator_traits<_BidirectionalIterator>::value_type* __first2, + _Compare __comp) { using _Ops = _IterOps<_AlgPolicy>; typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; @@ -63,200 +65,187 @@ void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterat } template -_LIBCPP_HIDE_FROM_ABI void -__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, - typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp) -{ - using _Ops = _IterOps<_AlgPolicy>; +_LIBCPP_HIDE_FROM_ABI void __merge_move_construct( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + typename iterator_traits<_InputIterator1>::value_type* __result, + _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; - typedef typename iterator_traits<_InputIterator1>::value_type value_type; - __destruct_n __d(0); - unique_ptr __h(__result, __d); - for (; true; ++__result) - { - if (__first1 == __last1) - { - for (; __first2 != __last2; ++__first2, (void) ++__result, __d.template __incr()) - ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); - __h.release(); - return; - } - if (__first2 == __last2) - { - for (; __first1 != __last1; ++__first1, (void) ++__result, __d.template __incr()) - ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); - __h.release(); - return; - } - if (__comp(*__first2, *__first1)) - { - ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); - __d.template __incr(); - ++__first2; - } - else - { - ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); - __d.template __incr(); - ++__first1; - } + typedef typename iterator_traits<_InputIterator1>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__result, __d); + for (; true; ++__result) { + if (__first1 == __last1) { + for (; __first2 != __last2; ++__first2, (void)++__result, __d.template __incr()) + ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); + __h.release(); + return; + } + if (__first2 == __last2) { + for (; __first1 != __last1; ++__first1, (void)++__result, __d.template __incr()) + ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); + __h.release(); + return; } + if (__comp(*__first2, *__first1)) { + ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); + __d.template __incr(); + ++__first2; + } else { + ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); + __d.template __incr(); + ++__first1; + } + } } template -_LIBCPP_HIDE_FROM_ABI void -__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, - _OutputIterator __result, _Compare __comp) -{ - using _Ops = _IterOps<_AlgPolicy>; +_LIBCPP_HIDE_FROM_ABI void __merge_move_assign( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; - for (; __first1 != __last1; ++__result) - { - if (__first2 == __last2) - { - for (; __first1 != __last1; ++__first1, (void) ++__result) - *__result = _Ops::__iter_move(__first1); - return; - } - if (__comp(*__first2, *__first1)) - { - *__result = _Ops::__iter_move(__first2); - ++__first2; - } - else - { - *__result = _Ops::__iter_move(__first1); - ++__first1; - } + for (; __first1 != __last1; ++__result) { + if (__first2 == __last2) { + for (; __first1 != __last1; ++__first1, (void)++__result) + *__result = _Ops::__iter_move(__first1); + return; } - for (; __first2 != __last2; ++__first2, (void) ++__result) - *__result = _Ops::__iter_move(__first2); + if (__comp(*__first2, *__first1)) { + *__result = _Ops::__iter_move(__first2); + ++__first2; + } else { + *__result = _Ops::__iter_move(__first1); + ++__first1; + } + } + for (; __first2 != __last2; ++__first2, (void)++__result) + *__result = _Ops::__iter_move(__first2); } template -void -__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len, - typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size); +void __stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __buff, + ptrdiff_t __buff_size); template -void -__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len, - typename iterator_traits<_RandomAccessIterator>::value_type* __first2) -{ - using _Ops = _IterOps<_AlgPolicy>; +void __stable_sort_move(_RandomAccessIterator __first1, + _RandomAccessIterator __last1, + _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __first2) { + using _Ops = _IterOps<_AlgPolicy>; - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - switch (__len) - { - case 0: - return; - case 1: - ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); - return; - case 2: - __destruct_n __d(0); - unique_ptr __h2(__first2, __d); - if (__comp(*--__last1, *__first1)) - { - ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); - __d.template __incr(); - ++__first2; - ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); - } - else - { - ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); - __d.template __incr(); - ++__first2; - ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); - } - __h2.release(); - return; - } - if (__len <= 8) - { - std::__insertion_sort_move<_AlgPolicy, _Compare>(__first1, __last1, __first2, __comp); - return; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + switch (__len) { + case 0: + return; + case 1: + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); + return; + case 2: + __destruct_n __d(0); + unique_ptr __h2(__first2, __d); + if (__comp(*--__last1, *__first1)) { + ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); + __d.template __incr(); + ++__first2; + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); + } else { + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); + __d.template __incr(); + ++__first2; + ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); } - typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; - _RandomAccessIterator __m = __first1 + __l2; - std::__stable_sort<_AlgPolicy, _Compare>(__first1, __m, __comp, __l2, __first2, __l2); - std::__stable_sort<_AlgPolicy, _Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); - std::__merge_move_construct<_AlgPolicy, _Compare>(__first1, __m, __m, __last1, __first2, __comp); + __h2.release(); + return; + } + if (__len <= 8) { + std::__insertion_sort_move<_AlgPolicy, _Compare>(__first1, __last1, __first2, __comp); + return; + } + typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; + _RandomAccessIterator __m = __first1 + __l2; + std::__stable_sort<_AlgPolicy, _Compare>(__first1, __m, __comp, __l2, __first2, __l2); + std::__stable_sort<_AlgPolicy, _Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); + std::__merge_move_construct<_AlgPolicy, _Compare>(__first1, __m, __m, __last1, __first2, __comp); } template -struct __stable_sort_switch -{ - static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value; +struct __stable_sort_switch { + static const unsigned value = 128 * is_trivially_copy_assignable<_Tp>::value; }; template -void -__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len, - typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size) -{ - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - switch (__len) - { - case 0: - case 1: - return; - case 2: - if (__comp(*--__last, *__first)) - _IterOps<_AlgPolicy>::iter_swap(__first, __last); - return; - } - if (__len <= static_cast(__stable_sort_switch::value)) - { - std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); - return; - } - typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; - _RandomAccessIterator __m = __first + __l2; - if (__len <= __buff_size) - { - __destruct_n __d(0); - unique_ptr __h2(__buff, __d); - std::__stable_sort_move<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff); - __d.__set(__l2, (value_type*)nullptr); - std::__stable_sort_move<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); - __d.__set(__len, (value_type*)nullptr); - std::__merge_move_assign<_AlgPolicy, _Compare>( - __buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); -// std::__merge<_Compare>(move_iterator(__buff), -// move_iterator(__buff + __l2), -// move_iterator<_RandomAccessIterator>(__buff + __l2), -// move_iterator<_RandomAccessIterator>(__buff + __len), -// __first, __comp); - return; - } - std::__stable_sort<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff, __buff_size); - std::__stable_sort<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); - std::__inplace_merge<_AlgPolicy>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); +void __stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __buff, + ptrdiff_t __buff_size) { + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + switch (__len) { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + return; + } + if (__len <= static_cast(__stable_sort_switch::value)) { + std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); + return; + } + typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; + _RandomAccessIterator __m = __first + __l2; + if (__len <= __buff_size) { + __destruct_n __d(0); + unique_ptr __h2(__buff, __d); + std::__stable_sort_move<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff); + __d.__set(__l2, (value_type*)nullptr); + std::__stable_sort_move<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); + __d.__set(__len, (value_type*)nullptr); + std::__merge_move_assign<_AlgPolicy, _Compare>( + __buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); + // std::__merge<_Compare>(move_iterator(__buff), + // move_iterator(__buff + __l2), + // move_iterator<_RandomAccessIterator>(__buff + __l2), + // move_iterator<_RandomAccessIterator>(__buff + __len), + // __first, __comp); + return; + } + std::__stable_sort<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff, __buff_size); + std::__stable_sort<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); + std::__inplace_merge<_AlgPolicy>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); } template -inline _LIBCPP_HIDE_FROM_ABI -void __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { - using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; +inline _LIBCPP_HIDE_FROM_ABI void +__stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; difference_type __len = __last - __first; pair __buf(0, 0); unique_ptr __h; if (__len > static_cast(__stable_sort_switch::value)) { -// TODO: Remove the use of std::get_temporary_buffer -_LIBCPP_SUPPRESS_DEPRECATED_PUSH - __buf = std::get_temporary_buffer(__len); -_LIBCPP_SUPPRESS_DEPRECATED_POP - __h.reset(__buf.first); + // TODO: Remove the use of std::get_temporary_buffer + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + __buf = std::get_temporary_buffer(__len); + _LIBCPP_SUPPRESS_DEPRECATED_POP + __h.reset(__buf.first); } std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second); @@ -264,14 +253,13 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP } template -inline _LIBCPP_HIDE_FROM_ABI -void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI void +stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { std::__stable_sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_HIDE_FROM_ABI -void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { +inline _LIBCPP_HIDE_FROM_ABI void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { std::stable_sort(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/swap_ranges.h b/libcxx/include/__algorithm/swap_ranges.h index 96eba7484bf4211859497793fcc42b6ebe4d7ca4..7fab5c49a656fe732efa4e79d21b33023dbb6ee3 100644 --- a/libcxx/include/__algorithm/swap_ranges.h +++ b/libcxx/include/__algorithm/swap_ranges.h @@ -22,8 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // 2+2 iterators: the shorter size will be used. template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -pair<_ForwardIterator1, _ForwardIterator2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator1, _ForwardIterator2> __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _Sentinel2 __last2) { while (__first1 != __last1 && __first2 != __last2) { _IterOps<_AlgPolicy>::iter_swap(__first1, __first2); @@ -36,8 +35,7 @@ __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 // 2+1 iterators: size2 >= size1. template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -pair<_ForwardIterator1, _ForwardIterator2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator1, _ForwardIterator2> __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2) { while (__first1 != __last1) { _IterOps<_AlgPolicy>::iter_swap(__first1, __first2); @@ -51,8 +49,7 @@ __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator2 swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { - return std::__swap_ranges<_ClassicAlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2)).second; + return std::__swap_ranges<_ClassicAlgPolicy>(std::move(__first1), std::move(__last1), std::move(__first2)).second; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/transform.h b/libcxx/include/__algorithm/transform.h index 76b9bb780cf948f0cf9ae1c0a0aad1b2263db35b..1b424409591cece7a96bca1f4b23d7b03d25033b 100644 --- a/libcxx/include/__algorithm/transform.h +++ b/libcxx/include/__algorithm/transform.h @@ -18,24 +18,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) -{ - for (; __first != __last; ++__first, (void) ++__result) - *__result = __op(*__first); - return __result; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) { + for (; __first != __last; ++__first, (void)++__result) + *__result = __op(*__first); + return __result; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, - _OutputIterator __result, _BinaryOperation __binary_op) -{ - for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result) - *__result = __binary_op(*__first1, *__first2); - return __result; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator transform( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _OutputIterator __result, + _BinaryOperation __binary_op) { + for (; __first1 != __last1; ++__first1, (void)++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h b/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h index 1f2039949d740ba63f83174410145f7a4ae4ae76..aef0fbfb7c2842ea9e6f279422f96fb098887bc5 100644 --- a/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h +++ b/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h @@ -20,7 +20,7 @@ #if _LIBCPP_STD_VER >= 20 _LIBCPP_PUSH_MACROS -#include <__undef_macros> +# include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD @@ -41,16 +41,12 @@ private: public: using result_type = invoke_result_t<_Gen&>; - _LIBCPP_HIDE_FROM_ABI - static constexpr auto min() { return __remove_cvref_t<_Gen>::min(); } - _LIBCPP_HIDE_FROM_ABI - static constexpr auto max() { return __remove_cvref_t<_Gen>::max(); } + _LIBCPP_HIDE_FROM_ABI static constexpr auto min() { return __remove_cvref_t<_Gen>::min(); } + _LIBCPP_HIDE_FROM_ABI static constexpr auto max() { return __remove_cvref_t<_Gen>::max(); } - _LIBCPP_HIDE_FROM_ABI - constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen_(__g) {} + _LIBCPP_HIDE_FROM_ABI constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen_(__g) {} - _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()() const { return __gen_(); } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()() const { return __gen_(); } }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/unwrap_iter.h b/libcxx/include/__algorithm/unwrap_iter.h index 91346e3c1bd2af9152765b6ce2fb4e91985392dc..a298a2b271056c81fdc354f989a3de929e325043 100644 --- a/libcxx/include/__algorithm/unwrap_iter.h +++ b/libcxx/include/__algorithm/unwrap_iter.h @@ -57,11 +57,11 @@ struct __unwrap_iter_impl<_Iter, true> { } }; -template, - __enable_if_t::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -decltype(_Impl::__unwrap(std::declval<_Iter>())) __unwrap_iter(_Iter __i) _NOEXCEPT { +template , + __enable_if_t::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 decltype(_Impl::__unwrap(std::declval<_Iter>())) +__unwrap_iter(_Iter __i) _NOEXCEPT { return _Impl::__unwrap(__i); } diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h index 449802a2e30405eb7f99b089eb06ce59e945c951..3dfb6937d0325e737fb0ab275c1b4cda564b67b9 100644 --- a/libcxx/include/__atomic/atomic.h +++ b/libcxx/include/__atomic/atomic.h @@ -33,241 +33,220 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -struct atomic - : public __atomic_base<_Tp> -{ +struct atomic : public __atomic_base<_Tp> { using __base = __atomic_base<_Tp>; using value_type = _Tp; using difference_type = value_type; #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI - atomic() = default; + _LIBCPP_HIDE_FROM_ABI atomic() = default; #else - _LIBCPP_HIDE_FROM_ABI - atomic() _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default; #endif - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} - _LIBCPP_HIDE_FROM_ABI - _Tp operator=(_Tp __d) volatile _NOEXCEPT - {__base::store(__d); return __d;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator=(_Tp __d) _NOEXCEPT - {__base::store(__d); return __d;} + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) volatile _NOEXCEPT { + __base::store(__d); + return __d; + } + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) _NOEXCEPT { + __base::store(__d); + return __d; + } - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; }; // atomic template -struct atomic<_Tp*> - : public __atomic_base<_Tp*> -{ - using __base = __atomic_base<_Tp*>; - using value_type = _Tp*; - using difference_type = ptrdiff_t; - - _LIBCPP_HIDE_FROM_ABI - atomic() _NOEXCEPT = default; - - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} - - _LIBCPP_HIDE_FROM_ABI - _Tp* operator=(_Tp* __d) volatile _NOEXCEPT - {__base::store(__d); return __d;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator=(_Tp* __d) _NOEXCEPT - {__base::store(__d); return __d;} - - _LIBCPP_HIDE_FROM_ABI - _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - // __atomic_fetch_add accepts function pointers, guard against them. - static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); - return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); - } - - _LIBCPP_HIDE_FROM_ABI - _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - // __atomic_fetch_add accepts function pointers, guard against them. - static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); - return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); - } - - _LIBCPP_HIDE_FROM_ABI - _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - // __atomic_fetch_add accepts function pointers, guard against them. - static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); - return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); - } - - _LIBCPP_HIDE_FROM_ABI - _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - // __atomic_fetch_add accepts function pointers, guard against them. - static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); - return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); - } - - _LIBCPP_HIDE_FROM_ABI - _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} - - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; +struct atomic<_Tp*> : public __atomic_base<_Tp*> { + using __base = __atomic_base<_Tp*>; + using value_type = _Tp*; + using difference_type = ptrdiff_t; + + _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} + + _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __d) volatile _NOEXCEPT { + __base::store(__d); + return __d; + } + _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __d) _NOEXCEPT { + __base::store(__d); + return __d; + } + + _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); + return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); + return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); + return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); + return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) volatile _NOEXCEPT { return fetch_add(1); } + _LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) _NOEXCEPT { return fetch_add(1); } + _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) volatile _NOEXCEPT { return fetch_sub(1); } + _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) _NOEXCEPT { return fetch_sub(1); } + _LIBCPP_HIDE_FROM_ABI _Tp* operator++() volatile _NOEXCEPT { return fetch_add(1) + 1; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator++() _NOEXCEPT { return fetch_add(1) + 1; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator--() volatile _NOEXCEPT { return fetch_sub(1) - 1; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator--() _NOEXCEPT { return fetch_sub(1) - 1; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT { return fetch_add(__op) + __op; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT { return fetch_add(__op) + __op; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT { return fetch_sub(__op) - __op; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT { return fetch_sub(__op) - __op; } + + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; }; #if _LIBCPP_STD_VER >= 20 template requires is_floating_point_v<_Tp> struct atomic<_Tp> : __atomic_base<_Tp> { - private: - _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_fp80_long_double() { - // Only x87-fp80 long double has 64-bit mantissa - return __LDBL_MANT_DIG__ == 64 && std::is_same_v<_Tp, long double>; - } +private: + _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_fp80_long_double() { + // Only x87-fp80 long double has 64-bit mantissa + return __LDBL_MANT_DIG__ == 64 && std::is_same_v<_Tp, long double>; + } - _LIBCPP_HIDE_FROM_ABI static constexpr bool __has_rmw_builtin() { + _LIBCPP_HIDE_FROM_ABI static constexpr bool __has_rmw_builtin() { # ifndef _LIBCPP_COMPILER_CLANG_BASED - return false; + return false; # else - // The builtin __cxx_atomic_fetch_add errors during compilation for - // long double on platforms with fp80 format. - // For more details, see - // lib/Sema/SemaChecking.cpp function IsAllowedValueType - // LLVM Parser does not allow atomicrmw with x86_fp80 type. - // if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) && - // &Context.getTargetInfo().getLongDoubleFormat() == - // &llvm::APFloat::x87DoubleExtended()) - // For more info - // https://github.com/llvm/llvm-project/issues/68602 - // https://reviews.llvm.org/D53965 - return !__is_fp80_long_double(); + // The builtin __cxx_atomic_fetch_add errors during compilation for + // long double on platforms with fp80 format. + // For more details, see + // lib/Sema/SemaChecking.cpp function IsAllowedValueType + // LLVM Parser does not allow atomicrmw with x86_fp80 type. + // if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) && + // &Context.getTargetInfo().getLongDoubleFormat() == + // &llvm::APFloat::x87DoubleExtended()) + // For more info + // https://github.com/llvm/llvm-project/issues/68602 + // https://reviews.llvm.org/D53965 + return !__is_fp80_long_double(); # endif - } - - template - _LIBCPP_HIDE_FROM_ABI static _Tp - __rmw_op(_This&& __self, _Tp __operand, memory_order __m, _Operation __operation, _BuiltinOp __builtin_op) { - if constexpr (__has_rmw_builtin()) { - return __builtin_op(std::addressof(std::forward<_This>(__self).__a_), __operand, __m); - } else { - _Tp __old = __self.load(memory_order_relaxed); - _Tp __new = __operation(__old, __operand); - while (!__self.compare_exchange_weak(__old, __new, __m, memory_order_relaxed)) { + } + + template + _LIBCPP_HIDE_FROM_ABI static _Tp + __rmw_op(_This&& __self, _Tp __operand, memory_order __m, _Operation __operation, _BuiltinOp __builtin_op) { + if constexpr (__has_rmw_builtin()) { + return __builtin_op(std::addressof(std::forward<_This>(__self).__a_), __operand, __m); + } else { + _Tp __old = __self.load(memory_order_relaxed); + _Tp __new = __operation(__old, __operand); + while (!__self.compare_exchange_weak(__old, __new, __m, memory_order_relaxed)) { # ifdef _LIBCPP_COMPILER_CLANG_BASED - if constexpr (__is_fp80_long_double()) { - // https://github.com/llvm/llvm-project/issues/47978 - // clang bug: __old is not updated on failure for atomic::compare_exchange_weak - // Note __old = __self.load(memory_order_relaxed) will not work - std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), &__old, memory_order_relaxed); - } -# endif - __new = __operation(__old, __operand); - } - return __old; + if constexpr (__is_fp80_long_double()) { + // https://github.com/llvm/llvm-project/issues/47978 + // clang bug: __old is not updated on failure for atomic::compare_exchange_weak + // Note __old = __self.load(memory_order_relaxed) will not work + std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), &__old, memory_order_relaxed); } +# endif + __new = __operation(__old, __operand); + } + return __old; } + } + + template + _LIBCPP_HIDE_FROM_ABI static _Tp __fetch_add(_This&& __self, _Tp __operand, memory_order __m) { + auto __builtin_op = [](auto __a, auto __builtin_operand, auto __order) { + return std::__cxx_atomic_fetch_add(__a, __builtin_operand, __order); + }; + return __rmw_op(std::forward<_This>(__self), __operand, __m, std::plus<>{}, __builtin_op); + } + + template + _LIBCPP_HIDE_FROM_ABI static _Tp __fetch_sub(_This&& __self, _Tp __operand, memory_order __m) { + auto __builtin_op = [](auto __a, auto __builtin_operand, auto __order) { + return std::__cxx_atomic_fetch_sub(__a, __builtin_operand, __order); + }; + return __rmw_op(std::forward<_This>(__self), __operand, __m, std::minus<>{}, __builtin_op); + } + +public: + using __base = __atomic_base<_Tp>; + using value_type = _Tp; + using difference_type = value_type; - template - _LIBCPP_HIDE_FROM_ABI static _Tp __fetch_add(_This&& __self, _Tp __operand, memory_order __m) { - auto __builtin_op = [](auto __a, auto __builtin_operand, auto __order) { - return std::__cxx_atomic_fetch_add(__a, __builtin_operand, __order); - }; - return __rmw_op(std::forward<_This>(__self), __operand, __m, std::plus<>{}, __builtin_op); - } - - template - _LIBCPP_HIDE_FROM_ABI static _Tp __fetch_sub(_This&& __self, _Tp __operand, memory_order __m) { - auto __builtin_op = [](auto __a, auto __builtin_operand, auto __order) { - return std::__cxx_atomic_fetch_sub(__a, __builtin_operand, __order); - }; - return __rmw_op(std::forward<_This>(__self), __operand, __m, std::minus<>{}, __builtin_op); - } - - public: - using __base = __atomic_base<_Tp>; - using value_type = _Tp; - using difference_type = value_type; - - _LIBCPP_HIDE_FROM_ABI constexpr atomic() noexcept = default; - _LIBCPP_HIDE_FROM_ABI constexpr atomic(_Tp __d) noexcept : __base(__d) {} - - atomic(const atomic&) = delete; - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; - - _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) volatile noexcept - requires __base::is_always_lock_free - { - __base::store(__d); - return __d; - } - _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) noexcept { - __base::store(__d); - return __d; - } - - _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile noexcept - requires __base::is_always_lock_free - { - return __fetch_add(*this, __op, __m); - } - - _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) noexcept { - return __fetch_add(*this, __op, __m); - } - - _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile noexcept - requires __base::is_always_lock_free - { - return __fetch_sub(*this, __op, __m); - } - - _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) noexcept { - return __fetch_sub(*this, __op, __m); - } - - _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) volatile noexcept - requires __base::is_always_lock_free - { - return fetch_add(__op) + __op; - } - - _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) noexcept { return fetch_add(__op) + __op; } - - _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) volatile noexcept - requires __base::is_always_lock_free - { - return fetch_sub(__op) - __op; - } - - _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) noexcept { return fetch_sub(__op) - __op; } + _LIBCPP_HIDE_FROM_ABI constexpr atomic() noexcept = default; + _LIBCPP_HIDE_FROM_ABI constexpr atomic(_Tp __d) noexcept : __base(__d) {} + + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) volatile noexcept + requires __base::is_always_lock_free + { + __base::store(__d); + return __d; + } + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) noexcept { + __base::store(__d); + return __d; + } + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile noexcept + requires __base::is_always_lock_free + { + return __fetch_add(*this, __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) noexcept { + return __fetch_add(*this, __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile noexcept + requires __base::is_always_lock_free + { + return __fetch_sub(*this, __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) noexcept { + return __fetch_sub(*this, __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) volatile noexcept + requires __base::is_always_lock_free + { + return fetch_add(__op) + __op; + } + + _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) noexcept { return fetch_add(__op) + __op; } + + _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) volatile noexcept + requires __base::is_always_lock_free + { + return fetch_sub(__op) - __op; + } + + _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) noexcept { return fetch_sub(__op) - __op; } }; #endif // _LIBCPP_STD_VER >= 20 @@ -275,476 +254,363 @@ struct atomic<_Tp> : __atomic_base<_Tp> { // atomic_is_lock_free template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT -{ - return __o->is_lock_free(); +_LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT { + return __o->is_lock_free(); } template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT -{ - return __o->is_lock_free(); +_LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT { + return __o->is_lock_free(); } // atomic_init template -_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI -void -atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - std::__cxx_atomic_init(std::addressof(__o->__a_), __d); +_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void +atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + std::__cxx_atomic_init(std::addressof(__o->__a_), __d); } template -_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI -void -atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - std::__cxx_atomic_init(std::addressof(__o->__a_), __d); +_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void +atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + std::__cxx_atomic_init(std::addressof(__o->__a_), __d); } // atomic_store template -_LIBCPP_HIDE_FROM_ABI -void -atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - __o->store(__d); +_LIBCPP_HIDE_FROM_ABI void atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + __o->store(__d); } template -_LIBCPP_HIDE_FROM_ABI -void -atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - __o->store(__d); +_LIBCPP_HIDE_FROM_ABI void atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + __o->store(__d); } // atomic_store_explicit template -_LIBCPP_HIDE_FROM_ABI -void +_LIBCPP_HIDE_FROM_ABI void atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) -{ - __o->store(__d, __m); + _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { + __o->store(__d, __m); } template -_LIBCPP_HIDE_FROM_ABI -void +_LIBCPP_HIDE_FROM_ABI void atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) -{ - __o->store(__d, __m); + _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { + __o->store(__d, __m); } // atomic_load template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT -{ - return __o->load(); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT { + return __o->load(); } template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_load(const atomic<_Tp>* __o) _NOEXCEPT -{ - return __o->load(); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const atomic<_Tp>* __o) _NOEXCEPT { + return __o->load(); } // atomic_load_explicit template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) -{ - return __o->load(__m); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return __o->load(__m); } template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) -{ - return __o->load(__m); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return __o->load(__m); } // atomic_exchange template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->exchange(__d); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->exchange(__d); } template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->exchange(__d); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->exchange(__d); } // atomic_exchange_explicit template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT -{ - return __o->exchange(__d, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT { + return __o->exchange(__d, __m); } template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT -{ - return __o->exchange(__d, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT { + return __o->exchange(__d, __m); } // atomic_compare_exchange_weak template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->compare_exchange_weak(*__e, __d); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->compare_exchange_weak(*__e, __d); } template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->compare_exchange_weak(*__e, __d); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak( + atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->compare_exchange_weak(*__e, __d); } // atomic_compare_exchange_strong template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->compare_exchange_strong(*__e, __d); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->compare_exchange_strong(*__e, __d); } template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->compare_exchange_strong(*__e, __d); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong( + atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->compare_exchange_strong(*__e, __d); } // atomic_compare_exchange_weak_explicit template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, - typename atomic<_Tp>::value_type __d, - memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) -{ - return __o->compare_exchange_weak(*__e, __d, __s, __f); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit( + volatile atomic<_Tp>* __o, + typename atomic<_Tp>::value_type* __e, + typename atomic<_Tp>::value_type __d, + memory_order __s, + memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return __o->compare_exchange_weak(*__e, __d, __s, __f); } template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, - memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) -{ - return __o->compare_exchange_weak(*__e, __d, __s, __f); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit( + atomic<_Tp>* __o, + typename atomic<_Tp>::value_type* __e, + typename atomic<_Tp>::value_type __d, + memory_order __s, + memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return __o->compare_exchange_weak(*__e, __d, __s, __f); } // atomic_compare_exchange_strong_explicit template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, - typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, - memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) -{ - return __o->compare_exchange_strong(*__e, __d, __s, __f); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit( + volatile atomic<_Tp>* __o, + typename atomic<_Tp>::value_type* __e, + typename atomic<_Tp>::value_type __d, + memory_order __s, + memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return __o->compare_exchange_strong(*__e, __d, __s, __f); } template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, - typename atomic<_Tp>::value_type __d, - memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) -{ - return __o->compare_exchange_strong(*__e, __d, __s, __f); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit( + atomic<_Tp>* __o, + typename atomic<_Tp>::value_type* __e, + typename atomic<_Tp>::value_type __d, + memory_order __s, + memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return __o->compare_exchange_strong(*__e, __d, __s, __f); } // atomic_wait template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_wait(const volatile atomic<_Tp>* __o, - typename atomic<_Tp>::value_type __v) _NOEXCEPT -{ - return __o->wait(__v); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_wait(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT { + return __o->wait(__v); } template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_wait(const atomic<_Tp>* __o, - typename atomic<_Tp>::value_type __v) _NOEXCEPT -{ - return __o->wait(__v); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_wait(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT { + return __o->wait(__v); } // atomic_wait_explicit template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_wait_explicit(const volatile atomic<_Tp>* __o, - typename atomic<_Tp>::value_type __v, - memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) -{ - return __o->wait(__v, __m); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_wait_explicit(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return __o->wait(__v, __m); } template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_wait_explicit(const atomic<_Tp>* __o, - typename atomic<_Tp>::value_type __v, - memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) -{ - return __o->wait(__v, __m); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return __o->wait(__v, __m); } // atomic_notify_one template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT -{ - __o->notify_one(); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT { + __o->notify_one(); } template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT -{ - __o->notify_one(); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT { + __o->notify_one(); } // atomic_notify_all template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT -{ - __o->notify_all(); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT { + __o->notify_all(); } template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT -{ - __o->notify_all(); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT { + __o->notify_all(); } // atomic_fetch_add template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_add(__op); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { + return __o->fetch_add(__op); } template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_add(__op); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { + return __o->fetch_add(__op); } // atomic_fetch_add_explicit template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_add(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_add_explicit( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_add(__op, __m); } template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_add(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_add(__op, __m); } // atomic_fetch_sub template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_sub(__op); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { + return __o->fetch_sub(__op); } template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_sub(__op); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { + return __o->fetch_sub(__op); } // atomic_fetch_sub_explicit template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_sub(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_sub_explicit( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_sub(__op, __m); } template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_sub(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_sub(__op, __m); } // atomic_fetch_and template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_and(__op); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_and(__op); } template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_and(__op); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_and(__op); } // atomic_fetch_and_explicit template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_and(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and_explicit( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_and(__op, __m); } template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_and(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_and(__op, __m); } // atomic_fetch_or template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_or(__op); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_or(__op); } template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_or(__op); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_or(__op); } // atomic_fetch_or_explicit template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_or(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_or(__op, __m); } template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_or(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_or(__op, __m); } // atomic_fetch_xor template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_xor(__op); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_xor(__op); } template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_xor(__op); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_xor(__op); } // atomic_fetch_xor_explicit template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_xor(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor_explicit( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_xor(__op, __m); } template ::value && !is_same<_Tp, bool>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_xor(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_xor(__op, __m); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__atomic/atomic_base.h b/libcxx/include/__atomic/atomic_base.h index 775d06d7570183371130281231775fa3368ba66d..3ad3b562c598057f6714f819b1ff9e0b218e993d 100644 --- a/libcxx/include/__atomic/atomic_base.h +++ b/libcxx/include/__atomic/atomic_base.h @@ -29,114 +29,109 @@ _LIBCPP_BEGIN_NAMESPACE_STD template ::value && !is_same<_Tp, bool>::value> -struct __atomic_base // false +struct __atomic_base // false { - mutable __cxx_atomic_impl<_Tp> __a_; + mutable __cxx_atomic_impl<_Tp> __a_; #if _LIBCPP_STD_VER >= 17 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value; #endif - _LIBCPP_HIDE_FROM_ABI - bool is_lock_free() const volatile _NOEXCEPT - {return __cxx_atomic_is_lock_free(sizeof(__cxx_atomic_impl<_Tp>));} - _LIBCPP_HIDE_FROM_ABI - bool is_lock_free() const _NOEXCEPT - {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} - _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { - std::__cxx_atomic_store(std::addressof(__a_), __d, __m); - } - _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT - _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { - std::__cxx_atomic_store(std::addressof(__a_), __d, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { - return std::__cxx_atomic_load(std::addressof(__a_), __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { - return std::__cxx_atomic_load(std::addressof(__a_), __m); - } - _LIBCPP_HIDE_FROM_ABI - operator _Tp() const volatile _NOEXCEPT {return load();} - _LIBCPP_HIDE_FROM_ABI - operator _Tp() const _NOEXCEPT {return load();} - _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { - return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); - } - _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { - return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { - return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); - } - _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { - return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); - } - - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const - volatile _NOEXCEPT { - std::__cxx_atomic_wait(std::addressof(__a_), __v, __m); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void - wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT { - std::__cxx_atomic_wait(std::addressof(__a_), __v, __m); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { - std::__cxx_atomic_notify_one(std::addressof(__a_)); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { - std::__cxx_atomic_notify_one(std::addressof(__a_)); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { - std::__cxx_atomic_notify_all(std::addressof(__a_)); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { - std::__cxx_atomic_notify_all(std::addressof(__a_)); - } + _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const volatile _NOEXCEPT { + return __cxx_atomic_is_lock_free(sizeof(__cxx_atomic_impl<_Tp>)); + } + _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const _NOEXCEPT { + return static_cast<__atomic_base const volatile*>(this)->is_lock_free(); + } + _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { + std::__cxx_atomic_store(std::addressof(__a_), __d, __m); + } + _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT + _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { + std::__cxx_atomic_store(std::addressof(__a_), __d, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return std::__cxx_atomic_load(std::addressof(__a_), __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return std::__cxx_atomic_load(std::addressof(__a_), __m); + } + _LIBCPP_HIDE_FROM_ABI operator _Tp() const volatile _NOEXCEPT { return load(); } + _LIBCPP_HIDE_FROM_ABI operator _Tp() const _NOEXCEPT { return load(); } + _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT + _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); + } + _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT + _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT + _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); + } + _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT + _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); + } + + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const + volatile _NOEXCEPT { + std::__cxx_atomic_wait(std::addressof(__a_), __v, __m); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void + wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT { + std::__cxx_atomic_wait(std::addressof(__a_), __v, __m); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { + std::__cxx_atomic_notify_one(std::addressof(__a_)); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { + std::__cxx_atomic_notify_one(std::addressof(__a_)); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { + std::__cxx_atomic_notify_all(std::addressof(__a_)); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { + std::__cxx_atomic_notify_all(std::addressof(__a_)); + } #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI constexpr - __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {} + _LIBCPP_HIDE_FROM_ABI constexpr __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {} #else - _LIBCPP_HIDE_FROM_ABI - __atomic_base() _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI __atomic_base() _NOEXCEPT = default; #endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} - __atomic_base(const __atomic_base&) = delete; + __atomic_base(const __atomic_base&) = delete; }; #if _LIBCPP_STD_VER >= 17 @@ -147,84 +142,62 @@ _LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free; // atomic template -struct __atomic_base<_Tp, true> - : public __atomic_base<_Tp, false> -{ - using __base = __atomic_base<_Tp, false>; - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - __atomic_base() _NOEXCEPT = default; - - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} - - _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); - } - - _LIBCPP_HIDE_FROM_ABI - _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} - _LIBCPP_HIDE_FROM_ABI - _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} - _LIBCPP_HIDE_FROM_ABI - _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} - _LIBCPP_HIDE_FROM_ABI - _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} - _LIBCPP_HIDE_FROM_ABI - _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} +struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> { + using __base = __atomic_base<_Tp, false>; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __atomic_base() _NOEXCEPT = default; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp operator++(int) volatile _NOEXCEPT { return fetch_add(_Tp(1)); } + _LIBCPP_HIDE_FROM_ABI _Tp operator++(int) _NOEXCEPT { return fetch_add(_Tp(1)); } + _LIBCPP_HIDE_FROM_ABI _Tp operator--(int) volatile _NOEXCEPT { return fetch_sub(_Tp(1)); } + _LIBCPP_HIDE_FROM_ABI _Tp operator--(int) _NOEXCEPT { return fetch_sub(_Tp(1)); } + _LIBCPP_HIDE_FROM_ABI _Tp operator++() volatile _NOEXCEPT { return fetch_add(_Tp(1)) + _Tp(1); } + _LIBCPP_HIDE_FROM_ABI _Tp operator++() _NOEXCEPT { return fetch_add(_Tp(1)) + _Tp(1); } + _LIBCPP_HIDE_FROM_ABI _Tp operator--() volatile _NOEXCEPT { return fetch_sub(_Tp(1)) - _Tp(1); } + _LIBCPP_HIDE_FROM_ABI _Tp operator--() _NOEXCEPT { return fetch_sub(_Tp(1)) - _Tp(1); } + _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) volatile _NOEXCEPT { return fetch_add(__op) + __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) _NOEXCEPT { return fetch_add(__op) + __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) volatile _NOEXCEPT { return fetch_sub(__op) - __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) _NOEXCEPT { return fetch_sub(__op) - __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __op) volatile _NOEXCEPT { return fetch_and(__op) & __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __op) _NOEXCEPT { return fetch_and(__op) & __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __op) volatile _NOEXCEPT { return fetch_or(__op) | __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __op) _NOEXCEPT { return fetch_or(__op) | __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) volatile _NOEXCEPT { return fetch_xor(__op) ^ __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) _NOEXCEPT { return fetch_xor(__op) ^ __op; } }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__atomic/atomic_flag.h b/libcxx/include/__atomic/atomic_flag.h index edfa978f99357ba55e539f14a4248cab3c7773be..d76e5e45c01a0290d818d1f6a9373ddca6c5deae 100644 --- a/libcxx/include/__atomic/atomic_flag.h +++ b/libcxx/include/__atomic/atomic_flag.h @@ -24,205 +24,135 @@ _LIBCPP_BEGIN_NAMESPACE_STD -struct atomic_flag -{ - __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; - - _LIBCPP_HIDE_FROM_ABI - bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT - {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} - _LIBCPP_HIDE_FROM_ABI - bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT - {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} - - _LIBCPP_HIDE_FROM_ABI - bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} - _LIBCPP_HIDE_FROM_ABI - bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} - _LIBCPP_HIDE_FROM_ABI - void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} - _LIBCPP_HIDE_FROM_ABI - void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT - {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} - - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT - {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT - {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void notify_one() volatile _NOEXCEPT - {__cxx_atomic_notify_one(&__a_);} - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void notify_one() _NOEXCEPT - {__cxx_atomic_notify_one(&__a_);} - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void notify_all() volatile _NOEXCEPT - {__cxx_atomic_notify_all(&__a_);} - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void notify_all() _NOEXCEPT - {__cxx_atomic_notify_all(&__a_);} +struct atomic_flag { + __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; + + _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT { + return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m); + } + _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT { + return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m); + } + + _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m); + } + _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m); + } + _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m); + } + _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT { + __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m); + } + + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const + volatile _NOEXCEPT { + __cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void + wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT { + __cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { + __cxx_atomic_notify_one(&__a_); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { __cxx_atomic_notify_one(&__a_); } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { + __cxx_atomic_notify_all(&__a_); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { __cxx_atomic_notify_all(&__a_); } #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI constexpr - atomic_flag() _NOEXCEPT : __a_(false) {} + _LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {} #else - atomic_flag() _NOEXCEPT = default; + atomic_flag() _NOEXCEPT = default; #endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION - - atomic_flag(const atomic_flag&) = delete; - atomic_flag& operator=(const atomic_flag&) = delete; - atomic_flag& operator=(const atomic_flag&) volatile = delete; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION + atomic_flag(const atomic_flag&) = delete; + atomic_flag& operator=(const atomic_flag&) = delete; + atomic_flag& operator=(const atomic_flag&) volatile = delete; }; -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT -{ - return __o->test(); -} +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test(const atomic_flag* __o) _NOEXCEPT -{ - return __o->test(); -} +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const atomic_flag* __o) _NOEXCEPT { return __o->test(); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - return __o->test(__m); +inline _LIBCPP_HIDE_FROM_ABI bool +atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT { + return __o->test(__m); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - return __o->test(__m); +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT { + return __o->test(__m); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT -{ - return __o->test_and_set(); +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT { + return __o->test_and_set(); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT -{ - return __o->test_and_set(); -} +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT { return __o->test_and_set(); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - return __o->test_and_set(__m); +inline _LIBCPP_HIDE_FROM_ABI bool +atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT { + return __o->test_and_set(__m); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - return __o->test_and_set(__m); +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT { + return __o->test_and_set(__m); } -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT -{ - __o->clear(); -} +inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); } -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_flag_clear(atomic_flag* __o) _NOEXCEPT -{ - __o->clear(); -} +inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); } -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - __o->clear(__m); +inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT { + __o->clear(__m); } -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - __o->clear(__m); +inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT { + __o->clear(__m); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT -{ - __o->wait(__v); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT { + __o->wait(__v); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT -{ - __o->wait(__v); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT { + __o->wait(__v); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_wait_explicit(const volatile atomic_flag* __o, - bool __v, memory_order __m) _NOEXCEPT -{ - __o->wait(__v, __m); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT { + __o->wait(__v, __m); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_wait_explicit(const atomic_flag* __o, - bool __v, memory_order __m) _NOEXCEPT -{ - __o->wait(__v, __m); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT { + __o->wait(__v, __m); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT -{ - __o->notify_one(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT { + __o->notify_one(); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT -{ - __o->notify_one(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT { + __o->notify_one(); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT -{ - __o->notify_all(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT { + __o->notify_all(); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT -{ - __o->notify_all(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT { + __o->notify_all(); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__atomic/atomic_lock_free.h b/libcxx/include/__atomic/atomic_lock_free.h index d607569ed07da9f38d47adc5dee7482894130544..0715439db45039131e833d0f4dfc400e8a459b6b 100644 --- a/libcxx/include/__atomic/atomic_lock_free.h +++ b/libcxx/include/__atomic/atomic_lock_free.h @@ -16,33 +16,33 @@ #endif #if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE) -# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE -# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE -#ifndef _LIBCPP_HAS_NO_CHAR8_T -# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE -#endif -# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE -# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE -# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE -# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE -# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE -# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE -# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE -# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE +# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE +# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE +# ifndef _LIBCPP_HAS_NO_CHAR8_T +# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE +# endif +# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE +# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE +# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE +# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE +# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE +# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE +# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE +# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE #elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE) -# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE -# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE -#ifndef _LIBCPP_HAS_NO_CHAR8_T -# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE -#endif -# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE -# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE -# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE -# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE -# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE -# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE -# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE -# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE +# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +# ifndef _LIBCPP_HAS_NO_CHAR8_T +# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE +# endif +# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE +# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE +# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE +# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE +# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE #endif #endif // _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H diff --git a/libcxx/include/__atomic/atomic_sync.h b/libcxx/include/__atomic/atomic_sync.h index d55450bb5f9c5805a908d5d840c9ac66222802aa..3d20d6a8ce251488fb9c9b0564d6d48a2c02364a 100644 --- a/libcxx/include/__atomic/atomic_sync.h +++ b/libcxx/include/__atomic/atomic_sync.h @@ -34,77 +34,73 @@ _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*); _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t); -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*); -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*); -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*); -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void +__cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void +__cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t +__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void +__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t); template struct __libcpp_atomic_wait_backoff_impl { - _Atp* __a; - _Fn __test_fn; - _LIBCPP_AVAILABILITY_SYNC - _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const - { - if(__elapsed > chrono::microseconds(64)) - { - auto const __monitor = std::__libcpp_atomic_monitor(__a); - if(__test_fn()) - return true; - std::__libcpp_atomic_wait(__a, __monitor); - } - else if(__elapsed > chrono::microseconds(4)) - __libcpp_thread_yield(); - else - {} // poll - return false; - } + _Atp* __a; + _Fn __test_fn; + _LIBCPP_AVAILABILITY_SYNC + _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const { + if (__elapsed > chrono::microseconds(64)) { + auto const __monitor = std::__libcpp_atomic_monitor(__a); + if (__test_fn()) + return true; + std::__libcpp_atomic_wait(__a, __monitor); + } else if (__elapsed > chrono::microseconds(4)) + __libcpp_thread_yield(); + else { + } // poll + return false; + } }; template -_LIBCPP_AVAILABILITY_SYNC -_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn) -{ - __libcpp_atomic_wait_backoff_impl<_Atp, __decay_t<_Fn> > __backoff_fn = {__a, __test_fn}; - return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Fn&& __test_fn) { + __libcpp_atomic_wait_backoff_impl<_Atp, __decay_t<_Fn> > __backoff_fn = {__a, __test_fn}; + return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn); } #else // _LIBCPP_HAS_NO_THREADS template -_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { } +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) {} template -_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { } +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) {} template -_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn) -{ - return std::__libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy()); +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp*, _Fn&& __test_fn) { + return std::__libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy()); } #endif // _LIBCPP_HAS_NO_THREADS -template _LIBCPP_HIDE_FROM_ABI -bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) { - return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0; +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) { + return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0; } template struct __cxx_atomic_wait_test_fn_impl { - _Atp* __a; - _Tp __val; - memory_order __order; - _LIBCPP_HIDE_FROM_ABI bool operator()() const - { - return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val); - } + _Atp* __a; + _Tp __val; + memory_order __order; + _LIBCPP_HIDE_FROM_ABI bool operator()() const { + return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val); + } }; template -_LIBCPP_AVAILABILITY_SYNC -_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order) -{ - __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order}; - return std::__cxx_atomic_wait(__a, __test_fn); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool +__cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order) { + __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order}; + return std::__cxx_atomic_wait(__a, __test_fn); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__atomic/check_memory_order.h b/libcxx/include/__atomic/check_memory_order.h index d744312122bd46d504da820fe14fd53aad941f5f..3012aec0521b38763a1ecd8043e3b03f6d0a474d 100644 --- a/libcxx/include/__atomic/check_memory_order.h +++ b/libcxx/include/__atomic/check_memory_order.h @@ -15,20 +15,16 @@ # pragma GCC system_header #endif -#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ - _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \ - __m == memory_order_acquire || \ - __m == memory_order_acq_rel, \ - "memory order argument to atomic operation is invalid") +#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ + _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || __m == memory_order_acquire || __m == memory_order_acq_rel, \ + "memory order argument to atomic operation is invalid") -#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \ - _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \ - __m == memory_order_acq_rel, \ - "memory order argument to atomic operation is invalid") +#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \ + _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || __m == memory_order_acq_rel, \ + "memory order argument to atomic operation is invalid") -#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \ - _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \ - __f == memory_order_acq_rel, \ - "memory order argument to atomic operation is invalid") +#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \ + _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || __f == memory_order_acq_rel, \ + "memory order argument to atomic operation is invalid") #endif // _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H diff --git a/libcxx/include/__atomic/contention_t.h b/libcxx/include/__atomic/contention_t.h index 1d8d02430b4f0d6bd42c3a736a861515dcd1fe5a..65890f338ce990fdb276642a3706c162c120f7f4 100644 --- a/libcxx/include/__atomic/contention_t.h +++ b/libcxx/include/__atomic/contention_t.h @@ -20,9 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__)) - using __cxx_contention_t = int32_t; +using __cxx_contention_t = int32_t; #else - using __cxx_contention_t = int64_t; +using __cxx_contention_t = int64_t; #endif // __linux__ || (_AIX && !__64BIT__) using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; diff --git a/libcxx/include/__atomic/cxx_atomic_impl.h b/libcxx/include/__atomic/cxx_atomic_impl.h index 5d724669fee875a21672b7c01ed58154dda7238e..1a0b808a0cb1c4f994e02c38fc25af9b4ac7b582 100644 --- a/libcxx/include/__atomic/cxx_atomic_impl.h +++ b/libcxx/include/__atomic/cxx_atomic_impl.h @@ -26,20 +26,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \ - defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS) +#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS) // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because // the default operator= in an object is not volatile, a byte-by-byte copy // is required. -template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) { +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) { __a_value = __val; } -template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) { +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) { volatile char* __to = reinterpret_cast(std::addressof(__a_value)); - volatile char* __end = __to + sizeof(_Tp); + volatile char* __end = __to + sizeof(_Tp); volatile const char* __from = reinterpret_cast(std::addressof(__val)); while (__to != __end) *__to++ = *__from++; @@ -51,78 +50,74 @@ void __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& _ template struct __cxx_atomic_base_impl { - _LIBCPP_HIDE_FROM_ABI -#ifndef _LIBCPP_CXX03_LANG - __cxx_atomic_base_impl() _NOEXCEPT = default; -#else - __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT - : __a_value(value) {} +# ifndef _LIBCPP_CXX03_LANG + __cxx_atomic_base_impl() _NOEXCEPT = default; +# else + __cxx_atomic_base_impl() _NOEXCEPT : __a_value() { + } +# endif // _LIBCPP_CXX03_LANG + _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT : __a_value(value) {} _Tp __a_value; }; _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) { // Avoid switch statement to make this a constexpr. - return __order == memory_order_relaxed ? __ATOMIC_RELAXED: - (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: - (__order == memory_order_release ? __ATOMIC_RELEASE: - (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: - (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL: - __ATOMIC_CONSUME)))); + return __order == memory_order_relaxed + ? __ATOMIC_RELAXED + : (__order == memory_order_acquire + ? __ATOMIC_ACQUIRE + : (__order == memory_order_release + ? __ATOMIC_RELEASE + : (__order == memory_order_seq_cst + ? __ATOMIC_SEQ_CST + : (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_CONSUME)))); } _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) { // Avoid switch statement to make this a constexpr. - return __order == memory_order_relaxed ? __ATOMIC_RELAXED: - (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: - (__order == memory_order_release ? __ATOMIC_RELAXED: - (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: - (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE: - __ATOMIC_CONSUME)))); + return __order == memory_order_relaxed + ? __ATOMIC_RELAXED + : (__order == memory_order_acquire + ? __ATOMIC_ACQUIRE + : (__order == memory_order_release + ? __ATOMIC_RELAXED + : (__order == memory_order_seq_cst + ? __ATOMIC_SEQ_CST + : (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE : __ATOMIC_CONSUME)))); } template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { __cxx_atomic_assign_volatile(__a->__a_value, __val); } template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { __a->__a_value = __val; } -_LIBCPP_HIDE_FROM_ABI inline -void __cxx_atomic_thread_fence(memory_order __order) { +_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) { __atomic_thread_fence(__to_gcc_order(__order)); } -_LIBCPP_HIDE_FROM_ABI inline -void __cxx_atomic_signal_fence(memory_order __order) { +_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) { __atomic_signal_fence(__to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) { __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) { __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { _Tp __ret; __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order)); return __ret; @@ -141,17 +136,15 @@ __cxx_atomic_load_inplace(const __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, me } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { _Tp __ret; __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order)); return __ret; } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Tp __value, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) { _Tp __ret; __atomic_exchange( std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order)); @@ -159,9 +152,7 @@ _Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) { _Tp __ret; __atomic_exchange( std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order)); @@ -169,10 +160,12 @@ _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong( - volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, - memory_order __success, memory_order __failure) { +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + volatile __cxx_atomic_base_impl<_Tp>* __a, + _Tp* __expected, + _Tp __value, + memory_order __success, + memory_order __failure) { return __atomic_compare_exchange( std::addressof(__a->__a_value), __expected, @@ -183,10 +176,8 @@ bool __cxx_atomic_compare_exchange_strong( } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong( - __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, - memory_order __failure) { +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { return __atomic_compare_exchange( std::addressof(__a->__a_value), __expected, @@ -197,10 +188,12 @@ bool __cxx_atomic_compare_exchange_strong( } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak( - volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, - memory_order __success, memory_order __failure) { +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + volatile __cxx_atomic_base_impl<_Tp>* __a, + _Tp* __expected, + _Tp __value, + memory_order __success, + memory_order __failure) { return __atomic_compare_exchange( std::addressof(__a->__a_value), __expected, @@ -211,10 +204,8 @@ bool __cxx_atomic_compare_exchange_weak( } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak( - __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, - memory_order __failure) { +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { return __atomic_compare_exchange( std::addressof(__a->__a_value), __expected, @@ -225,193 +216,182 @@ bool __cxx_atomic_compare_exchange_weak( } template -struct __skip_amt { enum {value = 1}; }; +struct __skip_amt { + enum { value = 1 }; +}; template -struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; }; +struct __skip_amt<_Tp*> { + enum { value = sizeof(_Tp) }; +}; // FIXME: Haven't figured out what the spec says about using arrays with // atomic_fetch_add. Force a failure rather than creating bad behavior. template -struct __skip_amt<_Tp[]> { }; +struct __skip_amt<_Tp[]> {}; template -struct __skip_amt<_Tp[n]> { }; +struct __skip_amt<_Tp[n]> {}; template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Td __delta, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Td __delta, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } -#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) +# define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) #elif defined(_LIBCPP_HAS_C_ATOMIC_IMP) template struct __cxx_atomic_base_impl { - _LIBCPP_HIDE_FROM_ABI -#ifndef _LIBCPP_CXX03_LANG - __cxx_atomic_base_impl() _NOEXCEPT = default; -#else - __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT - : __a_value(__value) {} +# ifndef _LIBCPP_CXX03_LANG + __cxx_atomic_base_impl() _NOEXCEPT = default; +# else + __cxx_atomic_base_impl() _NOEXCEPT : __a_value() { + } +# endif // _LIBCPP_CXX03_LANG + _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT : __a_value(__value) {} _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value; }; -#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) +# define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) -_LIBCPP_HIDE_FROM_ABI inline -void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT { - __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order)); +_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT { + __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order)); } -_LIBCPP_HIDE_FROM_ABI inline -void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT { - __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order)); +_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT { + __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT { - __c11_atomic_init(std::addressof(__a->__a_value), __val); +template +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT { + __c11_atomic_init(std::addressof(__a->__a_value), __val); } -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT { - __c11_atomic_init(std::addressof(__a->__a_value), __val); +template +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) _NOEXCEPT { + __c11_atomic_init(std::addressof(__a->__a_value), __val); } -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT { - __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT { + __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT { - __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) _NOEXCEPT { + __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT { - using __ptr_type = __remove_const_t__a_value)>*; - return __c11_atomic_load( - const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT { + using __ptr_type = __remove_const_t__a_value)>*; + return __c11_atomic_load( + const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT { - using __ptr_type = __remove_const_t__a_value)>*; - return __c11_atomic_load( - const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT { + using __ptr_type = __remove_const_t__a_value)>*; + return __c11_atomic_load( + const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); } template _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const volatile* __a, _Tp* __dst, memory_order __order) _NOEXCEPT { - using __ptr_type = __remove_const_t__a_value)>*; - *__dst = __c11_atomic_load( - const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); + using __ptr_type = __remove_const_t__a_value)>*; + *__dst = __c11_atomic_load( + const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); } template _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const* __a, _Tp* __dst, memory_order __order) _NOEXCEPT { - using __ptr_type = __remove_const_t__a_value)>*; - *__dst = __c11_atomic_load( - const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); + using __ptr_type = __remove_const_t__a_value)>*; + *__dst = __c11_atomic_load( + const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT { - return __c11_atomic_exchange( - std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT { + return __c11_atomic_exchange( + std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT { - return __c11_atomic_exchange( - std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) _NOEXCEPT { + return __c11_atomic_exchange( + std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order)); } _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) { // Avoid switch statement to make this a constexpr. - return __order == memory_order_release ? memory_order_relaxed: - (__order == memory_order_acq_rel ? memory_order_acquire: - __order); + return __order == memory_order_release + ? memory_order_relaxed + : (__order == memory_order_acq_rel ? memory_order_acquire : __order); } -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + __cxx_atomic_base_impl<_Tp> volatile* __a, + _Tp* __expected, + _Tp __value, + memory_order __success, + memory_order __failure) _NOEXCEPT { return __c11_atomic_compare_exchange_strong( std::addressof(__a->__a_value), __expected, @@ -419,9 +399,10 @@ bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); } -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) + _NOEXCEPT { return __c11_atomic_compare_exchange_strong( std::addressof(__a->__a_value), __expected, @@ -430,9 +411,13 @@ bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); } -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + __cxx_atomic_base_impl<_Tp> volatile* __a, + _Tp* __expected, + _Tp __value, + memory_order __success, + memory_order __failure) _NOEXCEPT { return __c11_atomic_compare_exchange_weak( std::addressof(__a->__a_value), __expected, @@ -440,9 +425,10 @@ bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __ static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); } -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) + _NOEXCEPT { return __c11_atomic_compare_exchange_weak( std::addressof(__a->__a_value), __expected, @@ -451,92 +437,92 @@ bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_add( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_add( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp* +__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_add( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp* +__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_add( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_sub( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_sub( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp* +__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_sub( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp* +__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_sub( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_and( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_and( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_or( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_or( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_xor( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_xor( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } @@ -545,26 +531,23 @@ _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, mem #ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS -template +template struct __cxx_atomic_lock_impl { - - _LIBCPP_HIDE_FROM_ABI - __cxx_atomic_lock_impl() _NOEXCEPT - : __a_value(), __a_lock(0) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit - __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT - : __a_value(value), __a_lock(0) {} + _LIBCPP_HIDE_FROM_ABI __cxx_atomic_lock_impl() _NOEXCEPT : __a_value(), __a_lock(0) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT + : __a_value(value), + __a_lock(0) {} _Tp __a_value; mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock; _LIBCPP_HIDE_FROM_ABI void __lock() const volatile { - while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) - /*spin*/; + while (1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) + /*spin*/; } _LIBCPP_HIDE_FROM_ABI void __lock() const { - while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) - /*spin*/; + while (1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) + /*spin*/; } _LIBCPP_HIDE_FROM_ABI void __unlock() const volatile { __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); @@ -598,39 +581,33 @@ struct __cxx_atomic_lock_impl { }; template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { __cxx_atomic_assign_volatile(__a->__a_value, __val); } template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { __a->__a_value = __val; } template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { __a->__lock(); __cxx_atomic_assign_volatile(__a->__a_value, __val); __a->__unlock(); } template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { __a->__lock(); __a->__a_value = __val; __a->__unlock(); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { return __a->__read(); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { return __a->__read(); } @@ -645,8 +622,7 @@ _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { __a->__lock(); _Tp __old; __cxx_atomic_assign_volatile(__old, __a->__a_value); @@ -655,24 +631,22 @@ _Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value return __old; } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { __a->__lock(); - _Tp __old = __a->__a_value; + _Tp __old = __a->__a_value; __a->__a_value = __value; __a->__unlock(); return __old; } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Tp* __expected, _Tp __value, memory_order, memory_order) { +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order, memory_order) { _Tp __temp; __a->__lock(); __cxx_atomic_assign_volatile(__temp, __a->__a_value); bool __ret = (std::memcmp(&__temp, __expected, sizeof(_Tp)) == 0); - if(__ret) + if (__ret) __cxx_atomic_assign_volatile(__a->__a_value, __value); else __cxx_atomic_assign_volatile(*__expected, __a->__a_value); @@ -680,12 +654,11 @@ bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* return __ret; } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a, - _Tp* __expected, _Tp __value, memory_order, memory_order) { +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + __cxx_atomic_lock_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order, memory_order) { __a->__lock(); bool __ret = (std::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0); - if(__ret) + if (__ret) std::memcpy(&__a->__a_value, &__value, sizeof(_Tp)); else std::memcpy(__expected, &__a->__a_value, sizeof(_Tp)); @@ -694,14 +667,13 @@ bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a, } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Tp* __expected, _Tp __value, memory_order, memory_order) { +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order, memory_order) { _Tp __temp; __a->__lock(); __cxx_atomic_assign_volatile(__temp, __a->__a_value); bool __ret = (std::memcmp(&__temp, __expected, sizeof(_Tp)) == 0); - if(__ret) + if (__ret) __cxx_atomic_assign_volatile(__a->__a_value, __value); else __cxx_atomic_assign_volatile(*__expected, __a->__a_value); @@ -709,12 +681,11 @@ bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __ return __ret; } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a, - _Tp* __expected, _Tp __value, memory_order, memory_order) { +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + __cxx_atomic_lock_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order, memory_order) { __a->__lock(); bool __ret = (std::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0); - if(__ret) + if (__ret) std::memcpy(&__a->__a_value, &__value, sizeof(_Tp)); else std::memcpy(__expected, &__a->__a_value, sizeof(_Tp)); @@ -723,9 +694,7 @@ bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a, } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Td __delta, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Td __delta, memory_order) { __a->__lock(); _Tp __old; __cxx_atomic_assign_volatile(__old, __a->__a_value); @@ -734,9 +703,7 @@ _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a, return __old; } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a, - _Td __delta, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a, _Td __delta, memory_order) { __a->__lock(); _Tp __old = __a->__a_value; __a->__a_value += __delta; @@ -745,9 +712,8 @@ _Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a, } template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a, - ptrdiff_t __delta, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp* +__cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order) { __a->__lock(); _Tp* __old; __cxx_atomic_assign_volatile(__old, __a->__a_value); @@ -756,9 +722,7 @@ _Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a, return __old; } template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a, - ptrdiff_t __delta, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order) { __a->__lock(); _Tp* __old = __a->__a_value; __a->__a_value += __delta; @@ -767,9 +731,7 @@ _Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a, } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Td __delta, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Td __delta, memory_order) { __a->__lock(); _Tp __old; __cxx_atomic_assign_volatile(__old, __a->__a_value); @@ -778,9 +740,7 @@ _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a, return __old; } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a, - _Td __delta, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a, _Td __delta, memory_order) { __a->__lock(); _Tp __old = __a->__a_value; __a->__a_value -= __delta; @@ -789,9 +749,8 @@ _Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a, } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __pattern, memory_order) { __a->__lock(); _Tp __old; __cxx_atomic_assign_volatile(__old, __a->__a_value); @@ -800,9 +759,7 @@ _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a, return __old; } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __pattern, memory_order) { __a->__lock(); _Tp __old = __a->__a_value; __a->__a_value &= __pattern; @@ -811,9 +768,8 @@ _Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a, } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __pattern, memory_order) { __a->__lock(); _Tp __old; __cxx_atomic_assign_volatile(__old, __a->__a_value); @@ -822,9 +778,7 @@ _Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a, return __old; } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __pattern, memory_order) { __a->__lock(); _Tp __old = __a->__a_value; __a->__a_value |= __pattern; @@ -833,9 +787,8 @@ _Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a, } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __pattern, memory_order) { __a->__lock(); _Tp __old; __cxx_atomic_assign_volatile(__old, __a->__a_value); @@ -844,9 +797,7 @@ _Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a, return __old; } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __pattern, memory_order) { __a->__lock(); _Tp __old = __a->__a_value; __a->__a_value ^= __pattern; @@ -859,16 +810,13 @@ template , __cxx_atomic_lock_impl<_Tp> >::type> #else -template > +template > #endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS struct __cxx_atomic_impl : public _Base { - static_assert(is_trivially_copyable<_Tp>::value, - "std::atomic requires that 'T' be a trivially copyable type"); + static_assert(is_trivially_copyable<_Tp>::value, "std::atomic requires that 'T' be a trivially copyable type"); _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT - : _Base(__value) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {} }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__atomic/fence.h b/libcxx/include/__atomic/fence.h index c62f38f21157b6f9494af04c988ceef5728ec329..8c27ea54d62dd0333c8585db856034fbed39cabc 100644 --- a/libcxx/include/__atomic/fence.h +++ b/libcxx/include/__atomic/fence.h @@ -19,19 +19,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_thread_fence(memory_order __m) _NOEXCEPT -{ - __cxx_atomic_thread_fence(__m); -} - -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_signal_fence(memory_order __m) _NOEXCEPT -{ - __cxx_atomic_signal_fence(__m); -} +inline _LIBCPP_HIDE_FROM_ABI void atomic_thread_fence(memory_order __m) _NOEXCEPT { __cxx_atomic_thread_fence(__m); } + +inline _LIBCPP_HIDE_FROM_ABI void atomic_signal_fence(memory_order __m) _NOEXCEPT { __cxx_atomic_signal_fence(__m); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__atomic/kill_dependency.h b/libcxx/include/__atomic/kill_dependency.h index 1bd5c8ca765a7fd2f677d89beab1d58d14e4aad1..103d52d35787fefb9d0f8701789fd6d467979074 100644 --- a/libcxx/include/__atomic/kill_dependency.h +++ b/libcxx/include/__atomic/kill_dependency.h @@ -18,10 +18,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI -_Tp kill_dependency(_Tp __y) _NOEXCEPT -{ - return __y; +_LIBCPP_HIDE_FROM_ABI _Tp kill_dependency(_Tp __y) _NOEXCEPT { + return __y; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__atomic/memory_order.h b/libcxx/include/__atomic/memory_order.h index 3671dc3cf9be03a2dcabc0e087b9dae1fb315fc9..16fd1867698faa1b76eda475a01ffb391285fbd1 100644 --- a/libcxx/include/__atomic/memory_order.h +++ b/libcxx/include/__atomic/memory_order.h @@ -22,14 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // Figure out what the underlying type for `memory_order` would be if it were // declared as an unscoped enum (accounting for -fshort-enums). Use this result // to pin the underlying type in C++20. -enum __legacy_memory_order { - __mo_relaxed, - __mo_consume, - __mo_acquire, - __mo_release, - __mo_acq_rel, - __mo_seq_cst -}; +enum __legacy_memory_order { __mo_relaxed, __mo_consume, __mo_acquire, __mo_release, __mo_acq_rel, __mo_seq_cst }; using __memory_order_underlying_t = underlying_type<__legacy_memory_order>::type; @@ -45,7 +38,7 @@ enum class memory_order : __memory_order_underlying_t { }; static_assert((is_same::type, __memory_order_underlying_t>::value), - "unexpected underlying type for std::memory_order"); + "unexpected underlying type for std::memory_order"); inline constexpr auto memory_order_relaxed = memory_order::relaxed; inline constexpr auto memory_order_consume = memory_order::consume; diff --git a/libcxx/include/__availability b/libcxx/include/__availability index b5230b3f56b8d81cf78f363de2e43ec9525cba81..e9904275e73414219ad6f3c2f0837a638d191616 100644 --- a/libcxx/include/__availability +++ b/libcxx/include/__availability @@ -64,25 +64,22 @@ // // [1]: https://clang.llvm.org/docs/AttributeReference.html#availability - // For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY // for a while. #if defined(_LIBCPP_DISABLE_AVAILABILITY) -# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) -# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS -# endif +# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +# endif #endif // Availability markup is disabled when building the library, or when the compiler // doesn't support the proper attributes. -#if defined(_LIBCPP_BUILDING_LIBRARY) || \ - defined(_LIBCXXABI_BUILDING_LIBRARY) || \ - !__has_feature(attribute_availability_with_strict) || \ - !__has_feature(attribute_availability_in_templates) || \ +#if defined(_LIBCPP_BUILDING_LIBRARY) || defined(_LIBCXXABI_BUILDING_LIBRARY) || \ + !__has_feature(attribute_availability_with_strict) || !__has_feature(attribute_availability_in_templates) || \ !__has_extension(pragma_clang_attribute_external_declaration) -# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) -# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS -# endif +# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +# endif #endif #if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) @@ -160,7 +157,7 @@ # define _LIBCPP_AVAILABILITY_HAS_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_HAS_BAD_ANY_CAST _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((availability(watchos,strict,introduced=5.0))) +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((availability(watchos, strict, introduced = 5.0))) # define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS @@ -175,11 +172,11 @@ # else # define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY 1 # endif -# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY \ - __attribute__((availability(macos,strict,introduced=10.15))) \ - __attribute__((availability(ios,strict,introduced=13.0))) \ - __attribute__((availability(tvos,strict,introduced=13.0))) \ - __attribute__((availability(watchos,strict,introduced=6.0))) +# define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY \ + __attribute__((availability(macos, strict, introduced = 10.15))) \ + __attribute__((availability(ios, strict, introduced = 13.0))) \ + __attribute__((availability(tvos, strict, introduced = 13.0))) \ + __attribute__((availability(watchos, strict, introduced = 6.0))) // clang-format off # define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH \ _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \ @@ -204,13 +201,13 @@ # else # define _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT 1 # endif -# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \ - __attribute__((availability(macos,strict,introduced=13.3))) \ - __attribute__((availability(ios,strict,introduced=16.3))) \ - __attribute__((availability(tvos,strict,introduced=16.3))) \ - __attribute__((availability(watchos,strict,introduced=9.3))) +# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \ + __attribute__((availability(macos, strict, introduced = 13.3))) \ + __attribute__((availability(ios, strict, introduced = 16.3))) \ + __attribute__((availability(tvos, strict, introduced = 16.3))) \ + __attribute__((availability(watchos, strict, introduced = 9.3))) - // c++20 synchronization library +// c++20 synchronization library // clang-format off # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \ @@ -220,19 +217,18 @@ # define _LIBCPP_AVAILABILITY_HAS_SYNC 0 # else # define _LIBCPP_AVAILABILITY_HAS_SYNC 1 -# endif -# define _LIBCPP_AVAILABILITY_SYNC \ - __attribute__((availability(macos,strict,introduced=11.0))) \ - __attribute__((availability(ios,strict,introduced=14.0))) \ - __attribute__((availability(tvos,strict,introduced=14.0))) \ - __attribute__((availability(watchos,strict,introduced=7.0))) +# endif +# define _LIBCPP_AVAILABILITY_SYNC \ + __attribute__((availability(macos, strict, introduced = 11.0))) \ + __attribute__((availability(ios, strict, introduced = 14.0))) \ + __attribute__((availability(tvos, strict, introduced = 14.0))) \ + __attribute__((availability(watchos, strict, introduced = 7.0))) // __libcpp_verbose_abort // TODO: Update once this is released # define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT 0 -# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT \ - __attribute__((unavailable)) +# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT __attribute__((unavailable)) // std::pmr // clang-format off @@ -276,7 +272,8 @@ // ...New vendors can add availability markup here... -# error "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!" +# error \ + "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!" #endif @@ -284,13 +281,13 @@ // Those are defined in terms of the availability attributes above, and // should not be vendor-specific. #if defined(_LIBCPP_HAS_NO_EXCEPTIONS) -# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS #else -# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS #endif #endif // _LIBCPP___AVAILABILITY diff --git a/libcxx/include/__bit/bit_cast.h b/libcxx/include/__bit/bit_cast.h index 39842465e12a494426fd5d1d0278f0cfe759b699..f20b39ae748b101d6f6ac935fd1974a9113db863 100644 --- a/libcxx/include/__bit/bit_cast.h +++ b/libcxx/include/__bit/bit_cast.h @@ -22,8 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template - requires(sizeof(_ToType) == sizeof(_FromType) && - is_trivially_copyable_v<_ToType> && + requires(sizeof(_ToType) == sizeof(_FromType) && is_trivially_copyable_v<_ToType> && is_trivially_copyable_v<_FromType>) _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept { return __builtin_bit_cast(_ToType, __from); diff --git a/libcxx/include/__bit/bit_ceil.h b/libcxx/include/__bit/bit_ceil.h index 9eae5c391a835f93cccf1b8725d80f0b6a65838b..17fe06aa41ccd870a3659d5a26f4bccbdd82ae77 100644 --- a/libcxx/include/__bit/bit_ceil.h +++ b/libcxx/include/__bit/bit_ceil.h @@ -33,7 +33,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_ceil(_Tp __t) no if constexpr (sizeof(_Tp) >= sizeof(unsigned)) return _Tp{1} << __n; else { - const unsigned __extra = numeric_limits::digits - numeric_limits<_Tp>::digits; + const unsigned __extra = numeric_limits::digits - numeric_limits<_Tp>::digits; const unsigned __ret_val = 1u << (__n + __extra); return (_Tp)(__ret_val >> __extra); } diff --git a/libcxx/include/__bit/byteswap.h b/libcxx/include/__bit/byteswap.h index a1e1b530975e3dbc83cfd56d1104826e2644d561..20045d6fd43cb57a1e41f1a0356b5067f3d38cdd 100644 --- a/libcxx/include/__bit/byteswap.h +++ b/libcxx/include/__bit/byteswap.h @@ -24,7 +24,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { - if constexpr (sizeof(_Tp) == 1) { return __val; } else if constexpr (sizeof(_Tp) == 2) { @@ -33,15 +32,15 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) no return __builtin_bswap32(__val); } else if constexpr (sizeof(_Tp) == 8) { return __builtin_bswap64(__val); -#ifndef _LIBCPP_HAS_NO_INT128 +# ifndef _LIBCPP_HAS_NO_INT128 } else if constexpr (sizeof(_Tp) == 16) { -#if __has_builtin(__builtin_bswap128) +# if __has_builtin(__builtin_bswap128) return __builtin_bswap128(__val); -#else +# else return static_cast<_Tp>(byteswap(static_cast(__val))) << 64 | static_cast<_Tp>(byteswap(static_cast(__val >> 64))); -#endif // __has_builtin(__builtin_bswap128) -#endif // _LIBCPP_HAS_NO_INT128 +# endif // __has_builtin(__builtin_bswap128) +# endif // _LIBCPP_HAS_NO_INT128 } else { static_assert(sizeof(_Tp) == 0, "byteswap is unimplemented for integral types of this size"); } diff --git a/libcxx/include/__bit/countl.h b/libcxx/include/__bit/countl.h index efc9e200b13a8a570ba73f0d7ae8319c40cece4c..396cfc2c3f4064fca7a2c2e69c56a1d10e5a9137 100644 --- a/libcxx/include/__bit/countl.h +++ b/libcxx/include/__bit/countl.h @@ -24,18 +24,20 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -int __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(unsigned __x) _NOEXCEPT { + return __builtin_clz(__x); +} -_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(unsigned long __x) _NOEXCEPT { + return __builtin_clzl(__x); +} -_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(unsigned long long __x) _NOEXCEPT { + return __builtin_clzll(__x); +} -# ifndef _LIBCPP_HAS_NO_INT128 -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -int __libcpp_clz(__uint128_t __x) _NOEXCEPT { +#ifndef _LIBCPP_HAS_NO_INT128 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(__uint128_t __x) _NOEXCEPT { // The function is written in this form due to C++ constexpr limitations. // The algorithm: // - Test whether any bit in the high 64-bits is set @@ -45,42 +47,38 @@ int __libcpp_clz(__uint128_t __x) _NOEXCEPT { // - Any bits set: // - The number of leading zeros of the input is the number of leading // zeros in the high 64-bits. - return ((__x >> 64) == 0) - ? (64 + __builtin_clzll(static_cast(__x))) - : __builtin_clzll(static_cast(__x >> 64)); + return ((__x >> 64) == 0) ? (64 + __builtin_clzll(static_cast(__x))) + : __builtin_clzll(static_cast(__x >> 64)); } -# endif // _LIBCPP_HAS_NO_INT128 - -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -int __countl_zero(_Tp __t) _NOEXCEPT -{ - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type"); - if (__t == 0) - return numeric_limits<_Tp>::digits; - - if (sizeof(_Tp) <= sizeof(unsigned int)) - return std::__libcpp_clz(static_cast(__t)) - - (numeric_limits::digits - numeric_limits<_Tp>::digits); - else if (sizeof(_Tp) <= sizeof(unsigned long)) - return std::__libcpp_clz(static_cast(__t)) - - (numeric_limits::digits - numeric_limits<_Tp>::digits); - else if (sizeof(_Tp) <= sizeof(unsigned long long)) - return std::__libcpp_clz(static_cast(__t)) - - (numeric_limits::digits - numeric_limits<_Tp>::digits); - else - { - int __ret = 0; - int __iter = 0; - const unsigned int __ulldigits = numeric_limits::digits; - while (true) { - __t = std::__rotl(__t, __ulldigits); - if ((__iter = std::__countl_zero(static_cast(__t))) != __ulldigits) - break; - __ret += __iter; - } - return __ret + __iter; +#endif // _LIBCPP_HAS_NO_INT128 + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _NOEXCEPT { + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type"); + if (__t == 0) + return numeric_limits<_Tp>::digits; + + if (sizeof(_Tp) <= sizeof(unsigned int)) + return std::__libcpp_clz(static_cast(__t)) - + (numeric_limits::digits - numeric_limits<_Tp>::digits); + else if (sizeof(_Tp) <= sizeof(unsigned long)) + return std::__libcpp_clz(static_cast(__t)) - + (numeric_limits::digits - numeric_limits<_Tp>::digits); + else if (sizeof(_Tp) <= sizeof(unsigned long long)) + return std::__libcpp_clz(static_cast(__t)) - + (numeric_limits::digits - numeric_limits<_Tp>::digits); + else { + int __ret = 0; + int __iter = 0; + const unsigned int __ulldigits = numeric_limits::digits; + while (true) { + __t = std::__rotl(__t, __ulldigits); + if ((__iter = std::__countl_zero(static_cast(__t))) != __ulldigits) + break; + __ret += __iter; } + return __ret + __iter; + } } #if _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__bit/countr.h b/libcxx/include/__bit/countr.h index 66ca5e7e66f2b0d95ab84ff7348e03931cdb87f1..0cc679f87a99d9754ce2f115d6cc5cd9d7bedef8 100644 --- a/libcxx/include/__bit/countr.h +++ b/libcxx/include/__bit/countr.h @@ -23,14 +23,17 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -int __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz(unsigned __x) _NOEXCEPT { + return __builtin_ctz(__x); +} -_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -int __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz(unsigned long __x) _NOEXCEPT { + return __builtin_ctzl(__x); +} -_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { + return __builtin_ctzll(__x); +} #if _LIBCPP_STD_VER >= 20 @@ -46,7 +49,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) n else if (sizeof(_Tp) <= sizeof(unsigned long long)) return std::__libcpp_ctz(static_cast(__t)); else { - int __ret = 0; + int __ret = 0; const unsigned int __ulldigits = numeric_limits::digits; while (static_cast(__t) == 0uLL) { __ret += __ulldigits; diff --git a/libcxx/include/__bit/endian.h b/libcxx/include/__bit/endian.h index 52635f2d249500da1157bd436f3b99ec4b74e748..2d31e5ddff4f1ff1da770967a81ee2066e8f0a19 100644 --- a/libcxx/include/__bit/endian.h +++ b/libcxx/include/__bit/endian.h @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD enum class endian { little = 0xDEAD, - big = 0xFACE, + big = 0xFACE, # if defined(_LIBCPP_LITTLE_ENDIAN) native = little # elif defined(_LIBCPP_BIG_ENDIAN) diff --git a/libcxx/include/__bit/popcount.h b/libcxx/include/__bit/popcount.h index f0bb87ea717ee8968721de52e37ddb03a705c021..b0319cef251894c4de6739dfdc4a96f31d517df7 100644 --- a/libcxx/include/__bit/popcount.h +++ b/libcxx/include/__bit/popcount.h @@ -23,14 +23,17 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -int __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_popcount(unsigned __x) _NOEXCEPT { + return __builtin_popcount(__x); +} -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -int __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_popcount(unsigned long __x) _NOEXCEPT { + return __builtin_popcountl(__x); +} -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { + return __builtin_popcountll(__x); +} #if _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/calendar.h b/libcxx/include/__chrono/calendar.h index 91aaf63253890b15d073fe8378528b5f8c1f4246..bb1c5e7ebc8d0bc794bfc18eb3f2324317ab567d 100644 --- a/libcxx/include/__chrono/calendar.h +++ b/libcxx/include/__chrono/calendar.h @@ -22,19 +22,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { struct local_t {}; -template -using local_time = time_point; +template +using local_time = time_point; using local_seconds = local_time; using local_days = local_time; -struct last_spec { explicit last_spec() = default; }; +struct last_spec { + explicit last_spec() = default; +}; inline constexpr last_spec last{}; - } // namespace chrono _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__chrono/convert_to_timespec.h b/libcxx/include/__chrono/convert_to_timespec.h index fab07f2567d46b2c161382f2a908eea760b8faf4..11e0b826d05b4c95124c28d6e2f609b6f9ffad86 100644 --- a/libcxx/include/__chrono/convert_to_timespec.h +++ b/libcxx/include/__chrono/convert_to_timespec.h @@ -26,23 +26,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD // Convert a nanoseconds duration to the given TimeSpec type, which must have // the same properties as std::timespec. template -_LIBCPP_HIDE_FROM_ABI inline -_TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns) -{ +_LIBCPP_HIDE_FROM_ABI inline _TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns) { using namespace chrono; seconds __s = duration_cast(__ns); _TimeSpec __ts; typedef decltype(__ts.tv_sec) __ts_sec; const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); - if (__s.count() < __ts_sec_max) - { - __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + if (__s.count() < __ts_sec_max) { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); __ts.tv_nsec = static_cast((__ns - __s).count()); - } - else - { - __ts.tv_sec = __ts_sec_max; + } else { + __ts.tv_sec = __ts_sec_max; __ts.tv_nsec = 999999999; // (10^9 - 1) } diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h index c907c036c146ad08e52f7ac461ca32de7be280ce..7342084b08c8865a095e29396ad1486773b39825 100644 --- a/libcxx/include/__chrono/day.h +++ b/libcxx/include/__chrono/day.h @@ -22,58 +22,73 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class day { private: - unsigned char __d_; + unsigned char __d_; + public: - day() = default; - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr day(unsigned __val) noexcept : __d_(static_cast(__val)) {} - _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator++() noexcept { ++__d_; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator--() noexcept { --__d_; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI constexpr day& operator+=(const days& __dd) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr day& operator-=(const days& __dd) noexcept; - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __d_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __d_ >= 1 && __d_ <= 31; } - }; - - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const day& __lhs, const day& __rhs) noexcept -{ return static_cast(__lhs) == static_cast(__rhs); } - -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const day& __lhs, const day& __rhs) noexcept { + day() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr day(unsigned __val) noexcept + : __d_(static_cast(__val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator++() noexcept { + ++__d_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr day operator++(int) noexcept { + day __tmp = *this; + ++(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator--() noexcept { + --__d_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr day operator--(int) noexcept { + day __tmp = *this; + --(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI constexpr day& operator+=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr day& operator-=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __d_ >= 1 && __d_ <= 31; } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const day& __lhs, const day& __rhs) noexcept { + return static_cast(__lhs) == static_cast(__rhs); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering operator<=>(const day& __lhs, const day& __rhs) noexcept { return static_cast(__lhs) <=> static_cast(__rhs); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -day operator+ (const day& __lhs, const days& __rhs) noexcept -{ return day(static_cast(__lhs) + __rhs.count()); } +_LIBCPP_HIDE_FROM_ABI inline constexpr day operator+(const day& __lhs, const days& __rhs) noexcept { + return day(static_cast(__lhs) + __rhs.count()); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -day operator+ (const days& __lhs, const day& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr day operator+(const days& __lhs, const day& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -day operator- (const day& __lhs, const days& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr day operator-(const day& __lhs, const days& __rhs) noexcept { + return __lhs + -__rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -days operator-(const day& __lhs, const day& __rhs) noexcept -{ return days(static_cast(static_cast(__lhs)) - - static_cast(static_cast(__rhs))); } +_LIBCPP_HIDE_FROM_ABI inline constexpr days operator-(const day& __lhs, const day& __rhs) noexcept { + return days(static_cast(static_cast(__lhs)) - static_cast(static_cast(__rhs))); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -day& day::operator+=(const days& __dd) noexcept -{ *this = *this + __dd; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator+=(const days& __dd) noexcept { + *this = *this + __dd; + return *this; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -day& day::operator-=(const days& __dd) noexcept -{ *this = *this - __dd; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) noexcept { + *this = *this - __dd; + return *this; +} } // namespace chrono diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h index a19d55fc6682983356726937b1454166c076f2bd..5693ee64409167ec0e69765e17fd03a25f00b372 100644 --- a/libcxx/include/__chrono/duration.h +++ b/libcxx/include/__chrono/duration.h @@ -29,100 +29,82 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { -template > class _LIBCPP_TEMPLATE_VIS duration; +template > +class _LIBCPP_TEMPLATE_VIS duration; template struct __is_duration : false_type {}; template -struct __is_duration > : true_type {}; +struct __is_duration > : true_type {}; template -struct __is_duration > : true_type {}; +struct __is_duration > : true_type {}; template -struct __is_duration > : true_type {}; +struct __is_duration > : true_type {}; template -struct __is_duration > : true_type {}; +struct __is_duration > : true_type {}; } // namespace chrono template -struct _LIBCPP_TEMPLATE_VIS common_type, - chrono::duration<_Rep2, _Period2> > -{ - typedef chrono::duration::type, - typename __ratio_gcd<_Period1, _Period2>::type> type; +struct _LIBCPP_TEMPLATE_VIS common_type, chrono::duration<_Rep2, _Period2> > { + typedef chrono::duration::type, typename __ratio_gcd<_Period1, _Period2>::type> + type; }; namespace chrono { // duration_cast -template ::type, - bool = _Period::num == 1, - bool = _Period::den == 1> + bool = _Period::num == 1, + bool = _Period::den == 1> struct __duration_cast; template -struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - return _ToDuration(static_cast(__fd.count())); - } +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const { + return _ToDuration(static_cast(__fd.count())); + } }; template -struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type::type _Ct; - return _ToDuration(static_cast( - static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); - } +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const { + typedef typename common_type::type _Ct; + return _ToDuration( + static_cast(static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); + } }; template -struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type::type _Ct; - return _ToDuration(static_cast( - static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); - } +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const { + typedef typename common_type::type _Ct; + return _ToDuration( + static_cast(static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); + } }; template -struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type::type _Ct; - return _ToDuration(static_cast( - static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) - / static_cast<_Ct>(_Period::den))); - } +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) / static_cast<_Ct>(_Period::den))); + } }; template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -_ToDuration -duration_cast(const duration<_Rep, _Period>& __fd) -{ - return __duration_cast, _ToDuration>()(__fd); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration duration_cast(const duration<_Rep, _Period>& __fd) { + return __duration_cast, _ToDuration>()(__fd); } template @@ -134,190 +116,204 @@ inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>: #endif template -struct _LIBCPP_TEMPLATE_VIS duration_values -{ +struct _LIBCPP_TEMPLATE_VIS duration_values { public: - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);} - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();} - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT { return _Rep(0); } + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT { return numeric_limits<_Rep>::max(); } + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT { return numeric_limits<_Rep>::lowest(); } }; #if _LIBCPP_STD_VER >= 17 template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -_ToDuration -floor(const duration<_Rep, _Period>& __d) -{ - _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); - if (__t > __d) - __t = __t - _ToDuration{1}; - return __t; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration floor(const duration<_Rep, _Period>& __d) { + _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); + if (__t > __d) + __t = __t - _ToDuration{1}; + return __t; } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -_ToDuration -ceil(const duration<_Rep, _Period>& __d) -{ - _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); - if (__t < __d) - __t = __t + _ToDuration{1}; - return __t; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration ceil(const duration<_Rep, _Period>& __d) { + _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); + if (__t < __d) + __t = __t + _ToDuration{1}; + return __t; } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -_ToDuration -round(const duration<_Rep, _Period>& __d) -{ - _ToDuration __lower = chrono::floor<_ToDuration>(__d); - _ToDuration __upper = __lower + _ToDuration{1}; - auto __lower_diff = __d - __lower; - auto __upper_diff = __upper - __d; - if (__lower_diff < __upper_diff) - return __lower; - if (__lower_diff > __upper_diff) - return __upper; - return __lower.count() & 1 ? __upper : __lower; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration round(const duration<_Rep, _Period>& __d) { + _ToDuration __lower = chrono::floor<_ToDuration>(__d); + _ToDuration __upper = __lower + _ToDuration{1}; + auto __lower_diff = __d - __lower; + auto __upper_diff = __upper - __d; + if (__lower_diff < __upper_diff) + return __lower; + if (__lower_diff > __upper_diff) + return __upper; + return __lower.count() & 1 ? __upper : __lower; } #endif // duration template -class _LIBCPP_TEMPLATE_VIS duration -{ - static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); - static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); - static_assert(_Period::num > 0, "duration period must be positive"); - - template - struct __no_overflow +class _LIBCPP_TEMPLATE_VIS duration { + static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); + static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); + static_assert(_Period::num > 0, "duration period must be positive"); + + template + struct __no_overflow { + private: + static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; + static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; + static const intmax_t __n1 = _R1::num / __gcd_n1_n2; + static const intmax_t __d1 = _R1::den / __gcd_d1_d2; + static const intmax_t __n2 = _R2::num / __gcd_n1_n2; + static const intmax_t __d2 = _R2::den / __gcd_d1_d2; + static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); + + template + struct __mul // __overflow == false { - private: - static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; - static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; - static const intmax_t __n1 = _R1::num / __gcd_n1_n2; - static const intmax_t __d1 = _R1::den / __gcd_d1_d2; - static const intmax_t __n2 = _R2::num / __gcd_n1_n2; - static const intmax_t __d2 = _R2::den / __gcd_d1_d2; - static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); - - template - struct __mul // __overflow == false - { - static const intmax_t value = _Xp * _Yp; - }; - - template - struct __mul<_Xp, _Yp, true> - { - static const intmax_t value = 1; - }; - - public: - static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); - typedef ratio<__mul<__n1, __d2, !value>::value, - __mul<__n2, __d1, !value>::value> type; + static const intmax_t value = _Xp * _Yp; + }; + + template + struct __mul<_Xp, _Yp, true> { + static const intmax_t value = 1; }; + public: + static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); + typedef ratio<__mul<__n1, __d2, !value>::value, __mul<__n2, __d1, !value>::value> type; + }; + public: - typedef _Rep rep; - typedef typename _Period::type period; + typedef _Rep rep; + typedef typename _Period::type period; + private: - rep __rep_; -public: + rep __rep_; +public: #ifndef _LIBCPP_CXX03_LANG - constexpr duration() = default; + constexpr duration() = default; #else - _LIBCPP_HIDE_FROM_ABI duration() {} + _LIBCPP_HIDE_FROM_ABI duration() {} #endif - template ::value && - (treat_as_floating_point::value || - !treat_as_floating_point<_Rep2>::value), int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - explicit duration(const _Rep2& __r) - : __rep_(__r) {} - - // conversions - template ::value && ( - treat_as_floating_point::value || - (__no_overflow<_Period2, period>::type::den == 1 && - !treat_as_floating_point<_Rep2>::value)), int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - duration(const duration<_Rep2, _Period2>& __d) - : __rep_(chrono::duration_cast(__d).count()) {} - - // observer - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR rep count() const {return __rep_;} - - // arithmetic - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type::type operator+() const {return typename common_type::type(*this);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type::type operator-() const {return typename common_type::type(-__rep_);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator++() {++__rep_; return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator++(int) {return duration(__rep_++);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator--() {--__rep_; return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator--(int) {return duration(__rep_--);} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator*=(const rep& __rhs) {__rep_ *= __rhs; return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator/=(const rep& __rhs) {__rep_ /= __rhs; return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const rep& __rhs) {__rep_ %= __rhs; return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const duration& __rhs) {__rep_ %= __rhs.count(); return *this;} - - // special values - - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values::zero());} - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values::min());} - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values::max());} + template ::value && + (treat_as_floating_point::value || !treat_as_floating_point<_Rep2>::value), + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit duration(const _Rep2& __r) : __rep_(__r) {} + + // conversions + template ::value && (treat_as_floating_point::value || + (__no_overflow<_Period2, period>::type::den == 1 && + !treat_as_floating_point<_Rep2>::value)), + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration(const duration<_Rep2, _Period2>& __d) + : __rep_(chrono::duration_cast(__d).count()) {} + + // observer + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR rep count() const { return __rep_; } + + // arithmetic + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type::type operator+() const { + return typename common_type::type(*this); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type::type operator-() const { + return typename common_type::type(-__rep_); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator++() { + ++__rep_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator++(int) { return duration(__rep_++); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator--() { + --__rep_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator--(int) { return duration(__rep_--); } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator+=(const duration& __d) { + __rep_ += __d.count(); + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator-=(const duration& __d) { + __rep_ -= __d.count(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator*=(const rep& __rhs) { + __rep_ *= __rhs; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator/=(const rep& __rhs) { + __rep_ /= __rhs; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const rep& __rhs) { + __rep_ %= __rhs; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const duration& __rhs) { + __rep_ %= __rhs.count(); + return *this; + } + + // special values + + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT { + return duration(duration_values::zero()); + } + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT { + return duration(duration_values::min()); + } + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT { + return duration(duration_values::max()); + } }; -typedef duration nanoseconds; -typedef duration microseconds; -typedef duration milliseconds; -typedef duration seconds; -typedef duration< long, ratio< 60> > minutes; -typedef duration< long, ratio<3600> > hours; +typedef duration nanoseconds; +typedef duration microseconds; +typedef duration milliseconds; +typedef duration seconds; +typedef duration< long, ratio< 60> > minutes; +typedef duration< long, ratio<3600> > hours; #if _LIBCPP_STD_VER >= 20 -typedef duration< int, ratio_multiply, hours::period>> days; -typedef duration< int, ratio_multiply, days::period>> weeks; -typedef duration< int, ratio_multiply, days::period>> years; -typedef duration< int, ratio_divide>> months; +typedef duration< int, ratio_multiply, hours::period>> days; +typedef duration< int, ratio_multiply, days::period>> weeks; +typedef duration< int, ratio_multiply, days::period>> years; +typedef duration< int, ratio_divide>> months; #endif // Duration == template -struct __duration_eq -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const - { - typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; - return _Ct(__lhs).count() == _Ct(__rhs).count(); - } +struct __duration_eq { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() == _Ct(__rhs).count(); + } }; template -struct __duration_eq<_LhsDuration, _LhsDuration> -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const - {return __lhs.count() == __rhs.count();} +struct __duration_eq<_LhsDuration, _LhsDuration> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const { + return __lhs.count() == __rhs.count(); + } }; template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -bool -operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __duration_eq, duration<_Rep2, _Period2> >()(__lhs, __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return __duration_eq, duration<_Rep2, _Period2> >()(__lhs, __rhs); } #if _LIBCPP_STD_VER <= 17 @@ -325,12 +321,9 @@ operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period // Duration != template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -bool -operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__lhs == __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return !(__lhs == __rhs); } #endif // _LIBCPP_STD_VER <= 17 @@ -338,76 +331,58 @@ operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period // Duration < template -struct __duration_lt -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const - { - typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; - return _Ct(__lhs).count() < _Ct(__rhs).count(); - } +struct __duration_lt { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() < _Ct(__rhs).count(); + } }; template -struct __duration_lt<_LhsDuration, _LhsDuration> -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const - {return __lhs.count() < __rhs.count();} +struct __duration_lt<_LhsDuration, _LhsDuration> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const { + return __lhs.count() < __rhs.count(); + } }; template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -bool -operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __duration_lt, duration<_Rep2, _Period2> >()(__lhs, __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator<(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return __duration_lt, duration<_Rep2, _Period2> >()(__lhs, __rhs); } // Duration > template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -bool -operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __rhs < __lhs; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return __rhs < __lhs; } // Duration <= template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -bool -operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__rhs < __lhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return !(__rhs < __lhs); } // Duration >= template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -bool -operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__lhs < __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return !(__lhs < __rhs); } #if _LIBCPP_STD_VER >= 20 -template +template requires three_way_comparable> -_LIBCPP_HIDE_FROM_ABI -constexpr auto operator<=>(const duration<_Rep1, _Period1>& __lhs, - const duration<_Rep2, _Period2>& __rhs) -{ - using _Ct = common_type_t, duration<_Rep2, _Period2>>; - return _Ct(__lhs).count() <=> _Ct(__rhs).count(); +_LIBCPP_HIDE_FROM_ABI constexpr auto +operator<=>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + using _Ct = common_type_t, duration<_Rep2, _Period2>>; + return _Ct(__lhs).count() <=> _Ct(__rhs).count(); } #endif // _LIBCPP_STD_VER >= 20 @@ -415,179 +390,151 @@ constexpr auto operator<=>(const duration<_Rep1, _Period1>& __lhs, // Duration + template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -typename common_type, duration<_Rep2, _Period2> >::type -operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR + typename common_type, duration<_Rep2, _Period2> >::type + operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); } // Duration - template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -typename common_type, duration<_Rep2, _Period2> >::type -operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR + typename common_type, duration<_Rep2, _Period2> >::type + operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); } // Duration * -template ::type>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -duration::type, _Period> -operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration::type, _Period> +operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); } -template ::type>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -duration::type, _Period> -operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) -{ - return __d * __s; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration::type, _Period> +operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) { + return __d * __s; } // Duration / -template ::value && is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -duration::type, _Period> -operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); +template ::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration::type, _Period> +operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); } template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -typename common_type<_Rep1, _Rep2>::type -operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type, duration<_Rep2, _Period2> >::type _Ct; - return _Ct(__lhs).count() / _Ct(__rhs).count(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<_Rep1, _Rep2>::type +operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef typename common_type, duration<_Rep2, _Period2> >::type _Ct; + return _Ct(__lhs).count() / _Ct(__rhs).count(); } // Duration % -template ::value && is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -duration::type, _Period> -operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); +template ::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration::type, _Period> +operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); } template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR -typename common_type, duration<_Rep2, _Period2> >::type -operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR + typename common_type, duration<_Rep2, _Period2> >::type + operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); } } // namespace chrono #if _LIBCPP_STD_VER >= 14 // Suffixes for duration literals [time.duration.literals] -inline namespace literals -{ - inline namespace chrono_literals - { - - _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h) - { - return chrono::hours(static_cast(__h)); - } - - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""h(long double __h) - { - return chrono::duration>(__h); - } - - - _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m) - { - return chrono::minutes(static_cast(__m)); - } - - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""min(long double __m) - { - return chrono::duration> (__m); - } +inline namespace literals { +inline namespace chrono_literals { +_LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h) { + return chrono::hours(static_cast(__h)); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s) - { - return chrono::seconds(static_cast(__s)); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""h(long double __h) { + return chrono::duration>(__h); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""s(long double __s) - { - return chrono::duration (__s); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m) { + return chrono::minutes(static_cast(__m)); +} +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""min(long double __m) { + return chrono::duration>(__m); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms) - { - return chrono::milliseconds(static_cast(__ms)); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s) { + return chrono::seconds(static_cast(__s)); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ms(long double __ms) - { - return chrono::duration(__ms); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""s(long double __s) { + return chrono::duration(__s); +} +_LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms) { + return chrono::milliseconds(static_cast(__ms)); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us) - { - return chrono::microseconds(static_cast(__us)); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ms(long double __ms) { + return chrono::duration(__ms); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""us(long double __us) - { - return chrono::duration (__us); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us) { + return chrono::microseconds(static_cast(__us)); +} +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""us(long double __us) { + return chrono::duration(__us); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) - { - return chrono::nanoseconds(static_cast(__ns)); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) { + return chrono::nanoseconds(static_cast(__ns)); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ns(long double __ns) - { - return chrono::duration (__ns); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ns(long double __ns) { + return chrono::duration(__ns); +} } // namespace chrono_literals } // namespace literals namespace chrono { // hoist the literals into namespace std::chrono - using namespace literals::chrono_literals; +using namespace literals::chrono_literals; } // namespace chrono #endif // _LIBCPP_STD_VER >= 14 diff --git a/libcxx/include/__chrono/file_clock.h b/libcxx/include/__chrono/file_clock.h index 9ea2fcb979355c1bbf54f931d06ce4753f91dde8..7d25729fec013aad42a574f77f89c234786e0468 100644 --- a/libcxx/include/__chrono/file_clock.h +++ b/libcxx/include/__chrono/file_clock.h @@ -31,13 +31,12 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { // [time.clock.file], type file_clock using file_clock = filesystem::_FilesystemClock; -template +template using file_time = time_point; } // namespace chrono @@ -49,35 +48,32 @@ _LIBCPP_END_NAMESPACE_STD #ifndef _LIBCPP_CXX03_LANG _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM struct _FilesystemClock { -#if !defined(_LIBCPP_HAS_NO_INT128) +# if !defined(_LIBCPP_HAS_NO_INT128) typedef __int128_t rep; typedef nano period; -#else +# else typedef long long rep; typedef nano period; -#endif +# endif typedef chrono::duration duration; typedef chrono::time_point<_FilesystemClock> time_point; - _LIBCPP_EXPORTED_FROM_ABI - static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; + _LIBCPP_EXPORTED_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept; -#if _LIBCPP_STD_VER >= 20 +# if _LIBCPP_STD_VER >= 20 template - _LIBCPP_HIDE_FROM_ABI - static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { + _LIBCPP_HIDE_FROM_ABI static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { return chrono::sys_time<_Duration>(__t.time_since_epoch()); } template - _LIBCPP_HIDE_FROM_ABI - static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { + _LIBCPP_HIDE_FROM_ABI static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { return chrono::file_time<_Duration>(__t.time_since_epoch()); } -#endif // _LIBCPP_STD_VER >= 20 +# endif // _LIBCPP_STD_VER >= 20 }; _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // !_LIBCPP_CXX03_LANG diff --git a/libcxx/include/__chrono/formatter.h b/libcxx/include/__chrono/formatter.h index 30ed360d4ef5058c14586e995e063d3446c38c7f..4ad59382a4148a226132f953d99c5ba99eb129cf 100644 --- a/libcxx/include/__chrono/formatter.h +++ b/libcxx/include/__chrono/formatter.h @@ -198,7 +198,8 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( if (__year < 1000 || __year > 9999) __formatter::__format_century(__year, __sstr); else - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); } break; case _CharT('j'): @@ -209,7 +210,8 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( // an intemediate step. __sstr << chrono::duration_cast(chrono::duration_cast(__value)).count(); else - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); break; case _CharT('q'): @@ -237,7 +239,8 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( case _CharT('S'): case _CharT('T'): - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); if constexpr (__use_fraction<_Tp>()) __formatter::__format_sub_seconds(__value, __sstr); break; @@ -289,7 +292,8 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( __formatter::__format_year(__year, __sstr); __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday); } else - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); } break; case _CharT('Z'): @@ -304,7 +308,8 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( // fractional part should be formatted. if (*(__it + 1) == 'S') { ++__it; - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); __formatter::__format_sub_seconds(__value, __sstr); break; } @@ -314,7 +319,8 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( ++__it; [[fallthrough]]; default: - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); break; } } else { @@ -634,8 +640,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -646,8 +651,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -658,8 +662,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -670,8 +673,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -682,8 +684,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -694,8 +695,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -706,8 +706,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -718,8 +717,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -730,8 +728,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -742,8 +739,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -754,8 +750,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -766,8 +761,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -778,8 +772,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -790,8 +783,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -802,8 +794,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; diff --git a/libcxx/include/__chrono/hh_mm_ss.h b/libcxx/include/__chrono/hh_mm_ss.h index 5bd452e57fa3c2175a022159c19bd1c362442c11..57d2247fe6a3c8c214603075b2f4c759725856d7 100644 --- a/libcxx/include/__chrono/hh_mm_ss.h +++ b/libcxx/include/__chrono/hh_mm_ss.h @@ -24,85 +24,84 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { template -class hh_mm_ss -{ +class hh_mm_ss { private: - static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); - using __CommonType = common_type_t<_Duration, chrono::seconds>; - - _LIBCPP_HIDE_FROM_ABI static constexpr uint64_t __pow10(unsigned __exp) - { - uint64_t __ret = 1; - for (unsigned __i = 0; __i < __exp; ++__i) - __ret *= 10U; - return __ret; - } - - _LIBCPP_HIDE_FROM_ABI static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) - { - if (__n >= 2 && __d != 0 && __w < 19) - return 1 + __width(__n, __d % __n * 10, __w+1); - return 0; - } + static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); + using __CommonType = common_type_t<_Duration, chrono::seconds>; + + _LIBCPP_HIDE_FROM_ABI static constexpr uint64_t __pow10(unsigned __exp) { + uint64_t __ret = 1; + for (unsigned __i = 0; __i < __exp; ++__i) + __ret *= 10U; + return __ret; + } + + _LIBCPP_HIDE_FROM_ABI static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) { + if (__n >= 2 && __d != 0 && __w < 19) + return 1 + __width(__n, __d % __n * 10, __w + 1); + return 0; + } public: - _LIBCPP_HIDE_FROM_ABI static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ? - __width(__CommonType::period::den) : 6u; - using precision = duration>; + _LIBCPP_HIDE_FROM_ABI static unsigned constexpr fractional_width = + __width(__CommonType::period::den) < 19 ? __width(__CommonType::period::den) : 6u; + using precision = duration>; - _LIBCPP_HIDE_FROM_ABI constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} + _LIBCPP_HIDE_FROM_ABI constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} - _LIBCPP_HIDE_FROM_ABI constexpr explicit hh_mm_ss(_Duration __d) noexcept : - __is_neg_(__d < _Duration(0)), - __h_(chrono::duration_cast (chrono::abs(__d))), + _LIBCPP_HIDE_FROM_ABI constexpr explicit hh_mm_ss(_Duration __d) noexcept + : __is_neg_(__d < _Duration(0)), + __h_(chrono::duration_cast(chrono::abs(__d))), __m_(chrono::duration_cast(chrono::abs(__d) - hours())), __s_(chrono::duration_cast(chrono::abs(__d) - hours() - minutes())), - __f_(chrono::duration_cast (chrono::abs(__d) - hours() - minutes() - seconds())) - {} + __f_(chrono::duration_cast(chrono::abs(__d) - hours() - minutes() - seconds())) {} - _LIBCPP_HIDE_FROM_ABI constexpr bool is_negative() const noexcept { return __is_neg_; } - _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours hours() const noexcept { return __h_; } - _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes minutes() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds seconds() const noexcept { return __s_; } - _LIBCPP_HIDE_FROM_ABI constexpr precision subseconds() const noexcept { return __f_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool is_negative() const noexcept { return __is_neg_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours hours() const noexcept { return __h_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes minutes() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds seconds() const noexcept { return __s_; } + _LIBCPP_HIDE_FROM_ABI constexpr precision subseconds() const noexcept { return __f_; } - _LIBCPP_HIDE_FROM_ABI constexpr precision to_duration() const noexcept - { - auto __dur = __h_ + __m_ + __s_ + __f_; - return __is_neg_ ? -__dur : __dur; - } + _LIBCPP_HIDE_FROM_ABI constexpr precision to_duration() const noexcept { + auto __dur = __h_ + __m_ + __s_ + __f_; + return __is_neg_ ? -__dur : __dur; + } - _LIBCPP_HIDE_FROM_ABI constexpr explicit operator precision() const noexcept { return to_duration(); } + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator precision() const noexcept { return to_duration(); } private: - bool __is_neg_; - chrono::hours __h_; - chrono::minutes __m_; - chrono::seconds __s_; - precision __f_; + bool __is_neg_; + chrono::hours __h_; + chrono::minutes __m_; + chrono::seconds __s_; + precision __f_; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(hh_mm_ss); -_LIBCPP_HIDE_FROM_ABI constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } -_LIBCPP_HIDE_FROM_ABI constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_am(const hours& __h) noexcept { + return __h >= hours(0) && __h < hours(12); +} +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_pm(const hours& __h) noexcept { + return __h >= hours(12) && __h < hours(24); +} -_LIBCPP_HIDE_FROM_ABI constexpr hours make12(const hours& __h) noexcept -{ - if (__h == hours( 0)) return hours(12); - else if (__h <= hours(12)) return __h; - else return __h - hours(12); +_LIBCPP_HIDE_FROM_ABI inline constexpr hours make12(const hours& __h) noexcept { + if (__h == hours(0)) + return hours(12); + else if (__h <= hours(12)) + return __h; + else + return __h - hours(12); } -_LIBCPP_HIDE_FROM_ABI constexpr hours make24(const hours& __h, bool __is_pm) noexcept -{ - if (__is_pm) - return __h == hours(12) ? __h : __h + hours(12); - else - return __h == hours(12) ? hours(0) : __h; +_LIBCPP_HIDE_FROM_ABI inline constexpr hours make24(const hours& __h, bool __is_pm) noexcept { + if (__is_pm) + return __h == hours(12) ? __h : __h + hours(12); + else + return __h == hours(12) ? hours(0) : __h; } } // namespace chrono diff --git a/libcxx/include/__chrono/high_resolution_clock.h b/libcxx/include/__chrono/high_resolution_clock.h index 778ff44f3d09b89279ce65fe5cdc341e1244f625..0697fd2de9b4de413d1f5980cadb43fc09f357dd 100644 --- a/libcxx/include/__chrono/high_resolution_clock.h +++ b/libcxx/include/__chrono/high_resolution_clock.h @@ -20,8 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { #ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK typedef steady_clock high_resolution_clock; diff --git a/libcxx/include/__chrono/literals.h b/libcxx/include/__chrono/literals.h index 28ddc43a2c0c606657ec9f2baf31e21f54db6443..89800440edf43522d9295c6d1754e57b4aa8c5e8 100644 --- a/libcxx/include/__chrono/literals.h +++ b/libcxx/include/__chrono/literals.h @@ -22,24 +22,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD -inline namespace literals -{ - inline namespace chrono_literals - { - _LIBCPP_HIDE_FROM_ABI constexpr chrono::day operator ""d(unsigned long long __d) noexcept - { - return chrono::day(static_cast(__d)); - } - - _LIBCPP_HIDE_FROM_ABI constexpr chrono::year operator ""y(unsigned long long __y) noexcept - { - return chrono::year(static_cast(__y)); - } +inline namespace literals { +inline namespace chrono_literals { +_LIBCPP_HIDE_FROM_ABI constexpr chrono::day operator""d(unsigned long long __d) noexcept { + return chrono::day(static_cast(__d)); +} + +_LIBCPP_HIDE_FROM_ABI constexpr chrono::year operator""y(unsigned long long __y) noexcept { + return chrono::year(static_cast(__y)); +} } // namespace chrono_literals } // namespace literals namespace chrono { // hoist the literals into namespace std::chrono - using namespace literals::chrono_literals; +using namespace literals::chrono_literals; } // namespace chrono _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h index 7566e4ed29983f49f2d1a0fc1a02adff06dbfc67..ce5cc21aab7d1e07afcd2e34fb32678c0e532012 100644 --- a/libcxx/include/__chrono/month.h +++ b/libcxx/include/__chrono/month.h @@ -22,64 +22,76 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class month { private: - unsigned char __m_; + unsigned char __m_; + public: - month() = default; - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr month(unsigned __val) noexcept : __m_(static_cast(__val)) {} - _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { *this += months{1}; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { *this -= months{1}; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI constexpr month& operator+=(const months& __m1) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr month& operator-=(const months& __m1) noexcept; - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_ >= 1 && __m_ <= 12; } + month() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr month(unsigned __val) noexcept + : __m_(static_cast(__val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { + *this += months{1}; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr month operator++(int) noexcept { + month __tmp = *this; + ++(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { + *this -= months{1}; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr month operator--(int) noexcept { + month __tmp = *this; + --(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI constexpr month& operator+=(const months& __m1) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr month& operator-=(const months& __m1) noexcept; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_ >= 1 && __m_ <= 12; } }; +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const month& __lhs, const month& __rhs) noexcept { + return static_cast(__lhs) == static_cast(__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const month& __lhs, const month& __rhs) noexcept -{ return static_cast(__lhs) == static_cast(__rhs); } - -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const month& __lhs, const month& __rhs) noexcept { - return static_cast(__lhs) <=> static_cast(__rhs); +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering operator<=>(const month& __lhs, const month& __rhs) noexcept { + return static_cast(__lhs) <=> static_cast(__rhs); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -month operator+ (const month& __lhs, const months& __rhs) noexcept -{ - auto const __mu = static_cast(static_cast(__lhs)) + (__rhs.count() - 1); - auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; - return month{static_cast(__mu - __yr * 12 + 1)}; +_LIBCPP_HIDE_FROM_ABI inline constexpr month operator+(const month& __lhs, const months& __rhs) noexcept { + auto const __mu = static_cast(static_cast(__lhs)) + (__rhs.count() - 1); + auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; + return month{static_cast(__mu - __yr * 12 + 1)}; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -month operator+ (const months& __lhs, const month& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month operator+(const months& __lhs, const month& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month operator- (const month& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month operator-(const month& __lhs, const months& __rhs) noexcept { + return __lhs + -__rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -months operator-(const month& __lhs, const month& __rhs) noexcept -{ - auto const __dm = static_cast(__lhs) - static_cast(__rhs); - return months(__dm <= 11 ? __dm : __dm + 12); +_LIBCPP_HIDE_FROM_ABI inline constexpr months operator-(const month& __lhs, const month& __rhs) noexcept { + auto const __dm = static_cast(__lhs) - static_cast(__rhs); + return months(__dm <= 11 ? __dm : __dm + 12); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -month& month::operator+=(const months& __dm) noexcept -{ *this = *this + __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month& month::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month& month::operator-=(const months& __dm) noexcept -{ *this = *this - __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month& month::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} inline constexpr month January{1}; inline constexpr month February{2}; diff --git a/libcxx/include/__chrono/month_weekday.h b/libcxx/include/__chrono/month_weekday.h index eb9e42d01f853a9b779f643b1c6731c6093fa390..79198796552148d45ee931bbb6a81f53227d4aa3 100644 --- a/libcxx/include/__chrono/month_weekday.h +++ b/libcxx/include/__chrono/month_weekday.h @@ -22,72 +22,80 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class month_weekday { private: - chrono::month __m_; - chrono::weekday_indexed __wdi_; + chrono::month __m_; + chrono::weekday_indexed __wdi_; + public: - _LIBCPP_HIDE_FROM_ABI constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept - : __m_{__mval}, __wdi_{__wdival} {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdi_.ok(); } + _LIBCPP_HIDE_FROM_ABI constexpr month_weekday(const chrono::month& __mval, + const chrono::weekday_indexed& __wdival) noexcept + : __m_{__mval}, __wdi_{__wdival} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdi_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept -{ return month_weekday{__lhs, __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept { + return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept -{ return month_weekday{month(__lhs), __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday +operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept { + return month_weekday{__lhs, __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept -{ return month_weekday{__rhs, __lhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept { + return month_weekday{month(__lhs), __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept -{ return month_weekday{month(__rhs), __lhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday +operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept { + return month_weekday{__rhs, __lhs}; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept { + return month_weekday{month(__rhs), __lhs}; +} class month_weekday_last { - chrono::month __m_; - chrono::weekday_last __wdl_; - public: - _LIBCPP_HIDE_FROM_ABI constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept - : __m_{__mval}, __wdl_{__wdlval} {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdl_.ok(); } + chrono::month __m_; + chrono::weekday_last __wdl_; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr month_weekday_last(const chrono::month& __mval, + const chrono::weekday_last& __wdlval) noexcept + : __m_{__mval}, __wdl_{__wdlval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdl_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept { + return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept -{ return month_weekday_last{__lhs, __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last +operator/(const month& __lhs, const weekday_last& __rhs) noexcept { + return month_weekday_last{__lhs, __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept -{ return month_weekday_last{month(__lhs), __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept { + return month_weekday_last{month(__lhs), __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept -{ return month_weekday_last{__rhs, __lhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last +operator/(const weekday_last& __lhs, const month& __rhs) noexcept { + return month_weekday_last{__rhs, __lhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept -{ return month_weekday_last{month(__rhs), __lhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept { + return month_weekday_last{month(__rhs), __lhs}; +} } // namespace chrono _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__chrono/monthday.h b/libcxx/include/__chrono/monthday.h index 03fd7503a6b435ce256b880905a196a2f9ba35be..a89d16e518618ef50aab094a6bc9b13e0421a50c 100644 --- a/libcxx/include/__chrono/monthday.h +++ b/libcxx/include/__chrono/monthday.h @@ -24,101 +24,105 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class month_day { private: - chrono::month __m_; - chrono::day __d_; + chrono::month __m_; + chrono::day __d_; + public: - month_day() = default; - _LIBCPP_HIDE_FROM_ABI constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept - : __m_{__mval}, __d_{__dval} {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } - _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; + month_day() = default; + _LIBCPP_HIDE_FROM_ABI constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept + : __m_{__mval}, __d_{__dval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool month_day::ok() const noexcept -{ - if (!__m_.ok()) return false; - const unsigned __dval = static_cast(__d_); - if (__dval < 1 || __dval > 31) return false; - if (__dval <= 29) return true; -// Now we've got either 30 or 31 - const unsigned __mval = static_cast(__m_); - if (__mval == 2) return false; - if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) - return __dval == 30; +_LIBCPP_HIDE_FROM_ABI inline constexpr bool month_day::ok() const noexcept { + if (!__m_.ok()) + return false; + const unsigned __dval = static_cast(__d_); + if (__dval < 1 || __dval > 31) + return false; + if (__dval <= 29) return true; + // Now we've got either 30 or 31 + const unsigned __mval = static_cast(__m_); + if (__mval == 2) + return false; + if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) + return __dval == 30; + return true; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept { + return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); +} -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const month_day& __lhs, const month_day& __rhs) noexcept { - if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) - return __c; - return __lhs.day() <=> __rhs.day(); +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering +operator<=>(const month_day& __lhs, const month_day& __rhs) noexcept { + if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) + return __c; + return __lhs.day() <=> __rhs.day(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day operator/(const month& __lhs, const day& __rhs) noexcept -{ return month_day{__lhs, __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day operator/(const month& __lhs, const day& __rhs) noexcept { + return month_day{__lhs, __rhs}; +} -_LIBCPP_HIDE_FROM_ABI constexpr -month_day operator/(const day& __lhs, const month& __rhs) noexcept -{ return __rhs / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day operator/(const day& __lhs, const month& __rhs) noexcept { + return __rhs / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day operator/(const month& __lhs, int __rhs) noexcept -{ return __lhs / day(__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day operator/(const month& __lhs, int __rhs) noexcept { + return __lhs / day(__rhs); +} -_LIBCPP_HIDE_FROM_ABI constexpr -month_day operator/(int __lhs, const day& __rhs) noexcept -{ return month(__lhs) / __rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day operator/(int __lhs, const day& __rhs) noexcept { + return month(__lhs) / __rhs; +} -_LIBCPP_HIDE_FROM_ABI constexpr -month_day operator/(const day& __lhs, int __rhs) noexcept -{ return month(__rhs) / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day operator/(const day& __lhs, int __rhs) noexcept { + return month(__rhs) / __lhs; +} class month_day_last { private: - chrono::month __m_; + chrono::month __m_; + public: - _LIBCPP_HIDE_FROM_ABI explicit constexpr month_day_last(const chrono::month& __val) noexcept - : __m_{__val} {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok(); } + _LIBCPP_HIDE_FROM_ABI explicit constexpr month_day_last(const chrono::month& __val) noexcept : __m_{__val} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return __lhs.month() == __rhs.month(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept { + return __lhs.month() == __rhs.month(); +} -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering operator<=>(const month_day_last& __lhs, const month_day_last& __rhs) noexcept { - return __lhs.month() <=> __rhs.month(); + return __lhs.month() <=> __rhs.month(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day_last operator/(const month& __lhs, last_spec) noexcept -{ return month_day_last{__lhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(const month& __lhs, last_spec) noexcept { + return month_day_last{__lhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day_last operator/(last_spec, const month& __rhs) noexcept -{ return month_day_last{__rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, const month& __rhs) noexcept { + return month_day_last{__rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day_last operator/(int __lhs, last_spec) noexcept -{ return month_day_last{month(__lhs)}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(int __lhs, last_spec) noexcept { + return month_day_last{month(__lhs)}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day_last operator/(last_spec, int __rhs) noexcept -{ return month_day_last{month(__rhs)}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int __rhs) noexcept { + return month_day_last{month(__rhs)}; +} } // namespace chrono diff --git a/libcxx/include/__chrono/steady_clock.h b/libcxx/include/__chrono/steady_clock.h index cdcd2fa0d9709cbe95922dc9196746ca0ee3c30a..612a7f156e6343d631c463fc76e29f5fff47bbb9 100644 --- a/libcxx/include/__chrono/steady_clock.h +++ b/libcxx/include/__chrono/steady_clock.h @@ -20,20 +20,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { #ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK -class _LIBCPP_EXPORTED_FROM_ABI steady_clock -{ +class _LIBCPP_EXPORTED_FROM_ABI steady_clock { public: - typedef nanoseconds duration; - typedef duration::rep rep; - typedef duration::period period; - typedef chrono::time_point time_point; - static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = true; + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = true; - static time_point now() _NOEXCEPT; + static time_point now() _NOEXCEPT; }; #endif diff --git a/libcxx/include/__chrono/system_clock.h b/libcxx/include/__chrono/system_clock.h index 06fe071df2b600ee99bfc05792f536585e6461f4..5a9eb65bdae7acc424b309ecfeb6d40233871889 100644 --- a/libcxx/include/__chrono/system_clock.h +++ b/libcxx/include/__chrono/system_clock.h @@ -21,21 +21,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { -class _LIBCPP_EXPORTED_FROM_ABI system_clock -{ +class _LIBCPP_EXPORTED_FROM_ABI system_clock { public: - typedef microseconds duration; - typedef duration::rep rep; - typedef duration::period period; - typedef chrono::time_point time_point; - static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; - - static time_point now() _NOEXCEPT; - static time_t to_time_t (const time_point& __t) _NOEXCEPT; - static time_point from_time_t(time_t __t) _NOEXCEPT; + typedef microseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; + + static time_point now() _NOEXCEPT; + static time_t to_time_t(const time_point& __t) _NOEXCEPT; + static time_point from_time_t(time_t __t) _NOEXCEPT; }; #if _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h index 5060d9b55539c1f600b0bbce1d6ae81f7106e736..e65253ddb98eea14796b4dfce325dac54315a9ae 100644 --- a/libcxx/include/__chrono/time_point.h +++ b/libcxx/include/__chrono/time_point.h @@ -28,108 +28,99 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { template -class _LIBCPP_TEMPLATE_VIS time_point -{ - static_assert(__is_duration<_Duration>::value, - "Second template parameter of time_point must be a std::chrono::duration"); +class _LIBCPP_TEMPLATE_VIS time_point { + static_assert(__is_duration<_Duration>::value, + "Second template parameter of time_point must be a std::chrono::duration"); + public: - typedef _Clock clock; - typedef _Duration duration; - typedef typename duration::rep rep; - typedef typename duration::period period; + typedef _Clock clock; + typedef _Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; + private: - duration __d_; + duration __d_; public: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point() : __d_(duration::zero()) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit time_point(const duration& __d) : __d_(__d) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point() : __d_(duration::zero()) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit time_point(const duration& __d) : __d_(__d) {} - // conversions - template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - time_point(const time_point& __t) - : __d_(__t.time_since_epoch()) {} + // conversions + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point(const time_point& __t) + : __d_(__t.time_since_epoch()) {} - // observer + // observer - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const {return __d_;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const { return __d_; } - // arithmetic + // arithmetic - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator+=(const duration& __d) { + __d_ += __d; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator-=(const duration& __d) { + __d_ -= __d; + return *this; + } - // special values + // special values - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());} - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());} + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT { return time_point(duration::min()); } + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT { return time_point(duration::max()); } }; } // namespace chrono template -struct _LIBCPP_TEMPLATE_VIS common_type, - chrono::time_point<_Clock, _Duration2> > -{ - typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; +struct _LIBCPP_TEMPLATE_VIS + common_type, chrono::time_point<_Clock, _Duration2> > { + typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; }; namespace chrono { template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -time_point<_Clock, _ToDuration> -time_point_cast(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration> +time_point_cast(const time_point<_Clock, _Duration>& __t) { + return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); } #if _LIBCPP_STD_VER >= 17 template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -time_point<_Clock, _ToDuration> -floor(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())}; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR time_point<_Clock, _ToDuration> +floor(const time_point<_Clock, _Duration>& __t) { + return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())}; } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -time_point<_Clock, _ToDuration> -ceil(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())}; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR time_point<_Clock, _ToDuration> +ceil(const time_point<_Clock, _Duration>& __t) { + return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())}; } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -time_point<_Clock, _ToDuration> -round(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())}; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR time_point<_Clock, _ToDuration> +round(const time_point<_Clock, _Duration>& __t) { + return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())}; } template ::is_signed, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR -duration<_Rep, _Period> -abs(duration<_Rep, _Period> __d) -{ - return __d >= __d.zero() ? +__d : -__d; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration<_Rep, _Period> abs(duration<_Rep, _Period> __d) { + return __d >= __d.zero() ? +__d : -__d; } #endif // _LIBCPP_STD_VER >= 17 // time_point == template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() == __rhs.time_since_epoch(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return __lhs.time_since_epoch() == __rhs.time_since_epoch(); } #if _LIBCPP_STD_VER <= 17 @@ -137,11 +128,9 @@ operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, // time_point != template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__lhs == __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return !(__lhs == __rhs); } #endif // _LIBCPP_STD_VER <= 17 @@ -149,41 +138,33 @@ operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, // time_point < template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() < __rhs.time_since_epoch(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return __lhs.time_since_epoch() < __rhs.time_since_epoch(); } // time_point > template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __rhs < __lhs; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return __rhs < __lhs; } // time_point <= template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__rhs < __lhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return !(__rhs < __lhs); } // time_point >= template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__lhs < __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return !(__lhs < __rhs); } #if _LIBCPP_STD_VER >= 20 @@ -191,7 +172,7 @@ operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, template _Duration2> _LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { - return __lhs.time_since_epoch() <=> __rhs.time_since_epoch(); + return __lhs.time_since_epoch() <=> __rhs.time_since_epoch(); } #endif // _LIBCPP_STD_VER >= 20 @@ -200,42 +181,37 @@ operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> -operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; - return _Tr (__lhs.time_since_epoch() + __rhs); + time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> + operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; + return _Tr(__lhs.time_since_epoch() + __rhs); } // time_point operator+(duration x, time_point y); template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -time_point<_Clock, typename common_type, _Duration2>::type> -operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __rhs + __lhs; + time_point<_Clock, typename common_type, _Duration2>::type> + operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return __rhs + __lhs; } // time_point operator-(time_point x, duration y); template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> -operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; - return _Ret(__lhs.time_since_epoch() -__rhs); + time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> + operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; + return _Ret(__lhs.time_since_epoch() - __rhs); } // duration operator-(time_point x, time_point y); template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -typename common_type<_Duration1, _Duration2>::type -operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() - __rhs.time_since_epoch(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename common_type<_Duration1, _Duration2>::type +operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return __lhs.time_since_epoch() - __rhs.time_since_epoch(); } } // namespace chrono diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h index 776d8ed3124caa726c5da58cbc38df70ef4c400c..5a7dedc6e3a16859252eda4776b3a6a704ddca24 100644 --- a/libcxx/include/__chrono/weekday.h +++ b/libcxx/include/__chrono/weekday.h @@ -24,144 +24,155 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class weekday_indexed; class weekday_last; class weekday { private: - unsigned char __wd_; - _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept; + unsigned char __wd_; + _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept; + public: weekday() = default; - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept : __wd_(static_cast(__val == 7 ? 0 : __val)) {} - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday(const sys_days& __sysd) noexcept - : __wd_(__weekday_from_days(__sysd.time_since_epoch().count())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept + : __wd_(static_cast(__val == 7 ? 0 : __val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday(const sys_days& __sysd) noexcept + : __wd_(__weekday_from_days(__sysd.time_since_epoch().count())) {} _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(const local_days& __locd) noexcept - : __wd_(__weekday_from_days(__locd.time_since_epoch().count())) {} - - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator++() noexcept { __wd_ = (__wd_ == 6 ? 0 : __wd_ + 1); return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator--() noexcept { __wd_ = (__wd_ == 0 ? 6 : __wd_ - 1); return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator+=(const days& __dd) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator-=(const days& __dd) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned c_encoding() const noexcept { return __wd_; } + : __wd_(__weekday_from_days(__locd.time_since_epoch().count())) {} + + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator++() noexcept { + __wd_ = (__wd_ == 6 ? 0 : __wd_ + 1); + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator++(int) noexcept { + weekday __tmp = *this; + ++(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator--() noexcept { + __wd_ = (__wd_ == 0 ? 6 : __wd_ - 1); + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator--(int) noexcept { + weekday __tmp = *this; + --(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator+=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator-=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned c_encoding() const noexcept { return __wd_; } _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned iso_encoding() const noexcept { return __wd_ == 0u ? 7 : __wd_; } _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_ <= 6; } - _LIBCPP_HIDE_FROM_ABI constexpr weekday_indexed operator[](unsigned __index) const noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr weekday_last operator[](last_spec) const noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr weekday_indexed operator[](unsigned __index) const noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr weekday_last operator[](last_spec) const noexcept; }; - // https://howardhinnant.github.io/date_algorithms.html#weekday_from_days -_LIBCPP_HIDE_FROM_ABI inline constexpr -unsigned char weekday::__weekday_from_days(int __days) noexcept -{ - return static_cast( - static_cast(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) - ); +_LIBCPP_HIDE_FROM_ABI inline constexpr unsigned char weekday::__weekday_from_days(int __days) noexcept { + return static_cast(static_cast(__days >= -4 ? (__days + 4) % 7 : (__days + 5) % 7 + 6)); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept -{ return __lhs.c_encoding() == __rhs.c_encoding(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept { + return __lhs.c_encoding() == __rhs.c_encoding(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept -{ return __lhs.c_encoding() < __rhs.c_encoding(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator<(const weekday& __lhs, const weekday& __rhs) noexcept { + return __lhs.c_encoding() < __rhs.c_encoding(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept -{ return __rhs < __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator>(const weekday& __lhs, const weekday& __rhs) noexcept { + return __rhs < __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__rhs < __lhs);} +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept { + return !(__rhs < __lhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__lhs < __rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept { + return !(__lhs < __rhs); +} -_LIBCPP_HIDE_FROM_ABI constexpr -weekday operator+(const weekday& __lhs, const days& __rhs) noexcept -{ - auto const __mu = static_cast(__lhs.c_encoding()) + __rhs.count(); - auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; - return weekday{static_cast(__mu - __yr * 7)}; +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept { + auto const __mu = static_cast(__lhs.c_encoding()) + __rhs.count(); + auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; + return weekday{static_cast(__mu - __yr * 7)}; } -_LIBCPP_HIDE_FROM_ABI constexpr -weekday operator+(const days& __lhs, const weekday& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI constexpr -weekday operator-(const weekday& __lhs, const days& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept { + return __lhs + -__rhs; +} -_LIBCPP_HIDE_FROM_ABI constexpr -days operator-(const weekday& __lhs, const weekday& __rhs) noexcept -{ - const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); - const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; - return days{__wdu - __wk * 7}; +_LIBCPP_HIDE_FROM_ABI inline constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept { + const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); + const int __wk = (__wdu >= 0 ? __wdu : __wdu - 6) / 7; + return days{__wdu - __wk * 7}; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -weekday& weekday::operator+=(const days& __dd) noexcept -{ *this = *this + __dd; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept { + *this = *this + __dd; + return *this; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -weekday& weekday::operator-=(const days& __dd) noexcept -{ *this = *this - __dd; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept { + *this = *this - __dd; + return *this; +} class weekday_indexed { private: - chrono::weekday __wd_; - unsigned char __idx_; + chrono::weekday __wd_; + unsigned char __idx_; + public: - weekday_indexed() = default; - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept - : __wd_{__wdval}, __idx_(__idxval) {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __idx_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_.ok() && __idx_ >= 1 && __idx_ <= 5; } + weekday_indexed() = default; + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept + : __wd_{__wdval}, __idx_(__idxval) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __idx_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_.ok() && __idx_ >= 1 && __idx_ <= 5; } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept -{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept { + return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); +} class weekday_last { private: - chrono::weekday __wd_; + chrono::weekday __wd_; + public: - _LIBCPP_HIDE_FROM_ABI explicit constexpr weekday_last(const chrono::weekday& __val) noexcept - : __wd_{__val} {} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::weekday weekday() const noexcept { return __wd_; } - _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept { return __wd_.ok(); } + _LIBCPP_HIDE_FROM_ABI explicit constexpr weekday_last(const chrono::weekday& __val) noexcept : __wd_{__val} {} + _LIBCPP_HIDE_FROM_ABI constexpr chrono::weekday weekday() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept { return __wd_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept -{ return __lhs.weekday() == __rhs.weekday(); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept { + return __lhs.weekday() == __rhs.weekday(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed weekday::operator[](unsigned __index) const noexcept { + return weekday_indexed{*this, __index}; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday_last weekday::operator[](last_spec) const noexcept { + return weekday_last{*this}; +} -inline constexpr weekday Sunday{0}; -inline constexpr weekday Monday{1}; -inline constexpr weekday Tuesday{2}; -inline constexpr weekday Wednesday{3}; -inline constexpr weekday Thursday{4}; -inline constexpr weekday Friday{5}; -inline constexpr weekday Saturday{6}; +inline constexpr weekday Sunday{0}; +inline constexpr weekday Monday{1}; +inline constexpr weekday Tuesday{2}; +inline constexpr weekday Wednesday{3}; +inline constexpr weekday Thursday{4}; +inline constexpr weekday Friday{5}; +inline constexpr weekday Saturday{6}; } // namespace chrono diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h index 14bcbdafdd8a531b5dd6ce9e64f17da4a6ee288a..1899d09f38dbdbd78fc9e960bfffcdb5f8861fe3 100644 --- a/libcxx/include/__chrono/year.h +++ b/libcxx/include/__chrono/year.h @@ -26,65 +26,81 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class year { private: - short __y_; + short __y_; + public: - year() = default; - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr year(int __val) noexcept : __y_(static_cast(__val)) {} - - _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator++() noexcept { ++__y_; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator--() noexcept { --__y_; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI constexpr year& operator+=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year& operator-=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr year operator+() const noexcept { return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year operator-() const noexcept { return year{-__y_}; } - - _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_leap() const noexcept { return __y_ % 4 == 0 && (__y_ % 100 != 0 || __y_ % 400 == 0); } - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator int() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; - _LIBCPP_HIDE_FROM_ABI static inline constexpr year min() noexcept { return year{-32767}; } - _LIBCPP_HIDE_FROM_ABI static inline constexpr year max() noexcept { return year{ 32767}; } + year() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr year(int __val) noexcept : __y_(static_cast(__val)) {} + + _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator++() noexcept { + ++__y_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator++(int) noexcept { + year __tmp = *this; + ++(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator--() noexcept { + --__y_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator--(int) noexcept { + year __tmp = *this; + --(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI constexpr year& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year& operator-=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator+() const noexcept { return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator-() const noexcept { return year{-__y_}; } + + _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_leap() const noexcept { + return __y_ % 4 == 0 && (__y_ % 100 != 0 || __y_ % 400 == 0); + } + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator int() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; + _LIBCPP_HIDE_FROM_ABI static inline constexpr year min() noexcept { return year{-32767}; } + _LIBCPP_HIDE_FROM_ABI static inline constexpr year max() noexcept { return year{32767}; } }; - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year& __lhs, const year& __rhs) noexcept -{ return static_cast(__lhs) == static_cast(__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const year& __lhs, const year& __rhs) noexcept { + return static_cast(__lhs) == static_cast(__rhs); +} _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const year& __lhs, const year& __rhs) noexcept { - return static_cast(__lhs) <=> static_cast(__rhs); + return static_cast(__lhs) <=> static_cast(__rhs); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -year operator+ (const year& __lhs, const years& __rhs) noexcept -{ return year(static_cast(__lhs) + __rhs.count()); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year operator+ (const years& __lhs, const year& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year operator+(const year& __lhs, const years& __rhs) noexcept { + return year(static_cast(__lhs) + __rhs.count()); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year operator- (const year& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year operator+(const years& __lhs, const year& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -years operator-(const year& __lhs, const year& __rhs) noexcept -{ return years{static_cast(__lhs) - static_cast(__rhs)}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year operator-(const year& __lhs, const years& __rhs) noexcept { + return __lhs + -__rhs; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr years operator-(const year& __lhs, const year& __rhs) noexcept { + return years{static_cast(__lhs) - static_cast(__rhs)}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year& year::operator+=(const years& __dy) noexcept -{ *this = *this + __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year& year::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year& year::operator-=(const years& __dy) noexcept -{ *this = *this - __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year& year::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept { static_assert(static_cast(std::numeric_limits::max()) == static_cast(max())); diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h index d1657b61015b9fb95a00e81ef7dcdc499f6fa6ba..369ea38f7560d9ba7f8516aca765d08fee70c786 100644 --- a/libcxx/include/__chrono/year_month.h +++ b/libcxx/include/__chrono/year_month.h @@ -24,73 +24,75 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class year_month { - chrono::year __y_; - chrono::month __m_; + chrono::year __y_; + chrono::month __m_; + public: - year_month() = default; - _LIBCPP_HIDE_FROM_ABI constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept - : __y_{__yval}, __m_{__mval} {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const months& __dm) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const months& __dm) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok(); } + year_month() = default; + _LIBCPP_HIDE_FROM_ABI constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept + : __y_{__yval}, __m_{__mval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator/(const year& __y, const month& __m) noexcept { + return year_month{__y, __m}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator/(const year& __y, int __m) noexcept { + return year_month{__y, month(__m)}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept { + return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); +} -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const year_month& __lhs, const year_month& __rhs) noexcept { - if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) - return __c; - return __lhs.month() <=> __rhs.month(); +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering +operator<=>(const year_month& __lhs, const year_month& __rhs) noexcept { + if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) + return __c; + return __lhs.month() <=> __rhs.month(); } -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator+(const year_month& __lhs, const months& __rhs) noexcept -{ - int __dmi = static_cast(static_cast(__lhs.month())) - 1 + __rhs.count(); - const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12; - __dmi = __dmi - __dy * 12 + 1; - return (__lhs.year() + years(__dy)) / month(static_cast(__dmi)); +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept { + int __dmi = static_cast(static_cast(__lhs.month())) - 1 + __rhs.count(); + const int __dy = (__dmi >= 0 ? __dmi : __dmi - 11) / 12; + __dmi = __dmi - __dy * 12 + 1; + return (__lhs.year() + years(__dy)) / month(static_cast(__dmi)); } -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator+(const months& __lhs, const year_month& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator+(const year_month& __lhs, const years& __rhs) noexcept -{ return (__lhs.year() + __rhs) / __lhs.month(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept { + return (__lhs.year() + __rhs) / __lhs.month(); +} -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator+(const years& __lhs, const year_month& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI constexpr -months operator-(const year_month& __lhs, const year_month& __rhs) noexcept -{ return (__lhs.year() - __rhs.year()) + months(static_cast(__lhs.month()) - static_cast(__rhs.month())); } +_LIBCPP_HIDE_FROM_ABI inline constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept { + return (__lhs.year() - __rhs.year()) + + months(static_cast(__lhs.month()) - static_cast(__rhs.month())); +} -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator-(const year_month& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept { + return __lhs + -__rhs; +} -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator-(const year_month& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept { + return __lhs + -__rhs; +} _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator+=(const months& __dm) noexcept { *this = *this + __dm; diff --git a/libcxx/include/__chrono/year_month_day.h b/libcxx/include/__chrono/year_month_day.h index ed5903f7d3f6956bb22c82fbfb6e4dbdcaaf7b1a..75884f3654d870f969b22c1406657e3b77191a45 100644 --- a/libcxx/include/__chrono/year_month_day.h +++ b/libcxx/include/__chrono/year_month_day.h @@ -31,271 +31,323 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class year_month_day_last; class year_month_day { private: - chrono::year __y_; - chrono::month __m_; - chrono::day __d_; + chrono::year __y_; + chrono::month __m_; + chrono::day __d_; + public: - year_month_day() = default; - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day( - const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept - : __y_{__yval}, __m_{__mval}, __d_{__dval} {} - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(const sys_days& __sysd) noexcept - : year_month_day(__from_days(__sysd.time_since_epoch())) {} - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_day(const local_days& __locd) noexcept - : year_month_day(__from_days(__locd.time_since_epoch())) {} - - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const months& __dm) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const months& __dm) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const years& __dy) noexcept; - - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - - _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; - - _LIBCPP_HIDE_FROM_ABI static constexpr year_month_day __from_days(days __d) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; + year_month_day() = default; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day( + const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept + : __y_{__yval}, __m_{__mval}, __d_{__dval} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(const sys_days& __sysd) noexcept + : year_month_day(__from_days(__sysd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_day(const local_days& __locd) noexcept + : year_month_day(__from_days(__locd.time_since_epoch())) {} + + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const years& __dy) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { + return local_days{__to_days()}; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; + + _LIBCPP_HIDE_FROM_ABI static constexpr year_month_day __from_days(days __d) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; }; - // https://howardhinnant.github.io/date_algorithms.html#civil_from_days -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day year_month_day::__from_days(days __d) noexcept -{ - static_assert(numeric_limits::digits >= 18, ""); - static_assert(numeric_limits::digits >= 20 , ""); - const int __z = __d.count() + 719468; - const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; - const unsigned __doe = static_cast(__z - __era * 146097); // [0, 146096] - const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] - const int __yr = static_cast(__yoe) + __era * 400; - const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] - const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] - const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] - const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] - return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day year_month_day::__from_days(days __d) noexcept { + static_assert(numeric_limits::digits >= 18, ""); + static_assert(numeric_limits::digits >= 20, ""); + const int __z = __d.count() + 719468; + const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; + const unsigned __doe = static_cast(__z - __era * 146097); // [0, 146096] + const unsigned __yoe = (__doe - __doe / 1460 + __doe / 36524 - __doe / 146096) / 365; // [0, 399] + const int __yr = static_cast(__yoe) + __era * 400; + const unsigned __doy = __doe - (365 * __yoe + __yoe / 4 - __yoe / 100); // [0, 365] + const unsigned __mp = (5 * __doy + 2) / 153; // [0, 11] + const unsigned __dy = __doy - (153 * __mp + 2) / 5 + 1; // [1, 31] + const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] + return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; } // https://howardhinnant.github.io/date_algorithms.html#days_from_civil -_LIBCPP_HIDE_FROM_ABI inline constexpr -days year_month_day::__to_days() const noexcept -{ - static_assert(numeric_limits::digits >= 18, ""); - static_assert(numeric_limits::digits >= 20 , ""); - - const int __yr = static_cast(__y_) - (__m_ <= February); - const unsigned __mth = static_cast(__m_); - const unsigned __dy = static_cast(__d_); - - const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; - const unsigned __yoe = static_cast(__yr - __era * 400); // [0, 399] - const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] - const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] - return days{__era * 146097 + static_cast(__doe) - 719468}; +_LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_day::__to_days() const noexcept { + static_assert(numeric_limits::digits >= 18, ""); + static_assert(numeric_limits::digits >= 20, ""); + + const int __yr = static_cast(__y_) - (__m_ <= February); + const unsigned __mth = static_cast(__m_); + const unsigned __dy = static_cast(__d_); + + const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; + const unsigned __yoe = static_cast(__yr - __era * 400); // [0, 399] + const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy - 1; // [0, 365] + const unsigned __doe = __yoe * 365 + __yoe / 4 - __yoe / 100 + __doy; // [0, 146096] + return days{__era * 146097 + static_cast(__doe) - 719468}; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept { + return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); +} -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering operator<=>(const year_month_day& __lhs, const year_month_day& __rhs) noexcept { - if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) - return __c; - if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) - return __c; - return __lhs.day() <=> __rhs.day(); + if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) + return __c; + if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) + return __c; + return __lhs.day() <=> __rhs.day(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept -{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(const year_month& __lhs, int __rhs) noexcept -{ return __lhs / day(__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept { + return year_month_day{__lhs.year(), __lhs.month(), __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept -{ return __lhs / __rhs.month() / __rhs.day(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const year_month& __lhs, int __rhs) noexcept { + return __lhs / day(__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(int __lhs, const month_day& __rhs) noexcept -{ return year(__lhs) / __rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept { + return __lhs / __rhs.month() / __rhs.day(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(int __lhs, const month_day& __rhs) noexcept { + return year(__lhs) / __rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(const month_day& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept { + return __rhs / __lhs; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const month_day& __lhs, int __rhs) noexcept { + return year(__rhs) / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept -{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator+(const year_month_day& __lhs, const months& __rhs) noexcept { + return (__lhs.year() / __lhs.month() + __rhs) / __lhs.day(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator+(const months& __lhs, const year_month_day& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator-(const year_month_day& __lhs, const months& __rhs) noexcept { + return __lhs + -__rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept -{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator+(const year_month_day& __lhs, const years& __rhs) noexcept { + return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator+(const years& __lhs, const year_month_day& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator-(const year_month_day& __lhs, const years& __rhs) noexcept { + return __lhs + -__rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} class year_month_day_last { private: - chrono::year __y_; - chrono::month_day_last __mdl_; + chrono::year __y_; + chrono::month_day_last __mdl_; + public: - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept - : __y_{__yval}, __mdl_{__mdlval} {} - - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const months& __m) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const months& __m) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const years& __y) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const years& __y) noexcept; - - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __mdl_.month(); } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl_; } - _LIBCPP_HIDE_FROM_ABI constexpr chrono::day day() const noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __mdl_.ok(); } + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept + : __y_{__yval}, __mdl_{__mdlval} {} + + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const months& __m) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const months& __m) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const years& __y) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const years& __y) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __mdl_.month(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::day day() const noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { + return sys_days{year() / month() / day()}; + } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { + return local_days{year() / month() / day()}; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __mdl_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -chrono::day year_month_day_last::day() const noexcept -{ - constexpr chrono::day __d[] = - { - chrono::day(31), chrono::day(28), chrono::day(31), - chrono::day(30), chrono::day(31), chrono::day(30), - chrono::day(31), chrono::day(31), chrono::day(30), - chrono::day(31), chrono::day(30), chrono::day(31) - }; - return (month() != February || !__y_.is_leap()) && month().ok() ? - __d[static_cast(month()) - 1] : chrono::day{29}; +_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day year_month_day_last::day() const noexcept { + constexpr chrono::day __d[] = { + chrono::day(31), + chrono::day(28), + chrono::day(31), + chrono::day(30), + chrono::day(31), + chrono::day(30), + chrono::day(31), + chrono::day(31), + chrono::day(30), + chrono::day(31), + chrono::day(30), + chrono::day(31)}; + return (month() != February || !__y_.is_leap()) && month().ok() + ? __d[static_cast(month()) - 1] + : chrono::day{29}; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept { + return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__lhs == __rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept { + return !(__lhs == __rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ - if (__lhs.year() < __rhs.year()) return true; - if (__lhs.year() > __rhs.year()) return false; - return __lhs.month_day_last() < __rhs.month_day_last(); +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator<(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept { + if (__lhs.year() < __rhs.year()) + return true; + if (__lhs.year() > __rhs.year()) + return false; + return __lhs.month_day_last() < __rhs.month_day_last(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs < __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator>(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept { + return __rhs < __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__rhs < __lhs);} +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept { + return !(__rhs < __lhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__lhs < __rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept { + return !(__lhs < __rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept -{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept { + return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept -{ return year_month_day_last{__lhs, __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator/(const year& __lhs, const month_day_last& __rhs) noexcept { + return year_month_day_last{__lhs, __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept -{ return year_month_day_last{year{__lhs}, __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept { + return year_month_day_last{year{__lhs}, __rhs}; +} _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last -operator/(const month_day_last& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept -{ return year{__rhs} / __lhs; } +operator/(const month_day_last& __lhs, const year& __rhs) noexcept { + return __rhs / __lhs; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept { + return year{__rhs} / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / last; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept { + return (__lhs.year() / __lhs.month() + __rhs) / last; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept -{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept { + return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& +year_month_day_last::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& +year_month_day_last::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& +year_month_day_last::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& +year_month_day_last::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept : __y_{__ymdl.year()}, __m_{__ymdl.month()}, __d_{__ymdl.day()} {} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool year_month_day::ok() const noexcept -{ - if (!__y_.ok() || !__m_.ok()) return false; - return chrono::day{1} <= __d_ && __d_ <= (__y_ / __m_ / last).day(); +_LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept { + if (!__y_.ok() || !__m_.ok()) + return false; + return chrono::day{1} <= __d_ && __d_ <= (__y_ / __m_ / last).day(); } } // namespace chrono diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h index 4b5cb492a19147eb463f44ca10c6dc9e4731f493..0c3dd494c878720cd02ab6973093057c7debebe6 100644 --- a/libcxx/include/__chrono/year_month_weekday.h +++ b/libcxx/include/__chrono/year_month_weekday.h @@ -31,211 +31,252 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class year_month_weekday { - chrono::year __y_; - chrono::month __m_; - chrono::weekday_indexed __wdi_; + chrono::year __y_; + chrono::month __m_; + chrono::weekday_indexed __wdi_; + public: - year_month_weekday() = default; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, - const chrono::weekday_indexed& __wdival) noexcept - : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {} - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const sys_days& __sysd) noexcept - : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept - : year_month_weekday(__from_days(__locd.time_since_epoch())) {} - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months&) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months&) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years&) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years&) noexcept; - - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdi_.weekday(); } - _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __wdi_.index(); } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } - - _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept - { - if (!__y_.ok() || !__m_.ok() || !__wdi_.ok()) return false; - if (__wdi_.index() <= 4) return true; - auto __nth_weekday_day = - __wdi_.weekday() - - chrono::weekday{static_cast(__y_ / __m_ / 1)} + - days{(__wdi_.index() - 1) * 7 + 1}; - return static_cast(__nth_weekday_day.count()) <= - static_cast((__y_ / __m_ / last).day()); - } - - _LIBCPP_HIDE_FROM_ABI static constexpr year_month_weekday __from_days(days __d) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; + year_month_weekday() = default; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday( + const chrono::year& __yval, const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept + : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const sys_days& __sysd) noexcept + : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept + : year_month_weekday(__from_days(__locd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years&) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdi_.weekday(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __wdi_.index(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } + + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { + return local_days{__to_days()}; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { + if (!__y_.ok() || !__m_.ok() || !__wdi_.ok()) + return false; + if (__wdi_.index() <= 4) + return true; + auto __nth_weekday_day = + __wdi_.weekday() - chrono::weekday{static_cast(__y_ / __m_ / 1)} + days{(__wdi_.index() - 1) * 7 + 1}; + return static_cast(__nth_weekday_day.count()) <= static_cast((__y_ / __m_ / last).day()); + } + + _LIBCPP_HIDE_FROM_ABI static constexpr year_month_weekday __from_days(days __d) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday year_month_weekday::__from_days(days __d) noexcept -{ - const sys_days __sysd{__d}; - const chrono::weekday __wd = chrono::weekday(__sysd); - const year_month_day __ymd = year_month_day(__sysd); - return year_month_weekday{__ymd.year(), __ymd.month(), - __wd[(static_cast(__ymd.day())-1)/7+1]}; +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday year_month_weekday::__from_days(days __d) noexcept { + const sys_days __sysd{__d}; + const chrono::weekday __wd = chrono::weekday(__sysd); + const year_month_day __ymd = year_month_day(__sysd); + return year_month_weekday{__ymd.year(), __ymd.month(), __wd[(static_cast(__ymd.day()) - 1) / 7 + 1]}; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -days year_month_weekday::__to_days() const noexcept -{ - const sys_days __sysd = sys_days(__y_/__m_/1); - return (__sysd + (__wdi_.weekday() - chrono::weekday(__sysd) + days{(__wdi_.index()-1)*7})) - .time_since_epoch(); +_LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_weekday::__to_days() const noexcept { + const sys_days __sysd = sys_days(__y_ / __m_ / 1); + return (__sysd + (__wdi_.weekday() - chrono::weekday(__sysd) + days{(__wdi_.index() - 1) * 7})).time_since_epoch(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept -{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept -{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept { + return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && + __lhs.weekday_indexed() == __rhs.weekday_indexed(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept -{ return year(__lhs) / __rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept { + return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator/(const year& __lhs, const month_weekday& __rhs) noexcept { + return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept { + return year(__lhs) / __rhs; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator/(const month_weekday& __lhs, const year& __rhs) noexcept { + return __rhs / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept { + return year(__rhs) / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept { + return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept -{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept { + return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept { + return __rhs + __lhs; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} class year_month_weekday_last { private: - chrono::year __y_; - chrono::month __m_; - chrono::weekday_last __wdl_; -public: - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval, - const chrono::weekday_last& __wdlval) noexcept - : __y_{__yval}, __m_{__mval}, __wdl_{__wdlval} {} - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; - - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdl_.weekday(); } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok() && __wdl_.ok(); } - - _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; + chrono::year __y_; + chrono::month __m_; + chrono::weekday_last __wdl_; +public: + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last( + const chrono::year& __yval, const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept + : __y_{__yval}, __m_{__mval}, __wdl_{__wdlval} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdl_.weekday(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { + return local_days{__to_days()}; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok() && __wdl_.ok(); } + + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -days year_month_weekday_last::__to_days() const noexcept -{ - const sys_days __last = sys_days{__y_/__m_/last}; - return (__last - (chrono::weekday{__last} - __wdl_.weekday())).time_since_epoch(); - +_LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_weekday_last::__to_days() const noexcept { + const sys_days __last = sys_days{__y_ / __m_ / last}; + return (__last - (chrono::weekday{__last} - __wdl_.weekday())).time_since_epoch(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept -{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept { + return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept -{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept { + return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept -{ return year(__lhs) / __rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept { + return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator/(int __lhs, const month_weekday_last& __rhs) noexcept { + return year(__lhs) / __rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept { + return __rhs / __lhs; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator/(const month_weekday_last& __lhs, int __rhs) noexcept { + return year(__rhs) / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept { + return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept -{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept { + return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& +year_month_weekday_last::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& +year_month_weekday_last::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& +year_month_weekday_last::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& +year_month_weekday_last::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} } // namespace chrono diff --git a/libcxx/include/__compare/common_comparison_category.h b/libcxx/include/__compare/common_comparison_category.h index 5fad99bf5ce0a538aa2f1c78e40b9573734bf69a..7aeb3da03a4f4a9975fa022a90ebcf63c2dc5a05 100644 --- a/libcxx/include/__compare/common_comparison_category.h +++ b/libcxx/include/__compare/common_comparison_category.h @@ -24,17 +24,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace __comp_detail { -enum _ClassifyCompCategory : unsigned { - _None, - _PartialOrd, - _WeakOrd, - _StrongOrd, - _CCC_Size -}; +enum _ClassifyCompCategory : unsigned { _None, _PartialOrd, _WeakOrd, _StrongOrd, _CCC_Size }; template -_LIBCPP_HIDE_FROM_ABI -constexpr _ClassifyCompCategory __type_to_enum() noexcept { +_LIBCPP_HIDE_FROM_ABI constexpr _ClassifyCompCategory __type_to_enum() noexcept { if (is_same_v<_Tp, partial_ordering>) return _PartialOrd; if (is_same_v<_Tp, weak_ordering>) @@ -45,8 +38,7 @@ constexpr _ClassifyCompCategory __type_to_enum() noexcept { } template -_LIBCPP_HIDE_FROM_ABI -constexpr _ClassifyCompCategory +_LIBCPP_HIDE_FROM_ABI constexpr _ClassifyCompCategory __compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { int __seen[_CCC_Size] = {}; for (auto __type : __types) @@ -60,12 +52,11 @@ __compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { return _StrongOrd; } -template -_LIBCPP_HIDE_FROM_ABI -constexpr auto __get_comp_type() { - using _CCC = _ClassifyCompCategory; +template +_LIBCPP_HIDE_FROM_ABI constexpr auto __get_comp_type() { + using _CCC = _ClassifyCompCategory; constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...}; - constexpr _CCC __cat = __comp_detail::__compute_comp_type(__type_kinds); + constexpr _CCC __cat = __comp_detail::__compute_comp_type(__type_kinds); if constexpr (__cat == _None) return void(); else if constexpr (__cat == _PartialOrd) @@ -80,12 +71,12 @@ constexpr auto __get_comp_type() { } // namespace __comp_detail // [cmp.common], common comparison category type -template +template struct _LIBCPP_TEMPLATE_VIS common_comparison_category { using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); }; -template +template using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__compare/compare_partial_order_fallback.h b/libcxx/include/__compare/compare_partial_order_fallback.h index a49408e1cfda92e866bc522b14425f4a5124abfd..e0efa3ccb88db76eb4cbe18f7f5bb78a2eb05241 100644 --- a/libcxx/include/__compare/compare_partial_order_fallback.h +++ b/libcxx/include/__compare/compare_partial_order_fallback.h @@ -27,44 +27,46 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __compare_partial_order_fallback { - struct __fn { - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) - noexcept(noexcept(std::partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - -> decltype( std::partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))) - { return std::partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)); } +struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept( + noexcept(std::partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) + -> decltype(std::partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))) { + return std::partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)); + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? partial_ordering::equivalent : - std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less : - std::forward<_Up>(__u) < std::forward<_Tp>(__t) ? partial_ordering::greater : - partial_ordering::unordered)) - -> decltype( std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? partial_ordering::equivalent : - std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less : - std::forward<_Up>(__u) < std::forward<_Tp>(__t) ? partial_ordering::greater : - partial_ordering::unordered) - { - return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? partial_ordering::equivalent : - std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less : - std::forward<_Up>(__u) < std::forward<_Tp>(__t) ? partial_ordering::greater : - partial_ordering::unordered; - } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(noexcept( + std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? partial_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less + : std::forward<_Up>(__u) < std::forward<_Tp>(__t) + ? partial_ordering::greater + : partial_ordering::unordered)) + -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? partial_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less + : std::forward<_Up>(__u) < std::forward<_Tp>(__t) + ? partial_ordering::greater + : partial_ordering::unordered) { + return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? partial_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less + : std::forward<_Up>(__u) < std::forward<_Tp>(__t) + ? partial_ordering::greater + : partial_ordering::unordered; + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()))) - -> decltype( __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>())) - { return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()); } - }; + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()); + } +}; } // namespace __compare_partial_order_fallback inline namespace __cpo { - inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{}; +inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__compare/compare_strong_order_fallback.h b/libcxx/include/__compare/compare_strong_order_fallback.h index 9e2dfee6b389fe7c735ffc1ae0a265169fcb9cd7..a94d517ed30fcea591257d69a7f01f2f97b2812e 100644 --- a/libcxx/include/__compare/compare_strong_order_fallback.h +++ b/libcxx/include/__compare/compare_strong_order_fallback.h @@ -27,41 +27,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __compare_strong_order_fallback { - struct __fn { - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) - noexcept(noexcept(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - -> decltype( std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))) - { return std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)); } +struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept( + noexcept(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) + -> decltype(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))) { + return std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)); + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal : - std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? strong_ordering::less : - strong_ordering::greater)) - -> decltype( std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal : - std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? strong_ordering::less : - strong_ordering::greater) - { - return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal : - std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? strong_ordering::less : - strong_ordering::greater; - } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(noexcept( + std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? strong_ordering::less + : strong_ordering::greater)) + -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? strong_ordering::less + : strong_ordering::greater) { + return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? strong_ordering::less + : strong_ordering::greater; + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()))) - -> decltype( __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>())) - { return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()); } - }; + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()); + } +}; } // namespace __compare_strong_order_fallback inline namespace __cpo { - inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{}; +inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__compare/compare_three_way.h b/libcxx/include/__compare/compare_three_way.h index b1ed2d1e7251c1d56161577880f5915414759c49..01c12076c0d73d021011587d169406d3c0d04f5a 100644 --- a/libcxx/include/__compare/compare_three_way.h +++ b/libcxx/include/__compare/compare_three_way.h @@ -22,16 +22,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -struct _LIBCPP_TEMPLATE_VIS compare_three_way -{ - template - requires three_way_comparable_with<_T1, _T2> - constexpr _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) <=> std::forward<_T2>(__u))) - { return std::forward<_T1>(__t) <=> std::forward<_T2>(__u); } - - using is_transparent = void; +struct _LIBCPP_TEMPLATE_VIS compare_three_way { + template + requires three_way_comparable_with<_T1, _T2> + constexpr _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) <=> std::forward<_T2>(__u))) { + return std::forward<_T1>(__t) <=> std::forward<_T2>(__u); + } + + using is_transparent = void; }; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__compare/compare_three_way_result.h b/libcxx/include/__compare/compare_three_way_result.h index 632ebdce1bce4aeedfdcb3483de3a59a0aabc7bb..d7508073433af465ae7d999985e65761a28f9d98 100644 --- a/libcxx/include/__compare/compare_three_way_result.h +++ b/libcxx/include/__compare/compare_three_way_result.h @@ -21,20 +21,21 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template -struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result { }; - -template -struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result<_Tp, _Up, decltype( - std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>(), void() -)> { - using type = decltype(std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>()); +template +struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result {}; + +template +struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result< + _Tp, + _Up, + decltype(std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>(), void())> { + using type = decltype(std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>()); }; -template -struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_result<_Tp, _Up, void> { }; +template +struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_result<_Tp, _Up, void> {}; -template +template using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::type; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__compare/compare_weak_order_fallback.h b/libcxx/include/__compare/compare_weak_order_fallback.h index b0a04abcaaf03c5331491c53b58b60de8212dd97..062b7b582cd7ebdc427c7ccd250fe7a8bc2101dc 100644 --- a/libcxx/include/__compare/compare_weak_order_fallback.h +++ b/libcxx/include/__compare/compare_weak_order_fallback.h @@ -27,41 +27,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __compare_weak_order_fallback { - struct __fn { - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) - noexcept(noexcept(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - -> decltype( std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))) - { return std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)); } +struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept( + noexcept(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) + -> decltype(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))) { + return std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)); + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent : - std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? weak_ordering::less : - weak_ordering::greater)) - -> decltype( std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent : - std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? weak_ordering::less : - weak_ordering::greater) - { - return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent : - std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? weak_ordering::less : - weak_ordering::greater; - } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(noexcept( + std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? weak_ordering::less + : weak_ordering::greater)) + -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? weak_ordering::less + : weak_ordering::greater) { + return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? weak_ordering::less + : weak_ordering::greater; + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()))) - -> decltype( __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>())) - { return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()); } - }; + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()); + } +}; } // namespace __compare_weak_order_fallback inline namespace __cpo { - inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{}; +inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__compare/ordering.h b/libcxx/include/__compare/ordering.h index c9a15efb3c2fc47a1942a3dee1ab38dab2653393..2995d381304f0e4b10870aaeb184d4a21f5a2172 100644 --- a/libcxx/include/__compare/ordering.h +++ b/libcxx/include/__compare/ordering.h @@ -22,46 +22,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 // exposition only -enum class _OrdResult : signed char { - __less = -1, - __equiv = 0, - __greater = 1 -}; +enum class _OrdResult : signed char { __less = -1, __equiv = 0, __greater = 1 }; -enum class _NCmpResult : signed char { - __unordered = -127 -}; +enum class _NCmpResult : signed char { __unordered = -127 }; class partial_ordering; class weak_ordering; class strong_ordering; -template +template inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...); struct _CmpUnspecifiedParam { - _LIBCPP_HIDE_FROM_ABI constexpr - _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} - template>> + template >> _CmpUnspecifiedParam(_Tp) = delete; }; class partial_ordering { using _ValueT = signed char; - _LIBCPP_HIDE_FROM_ABI - explicit constexpr partial_ordering(_OrdResult __v) noexcept - : __value_(_ValueT(__v)) {} + _LIBCPP_HIDE_FROM_ABI explicit constexpr partial_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} - _LIBCPP_HIDE_FROM_ABI - explicit constexpr partial_ordering(_NCmpResult __v) noexcept - : __value_(_ValueT(__v)) {} + _LIBCPP_HIDE_FROM_ABI explicit constexpr partial_ordering(_NCmpResult __v) noexcept : __value_(_ValueT(__v)) {} - _LIBCPP_HIDE_FROM_ABI - constexpr bool __is_ordered() const noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr bool __is_ordered() const noexcept { return __value_ != _ValueT(_NCmpResult::__unordered); } + public: // valid values static const partial_ordering less; @@ -70,63 +59,54 @@ public: static const partial_ordering unordered; // comparisons - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__is_ordered() && __v.__value_ == 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__is_ordered() && __v.__value_ < 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__is_ordered() && __v.__value_ <= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__is_ordered() && __v.__value_ > 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__is_ordered() && __v.__value_ >= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept { return __v.__is_ordered() && 0 < __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { return __v.__is_ordered() && 0 <= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { return __v.__is_ordered() && 0 > __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { return __v.__is_ordered() && 0 >= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr partial_ordering + operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr partial_ordering + operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); } + private: _ValueT __value_; }; @@ -139,76 +119,62 @@ inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__un class weak_ordering { using _ValueT = signed char; - _LIBCPP_HIDE_FROM_ABI - explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + _LIBCPP_HIDE_FROM_ABI explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} public: static const weak_ordering less; static const weak_ordering equivalent; static const weak_ordering greater; - _LIBCPP_HIDE_FROM_ABI - constexpr operator partial_ordering() const noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr operator partial_ordering() const noexcept { return __value_ == 0 ? partial_ordering::equivalent - : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); } // comparisons - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ == 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ < 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ <= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ > 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ >= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept { return 0 < __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { return 0 <= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { return 0 > __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { return 0 >= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); } @@ -223,8 +189,7 @@ inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); class strong_ordering { using _ValueT = signed char; - _LIBCPP_HIDE_FROM_ABI - explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + _LIBCPP_HIDE_FROM_ABI explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} public: static const strong_ordering less; @@ -233,74 +198,61 @@ public: static const strong_ordering greater; // conversions - _LIBCPP_HIDE_FROM_ABI - constexpr operator partial_ordering() const noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr operator partial_ordering() const noexcept { return __value_ == 0 ? partial_ordering::equivalent - : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); } - _LIBCPP_HIDE_FROM_ABI - constexpr operator weak_ordering() const noexcept { - return __value_ == 0 ? weak_ordering::equivalent - : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); + _LIBCPP_HIDE_FROM_ABI constexpr operator weak_ordering() const noexcept { + return __value_ == 0 ? weak_ordering::equivalent : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); } // comparisons - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ == 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ < 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ <= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ > 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ >= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept { return 0 < __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { return 0 <= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { return 0 > __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { return 0 >= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering + operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering + operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); } diff --git a/libcxx/include/__compare/partial_order.h b/libcxx/include/__compare/partial_order.h index 36a11dfaa2881b4df3cb814928c2acf69c571039..f3ed4900fbff25288500511f5f9aebdcd82dd0eb 100644 --- a/libcxx/include/__compare/partial_order.h +++ b/libcxx/include/__compare/partial_order.h @@ -28,43 +28,44 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __partial_order { - struct __fn { - // NOLINTBEGIN(libcpp-robust-against-adl) partial_order should use ADL, but only here - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) - noexcept(noexcept(partial_ordering(partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) - -> decltype( partial_ordering(partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - { return partial_ordering(partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); } - // NOLINTEND(libcpp-robust-against-adl) +struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) partial_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept( + noexcept(partial_ordering(partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(partial_ordering(partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return partial_ordering(partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } + // NOLINTEND(libcpp-robust-against-adl) - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) - noexcept(noexcept(partial_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) - -> decltype( partial_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - { return partial_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))); } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept( + noexcept(partial_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(partial_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return partial_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(partial_ordering(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) - -> decltype( partial_ordering(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - { return partial_ordering(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept( + noexcept(partial_ordering(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(partial_ordering(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return partial_ordering(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()))) - -> decltype( __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>())) - { return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()); } - }; + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()); + } +}; } // namespace __partial_order inline namespace __cpo { - inline constexpr auto partial_order = __partial_order::__fn{}; +inline constexpr auto partial_order = __partial_order::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__compare/strong_order.h b/libcxx/include/__compare/strong_order.h index cbfcf7316de9e0c1e5fe101bda6356b71d2e020f..5f6ade5aef8e4ac43c13739b721708e28789892d 100644 --- a/libcxx/include/__compare/strong_order.h +++ b/libcxx/include/__compare/strong_order.h @@ -34,100 +34,99 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __strong_order { - struct __fn { - // NOLINTBEGIN(libcpp-robust-against-adl) strong_order should use ADL, but only here - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) - noexcept(noexcept(strong_ordering(strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) - -> decltype( strong_ordering(strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - { return strong_ordering(strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); } - // NOLINTEND(libcpp-robust-against-adl) +struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) strong_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept( + noexcept(strong_ordering(strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(strong_ordering(strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return strong_ordering(strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } + // NOLINTEND(libcpp-robust-against-adl) - template> - requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> - _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept - { - if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int32_t)) { - int32_t __rx = std::bit_cast(__t); - int32_t __ry = std::bit_cast(__u); - __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; - __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; - return (__rx <=> __ry); - } else if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int64_t)) { - int64_t __rx = std::bit_cast(__t); - int64_t __ry = std::bit_cast(__u); - __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; - __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; - return (__rx <=> __ry); - } else if (__t < __u) { - return strong_ordering::less; - } else if (__t > __u) { - return strong_ordering::greater; - } else if (__t == __u) { - if constexpr (numeric_limits<_Dp>::radix == 2) { - return std::signbit(__u) <=> std::signbit(__t); - } else { - // This is bullet 3 of the IEEE754 algorithm, relevant - // only for decimal floating-point; - // see https://stackoverflow.com/questions/69068075/ - if (__t == 0 || std::isinf(__t)) { - return std::signbit(__u) <=> std::signbit(__t); - } else { - int __texp, __uexp; - (void)std::frexp(__t, &__texp); - (void)std::frexp(__u, &__uexp); - return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp); - } - } - } else { - // They're unordered, so one of them must be a NAN. - // The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN. - bool __t_is_nan = std::isnan(__t); - bool __u_is_nan = std::isnan(__u); - bool __t_is_negative = std::signbit(__t); - bool __u_is_negative = std::signbit(__u); - using _IntType = conditional_t< - sizeof(__t) == sizeof(int32_t), int32_t, conditional_t< - sizeof(__t) == sizeof(int64_t), int64_t, void> - >; - if constexpr (is_same_v<_IntType, void>) { - static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type"); - } else if (__t_is_nan && __u_is_nan) { - // Order by sign bit, then by "payload bits" (we'll just use bit_cast). - if (__t_is_negative != __u_is_negative) { - return (__u_is_negative <=> __t_is_negative); - } else { - return std::bit_cast<_IntType>(__t) <=> std::bit_cast<_IntType>(__u); - } - } else if (__t_is_nan) { - return __t_is_negative ? strong_ordering::less : strong_ordering::greater; - } else { - return __u_is_negative ? strong_ordering::greater : strong_ordering::less; - } - } + template > + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept { + if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int32_t)) { + int32_t __rx = std::bit_cast(__t); + int32_t __ry = std::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int64_t)) { + int64_t __rx = std::bit_cast(__t); + int64_t __ry = std::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if (__t < __u) { + return strong_ordering::less; + } else if (__t > __u) { + return strong_ordering::greater; + } else if (__t == __u) { + if constexpr (numeric_limits<_Dp>::radix == 2) { + return std::signbit(__u) <=> std::signbit(__t); + } else { + // This is bullet 3 of the IEEE754 algorithm, relevant + // only for decimal floating-point; + // see https://stackoverflow.com/questions/69068075/ + if (__t == 0 || std::isinf(__t)) { + return std::signbit(__u) <=> std::signbit(__t); + } else { + int __texp, __uexp; + (void)std::frexp(__t, &__texp); + (void)std::frexp(__u, &__uexp); + return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp); } + } + } else { + // They're unordered, so one of them must be a NAN. + // The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN. + bool __t_is_nan = std::isnan(__t); + bool __u_is_nan = std::isnan(__u); + bool __t_is_negative = std::signbit(__t); + bool __u_is_negative = std::signbit(__u); + using _IntType = + conditional_t< sizeof(__t) == sizeof(int32_t), + int32_t, + conditional_t< sizeof(__t) == sizeof(int64_t), int64_t, void> >; + if constexpr (is_same_v<_IntType, void>) { + static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type"); + } else if (__t_is_nan && __u_is_nan) { + // Order by sign bit, then by "payload bits" (we'll just use bit_cast). + if (__t_is_negative != __u_is_negative) { + return (__u_is_negative <=> __t_is_negative); + } else { + return std::bit_cast<_IntType>(__t) <=> std::bit_cast<_IntType>(__u); + } + } else if (__t_is_nan) { + return __t_is_negative ? strong_ordering::less : strong_ordering::greater; + } else { + return __u_is_negative ? strong_ordering::greater : strong_ordering::less; + } + } + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(strong_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) - -> decltype( strong_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - { return strong_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))); } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept( + noexcept(strong_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(strong_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return strong_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()))) - -> decltype( __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>())) - { return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()); } - }; + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()); + } +}; } // namespace __strong_order inline namespace __cpo { - inline constexpr auto strong_order = __strong_order::__fn{}; +inline constexpr auto strong_order = __strong_order::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__compare/three_way_comparable.h b/libcxx/include/__compare/three_way_comparable.h index 2b77bc3f54e6fbece22645bc9049a13caba94856..7a44ea9158a6f7254816439a49f7a78c86b65773 100644 --- a/libcxx/include/__compare/three_way_comparable.h +++ b/libcxx/include/__compare/three_way_comparable.h @@ -27,30 +27,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template -concept __compares_as = - same_as, _Cat>; +template +concept __compares_as = same_as, _Cat>; -template +template concept three_way_comparable = - __weakly_equality_comparable_with<_Tp, _Tp> && - __partially_ordered_with<_Tp, _Tp> && - requires(__make_const_lvalue_ref<_Tp> __a, __make_const_lvalue_ref<_Tp> __b) { - { __a <=> __b } -> __compares_as<_Cat>; - }; + __weakly_equality_comparable_with<_Tp, _Tp> && __partially_ordered_with<_Tp, _Tp> && + requires(__make_const_lvalue_ref<_Tp> __a, __make_const_lvalue_ref<_Tp> __b) { + { __a <=> __b } -> __compares_as<_Cat>; + }; -template +template concept three_way_comparable_with = - three_way_comparable<_Tp, _Cat> && - three_way_comparable<_Up, _Cat> && - common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && - three_way_comparable, __make_const_lvalue_ref<_Up>>, _Cat> && - __weakly_equality_comparable_with<_Tp, _Up> && - __partially_ordered_with<_Tp, _Up> && - requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { - { __t <=> __u } -> __compares_as<_Cat>; - { __u <=> __t } -> __compares_as<_Cat>; - }; + three_way_comparable<_Tp, _Cat> && three_way_comparable<_Up, _Cat> && + common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && + three_way_comparable, __make_const_lvalue_ref<_Up>>, _Cat> && + __weakly_equality_comparable_with<_Tp, _Up> && __partially_ordered_with<_Tp, _Up> && + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t <=> __u } -> __compares_as<_Cat>; + { __u <=> __t } -> __compares_as<_Cat>; + }; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__compare/weak_order.h b/libcxx/include/__compare/weak_order.h index e6a42ac4c923526007849642573d7823596ff94e..9f719eb64bbca34afacaedd70242c884afa24baa 100644 --- a/libcxx/include/__compare/weak_order.h +++ b/libcxx/include/__compare/weak_order.h @@ -28,71 +28,70 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __weak_order { - struct __fn { - // NOLINTBEGIN(libcpp-robust-against-adl) weak_order should use ADL, but only here - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<3>) - noexcept(noexcept(weak_ordering(weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) - -> decltype( weak_ordering(weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - { return weak_ordering(weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); } - // NOLINTEND(libcpp-robust-against-adl) +struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) weak_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<3>) noexcept( + noexcept(weak_ordering(weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(weak_ordering(weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return weak_ordering(weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } + // NOLINTEND(libcpp-robust-against-adl) - template> - requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> - _LIBCPP_HIDE_FROM_ABI static constexpr weak_ordering - __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept - { - partial_ordering __po = (__t <=> __u); - if (__po == partial_ordering::less) { - return weak_ordering::less; - } else if (__po == partial_ordering::equivalent) { - return weak_ordering::equivalent; - } else if (__po == partial_ordering::greater) { - return weak_ordering::greater; - } else { - // Otherwise, at least one of them is a NaN. - bool __t_is_nan = std::isnan(__t); - bool __u_is_nan = std::isnan(__u); - bool __t_is_negative = std::signbit(__t); - bool __u_is_negative = std::signbit(__u); - if (__t_is_nan && __u_is_nan) { - return (__u_is_negative <=> __t_is_negative); - } else if (__t_is_nan) { - return __t_is_negative ? weak_ordering::less : weak_ordering::greater; - } else { - return __u_is_negative ? weak_ordering::greater : weak_ordering::less; - } - } - } + template > + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr weak_ordering __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept { + partial_ordering __po = (__t <=> __u); + if (__po == partial_ordering::less) { + return weak_ordering::less; + } else if (__po == partial_ordering::equivalent) { + return weak_ordering::equivalent; + } else if (__po == partial_ordering::greater) { + return weak_ordering::greater; + } else { + // Otherwise, at least one of them is a NaN. + bool __t_is_nan = std::isnan(__t); + bool __u_is_nan = std::isnan(__u); + bool __t_is_negative = std::signbit(__t); + bool __u_is_negative = std::signbit(__u); + if (__t_is_nan && __u_is_nan) { + return (__u_is_negative <=> __t_is_negative); + } else if (__t_is_nan) { + return __t_is_negative ? weak_ordering::less : weak_ordering::greater; + } else { + return __u_is_negative ? weak_ordering::greater : weak_ordering::less; + } + } + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) - noexcept(noexcept(weak_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) - -> decltype( weak_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - { return weak_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))); } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept( + noexcept(weak_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(weak_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return weak_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(weak_ordering(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) - -> decltype( weak_ordering(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) - { return weak_ordering(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept( + noexcept(weak_ordering(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(weak_ordering(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return weak_ordering(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<3>()))) - -> decltype( __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<3>())) - { return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<3>()); } - }; + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<3>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<3>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<3>()); + } +}; } // namespace __weak_order inline namespace __cpo { - inline constexpr auto weak_order = __weak_order::__fn{}; +inline constexpr auto weak_order = __weak_order::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__config b/libcxx/include/__config index 7f66042f90256d2821e0f3eaefdeac2d68c6f7bf..adff13e714cb642a1ef7a9749942ef42d90e1aa0 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1010,8 +1010,8 @@ typedef __char32_t char32_t; # endif # ifndef _LIBCPP_HAS_NO_ASAN - extern "C" _LIBCPP_EXPORTED_FROM_ABI void - __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*); +extern "C" _LIBCPP_EXPORTED_FROM_ABI void +__sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*); extern "C" _LIBCPP_EXPORTED_FROM_ABI void __sanitizer_annotate_double_ended_contiguous_container( const void*, const void*, const void*, const void*, const void*, const void*); extern "C" _LIBCPP_EXPORTED_FROM_ABI int diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in index 6cade6f10d8acc1e9afe2795b1c1fe683d5d988f..7c002c5bfcf8e77f84e0cf14254b358d0896356f 100644 --- a/libcxx/include/__config_site.in +++ b/libcxx/include/__config_site.in @@ -29,6 +29,7 @@ #cmakedefine _LIBCPP_HAS_NO_WIDE_CHARACTERS #cmakedefine _LIBCPP_HAS_NO_STD_MODULES #cmakedefine _LIBCPP_HAS_NO_TIME_ZONE_DATABASE +#cmakedefine _LIBCPP_INSTRUMENTED_WITH_ASAN // PSTL backends #cmakedefine _LIBCPP_PSTL_CPU_BACKEND_SERIAL diff --git a/libcxx/include/__coroutine/coroutine_handle.h b/libcxx/include/__coroutine/coroutine_handle.h index 4e4e3eb5ba3097eba9cf11de2dad386a40bbd9c0..54bfe5b44f4c6a2cc375aeb209cc920560c8e29b 100644 --- a/libcxx/include/__coroutine/coroutine_handle.h +++ b/libcxx/include/__coroutine/coroutine_handle.h @@ -32,166 +32,141 @@ struct _LIBCPP_TEMPLATE_VIS coroutine_handle; template <> struct _LIBCPP_TEMPLATE_VIS coroutine_handle { public: - // [coroutine.handle.con], construct/reset - constexpr coroutine_handle() noexcept = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr coroutine_handle(nullptr_t) noexcept {} - - _LIBCPP_HIDE_FROM_ABI - coroutine_handle& operator=(nullptr_t) noexcept { - __handle_ = nullptr; - return *this; - } - - // [coroutine.handle.export.import], export/import - _LIBCPP_HIDE_FROM_ABI - constexpr void* address() const noexcept { return __handle_; } - - _LIBCPP_HIDE_FROM_ABI - static constexpr coroutine_handle from_address(void* __addr) noexcept { - coroutine_handle __tmp; - __tmp.__handle_ = __addr; - return __tmp; - } - - // [coroutine.handle.observers], observers - _LIBCPP_HIDE_FROM_ABI - constexpr explicit operator bool() const noexcept { - return __handle_ != nullptr; - } - - _LIBCPP_HIDE_FROM_ABI - bool done() const { - _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "done() can be called only on suspended coroutines"); - return __builtin_coro_done(__handle_); - } - - // [coroutine.handle.resumption], resumption - _LIBCPP_HIDE_FROM_ABI - void operator()() const { resume(); } - - _LIBCPP_HIDE_FROM_ABI - void resume() const { - _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "resume() can be called only on suspended coroutines"); - _LIBCPP_ASSERT_UNCATEGORIZED(!done(), "resume() has undefined behavior when the coroutine is done"); - __builtin_coro_resume(__handle_); - } - - _LIBCPP_HIDE_FROM_ABI - void destroy() const { - _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "destroy() can be called only on suspended coroutines"); - __builtin_coro_destroy(__handle_); - } + // [coroutine.handle.con], construct/reset + constexpr coroutine_handle() noexcept = default; + + _LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {} + + _LIBCPP_HIDE_FROM_ABI coroutine_handle& operator=(nullptr_t) noexcept { + __handle_ = nullptr; + return *this; + } + + // [coroutine.handle.export.import], export/import + _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } + + _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept { + coroutine_handle __tmp; + __tmp.__handle_ = __addr; + return __tmp; + } + + // [coroutine.handle.observers], observers + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; } + + _LIBCPP_HIDE_FROM_ABI bool done() const { + _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "done() can be called only on suspended coroutines"); + return __builtin_coro_done(__handle_); + } + + // [coroutine.handle.resumption], resumption + _LIBCPP_HIDE_FROM_ABI void operator()() const { resume(); } + + _LIBCPP_HIDE_FROM_ABI void resume() const { + _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "resume() can be called only on suspended coroutines"); + _LIBCPP_ASSERT_UNCATEGORIZED(!done(), "resume() has undefined behavior when the coroutine is done"); + __builtin_coro_resume(__handle_); + } + + _LIBCPP_HIDE_FROM_ABI void destroy() const { + _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "destroy() can be called only on suspended coroutines"); + __builtin_coro_destroy(__handle_); + } private: - _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const { - // FIXME actually implement a check for if the coro is suspended. - return __handle_ != nullptr; - } + _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const { + // FIXME actually implement a check for if the coro is suspended. + return __handle_ != nullptr; + } - void* __handle_ = nullptr; + void* __handle_ = nullptr; }; // [coroutine.handle.compare] -inline _LIBCPP_HIDE_FROM_ABI -constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { - return __x.address() == __y.address(); +inline _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { + return __x.address() == __y.address(); } -inline _LIBCPP_HIDE_FROM_ABI -constexpr strong_ordering operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { - return compare_three_way()(__x.address(), __y.address()); +inline _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering +operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { + return compare_three_way()(__x.address(), __y.address()); } template struct _LIBCPP_TEMPLATE_VIS coroutine_handle { public: - // [coroutine.handle.con], construct/reset - constexpr coroutine_handle() noexcept = default; - - _LIBCPP_HIDE_FROM_ABI - constexpr coroutine_handle(nullptr_t) noexcept {} - - _LIBCPP_HIDE_FROM_ABI - static coroutine_handle from_promise(_Promise& __promise) { - using _RawPromise = __remove_cv_t<_Promise>; - coroutine_handle __tmp; - __tmp.__handle_ = - __builtin_coro_promise(std::addressof(const_cast<_RawPromise&>(__promise)), alignof(_Promise), true); - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI - coroutine_handle& operator=(nullptr_t) noexcept { - __handle_ = nullptr; - return *this; - } - - // [coroutine.handle.export.import], export/import - _LIBCPP_HIDE_FROM_ABI - constexpr void* address() const noexcept { return __handle_; } - - _LIBCPP_HIDE_FROM_ABI - static constexpr coroutine_handle from_address(void* __addr) noexcept { - coroutine_handle __tmp; - __tmp.__handle_ = __addr; - return __tmp; - } - - // [coroutine.handle.conv], conversion - _LIBCPP_HIDE_FROM_ABI - constexpr operator coroutine_handle<>() const noexcept { - return coroutine_handle<>::from_address(address()); - } - - // [coroutine.handle.observers], observers - _LIBCPP_HIDE_FROM_ABI - constexpr explicit operator bool() const noexcept { - return __handle_ != nullptr; - } - - _LIBCPP_HIDE_FROM_ABI - bool done() const { - _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "done() can be called only on suspended coroutines"); - return __builtin_coro_done(__handle_); - } - - // [coroutine.handle.resumption], resumption - _LIBCPP_HIDE_FROM_ABI - void operator()() const { resume(); } - - _LIBCPP_HIDE_FROM_ABI - void resume() const { - _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "resume() can be called only on suspended coroutines"); - _LIBCPP_ASSERT_UNCATEGORIZED(!done(), "resume() has undefined behavior when the coroutine is done"); - __builtin_coro_resume(__handle_); - } - - _LIBCPP_HIDE_FROM_ABI - void destroy() const { - _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "destroy() can be called only on suspended coroutines"); - __builtin_coro_destroy(__handle_); - } - - // [coroutine.handle.promise], promise access - _LIBCPP_HIDE_FROM_ABI - _Promise& promise() const { - return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false)); - } + // [coroutine.handle.con], construct/reset + constexpr coroutine_handle() noexcept = default; + + _LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {} + + _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) { + using _RawPromise = __remove_cv_t<_Promise>; + coroutine_handle __tmp; + __tmp.__handle_ = + __builtin_coro_promise(std::addressof(const_cast<_RawPromise&>(__promise)), alignof(_Promise), true); + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI coroutine_handle& operator=(nullptr_t) noexcept { + __handle_ = nullptr; + return *this; + } + + // [coroutine.handle.export.import], export/import + _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } + + _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept { + coroutine_handle __tmp; + __tmp.__handle_ = __addr; + return __tmp; + } + + // [coroutine.handle.conv], conversion + _LIBCPP_HIDE_FROM_ABI constexpr operator coroutine_handle<>() const noexcept { + return coroutine_handle<>::from_address(address()); + } + + // [coroutine.handle.observers], observers + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; } + + _LIBCPP_HIDE_FROM_ABI bool done() const { + _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "done() can be called only on suspended coroutines"); + return __builtin_coro_done(__handle_); + } + + // [coroutine.handle.resumption], resumption + _LIBCPP_HIDE_FROM_ABI void operator()() const { resume(); } + + _LIBCPP_HIDE_FROM_ABI void resume() const { + _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "resume() can be called only on suspended coroutines"); + _LIBCPP_ASSERT_UNCATEGORIZED(!done(), "resume() has undefined behavior when the coroutine is done"); + __builtin_coro_resume(__handle_); + } + + _LIBCPP_HIDE_FROM_ABI void destroy() const { + _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "destroy() can be called only on suspended coroutines"); + __builtin_coro_destroy(__handle_); + } + + // [coroutine.handle.promise], promise access + _LIBCPP_HIDE_FROM_ABI _Promise& promise() const { + return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false)); + } private: - _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const { - // FIXME actually implement a check for if the coro is suspended. - return __handle_ != nullptr; - } - void* __handle_ = nullptr; + _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const { + // FIXME actually implement a check for if the coro is suspended. + return __handle_ != nullptr; + } + void* __handle_ = nullptr; }; // [coroutine.handle.hash] template struct hash> { - _LIBCPP_HIDE_FROM_ABI - size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { return hash()(__v.address()); } + _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { + return hash()(__v.address()); + } }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__coroutine/coroutine_traits.h b/libcxx/include/__coroutine/coroutine_traits.h index 7122cc8ea8fb2c6b6ff0fdef7433dd6d34f0fb19..78f05341f7486af5b7aa911b52e517033ba37359 100644 --- a/libcxx/include/__coroutine/coroutine_traits.h +++ b/libcxx/include/__coroutine/coroutine_traits.h @@ -34,17 +34,12 @@ template struct __coroutine_traits_sfinae {}; template -struct __coroutine_traits_sfinae< - _Tp, __void_t > -{ +struct __coroutine_traits_sfinae< _Tp, __void_t > { using promise_type = typename _Tp::promise_type; }; template -struct coroutine_traits - : public __coroutine_traits_sfinae<_Ret> -{ -}; +struct coroutine_traits : public __coroutine_traits_sfinae<_Ret> {}; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__coroutine/noop_coroutine_handle.h b/libcxx/include/__coroutine/noop_coroutine_handle.h index 9b7802d1e2827a8858ab7d1cc6ccc97d13fbe52e..da13d579604b55ca33d040617adfb09cab863681 100644 --- a/libcxx/include/__coroutine/noop_coroutine_handle.h +++ b/libcxx/include/__coroutine/noop_coroutine_handle.h @@ -20,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) +# if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) // [coroutine.noop] // [coroutine.promise.noop] @@ -30,80 +30,67 @@ struct noop_coroutine_promise {}; template <> struct _LIBCPP_TEMPLATE_VIS coroutine_handle { public: - // [coroutine.handle.noop.conv], conversion - _LIBCPP_HIDE_FROM_ABI - constexpr operator coroutine_handle<>() const noexcept { - return coroutine_handle<>::from_address(address()); - } - - // [coroutine.handle.noop.observers], observers - _LIBCPP_HIDE_FROM_ABI - constexpr explicit operator bool() const noexcept { return true; } - _LIBCPP_HIDE_FROM_ABI - constexpr bool done() const noexcept { return false; } - - // [coroutine.handle.noop.resumption], resumption - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()() const noexcept {} - _LIBCPP_HIDE_FROM_ABI - constexpr void resume() const noexcept {} - _LIBCPP_HIDE_FROM_ABI - constexpr void destroy() const noexcept {} - - // [coroutine.handle.noop.promise], promise access - _LIBCPP_HIDE_FROM_ABI - noop_coroutine_promise& promise() const noexcept { - return *static_cast( - __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false)); - } - - // [coroutine.handle.noop.address], address - _LIBCPP_HIDE_FROM_ABI - constexpr void* address() const noexcept { return __handle_; } + // [coroutine.handle.noop.conv], conversion + _LIBCPP_HIDE_FROM_ABI constexpr operator coroutine_handle<>() const noexcept { + return coroutine_handle<>::from_address(address()); + } + + // [coroutine.handle.noop.observers], observers + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return true; } + _LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; } + + // [coroutine.handle.noop.resumption], resumption + _LIBCPP_HIDE_FROM_ABI constexpr void operator()() const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr void resume() const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr void destroy() const noexcept {} + + // [coroutine.handle.noop.promise], promise access + _LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept { + return *static_cast( + __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false)); + } + + // [coroutine.handle.noop.address], address + _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } private: - _LIBCPP_HIDE_FROM_ABI - friend coroutine_handle noop_coroutine() noexcept; + _LIBCPP_HIDE_FROM_ABI friend coroutine_handle noop_coroutine() noexcept; -#if __has_builtin(__builtin_coro_noop) - _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { - this->__handle_ = __builtin_coro_noop(); - } +# if __has_builtin(__builtin_coro_noop) + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { this->__handle_ = __builtin_coro_noop(); } - void* __handle_ = nullptr; + void* __handle_ = nullptr; -#elif defined(_LIBCPP_COMPILER_GCC) - // GCC doesn't implement __builtin_coro_noop(). - // Construct the coroutine frame manually instead. - struct __noop_coroutine_frame_ty_ { - static void __dummy_resume_destroy_func() { } +# elif defined(_LIBCPP_COMPILER_GCC) + // GCC doesn't implement __builtin_coro_noop(). + // Construct the coroutine frame manually instead. + struct __noop_coroutine_frame_ty_ { + static void __dummy_resume_destroy_func() {} - void (*__resume_)() = __dummy_resume_destroy_func; - void (*__destroy_)() = __dummy_resume_destroy_func; - struct noop_coroutine_promise __promise_; - }; + void (*__resume_)() = __dummy_resume_destroy_func; + void (*__destroy_)() = __dummy_resume_destroy_func; + struct noop_coroutine_promise __promise_; + }; - static __noop_coroutine_frame_ty_ __noop_coroutine_frame_; + static __noop_coroutine_frame_ty_ __noop_coroutine_frame_; - void* __handle_ = &__noop_coroutine_frame_; + void* __handle_ = &__noop_coroutine_frame_; - _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default; + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default; -#endif // __has_builtin(__builtin_coro_noop) +# endif // __has_builtin(__builtin_coro_noop) }; using noop_coroutine_handle = coroutine_handle; -#if defined(_LIBCPP_COMPILER_GCC) -inline noop_coroutine_handle::__noop_coroutine_frame_ty_ - noop_coroutine_handle::__noop_coroutine_frame_{}; -#endif +# if defined(_LIBCPP_COMPILER_GCC) +inline noop_coroutine_handle::__noop_coroutine_frame_ty_ noop_coroutine_handle::__noop_coroutine_frame_{}; +# endif // [coroutine.noop.coroutine] -inline _LIBCPP_HIDE_FROM_ABI -noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } +inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } -#endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) +# endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__coroutine/trivial_awaitables.h b/libcxx/include/__coroutine/trivial_awaitables.h index 0e4b08e377c0e72de93ae29d2a8dbf1e3f590bc9..b604bd3c2d8ad2bc38fc8a76fc12d2b08379dc37 100644 --- a/libcxx/include/__coroutine/trivial_awaitables.h +++ b/libcxx/include/__coroutine/trivial_awaitables.h @@ -22,21 +22,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [coroutine.trivial.awaitables] struct suspend_never { - _LIBCPP_HIDE_FROM_ABI - constexpr bool await_ready() const noexcept { return true; } - _LIBCPP_HIDE_FROM_ABI - constexpr void await_suspend(coroutine_handle<>) const noexcept {} - _LIBCPP_HIDE_FROM_ABI - constexpr void await_resume() const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr bool await_ready() const noexcept { return true; } + _LIBCPP_HIDE_FROM_ABI constexpr void await_suspend(coroutine_handle<>) const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr void await_resume() const noexcept {} }; struct suspend_always { - _LIBCPP_HIDE_FROM_ABI - constexpr bool await_ready() const noexcept { return false; } - _LIBCPP_HIDE_FROM_ABI - constexpr void await_suspend(coroutine_handle<>) const noexcept {} - _LIBCPP_HIDE_FROM_ABI - constexpr void await_resume() const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr bool await_ready() const noexcept { return false; } + _LIBCPP_HIDE_FROM_ABI constexpr void await_suspend(coroutine_handle<>) const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr void await_resume() const noexcept {} }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__debug_utils/randomize_range.h b/libcxx/include/__debug_utils/randomize_range.h index dce61923bc9c863c488efacfed5a2fa6f572b783..7eb77d81ab2a3db2866c4916c39c3eb1e95c7b5f 100644 --- a/libcxx/include/__debug_utils/randomize_range.h +++ b/libcxx/include/__debug_utils/randomize_range.h @@ -23,8 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __debug_randomize_range(_Iterator __first, _Sentinel __last) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __debug_randomize_range(_Iterator __first, _Sentinel __last) { #ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY # ifdef _LIBCPP_CXX03_LANG # error Support for unspecified stability is only for C++11 and higher diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h index bf16c8f720d2681580e8a0da2ff3298c12fc36c8..97f92bdfe44c4e5581ad5a1cbedeb5ab4e4887ce 100644 --- a/libcxx/include/__expected/expected.h +++ b/libcxx/include/__expected/expected.h @@ -90,19 +90,14 @@ _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) { template class expected { - static_assert( - !is_reference_v<_Tp> && - !is_function_v<_Tp> && - !is_same_v, in_place_t> && - !is_same_v, unexpect_t> && - !__is_std_unexpected>::value && - __valid_std_unexpected<_Err>::value - , - "[expected.object.general] A program that instantiates the definition of template expected for a " - "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a " - "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the " - "definition of the template expected with a type for the E parameter that is not a valid " - "template argument for unexpected is ill-formed."); + static_assert(!is_reference_v<_Tp> && !is_function_v<_Tp> && !is_same_v, in_place_t> && + !is_same_v, unexpect_t> && !__is_std_unexpected>::value && + __valid_std_unexpected<_Err>::value, + "[expected.object.general] A program that instantiates the definition of template expected for a " + "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a " + "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the " + "definition of the template expected with a type for the E parameter that is not a valid " + "template argument for unexpected is ill-formed."); template friend class expected; @@ -116,36 +111,33 @@ public: using rebind = expected<_Up, error_type>; // [expected.object.ctor], constructors - _LIBCPP_HIDE_FROM_ABI constexpr expected() - noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened requires is_default_constructible_v<_Tp> : __union_(std::in_place), __has_val_(true) {} _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) - requires(is_copy_constructible_v<_Tp> && - is_copy_constructible_v<_Err> && - is_trivially_copy_constructible_v<_Tp> && + requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>) = default; - _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other) - noexcept(is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other) noexcept( + is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>)) - : __union_(__other.__has_val_, __other.__union_), __has_val_(__other.__has_val_) { } + : __union_(__other.__has_val_, __other.__union_), __has_val_(__other.__has_val_) {} _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) - requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> - && is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>) + requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Tp> && + is_trivially_move_constructible_v<_Err>) = default; - _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other) - noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>) + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other) noexcept( + is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>) requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)) - : __union_(__other.__has_val_, std::move(__other.__union_)), __has_val_(__other.__has_val_) { } + : __union_(__other.__has_val_, std::move(__other.__union_)), __has_val_(__other.__has_val_) {} private: template @@ -182,16 +174,16 @@ public: requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v || !is_convertible_v) - expected(const expected<_Up, _OtherErr>& __other) - noexcept(is_nothrow_constructible_v<_Tp, const _Up&> && - is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + expected(const expected<_Up, _OtherErr>& __other) noexcept( + is_nothrow_constructible_v<_Tp, const _Up&> && + is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened : __union_(__other.__has_val_, __other.__union_), __has_val_(__other.__has_val_) {} template requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>) - expected(expected<_Up, _OtherErr>&& __other) - noexcept(is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + expected(expected<_Up, _OtherErr>&& __other) noexcept( + is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened : __union_(__other.__has_val_, std::move(__other.__union_)), __has_val_(__other.__has_val_) {} template @@ -204,42 +196,38 @@ public: template requires is_constructible_v<_Err, const _OtherErr&> - _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) - expected(const unexpected<_OtherErr>& __unex) - noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) expected( + const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened : __union_(std::unexpect, __unex.error()), __has_val_(false) {} template requires is_constructible_v<_Err, _OtherErr> _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) - expected(unexpected<_OtherErr>&& __unex) - noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened : __union_(std::unexpect, std::move(__unex.error())), __has_val_(false) {} template requires is_constructible_v<_Tp, _Args...> - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Tp, _Args...>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Tp, _Args...>) // strengthened : __union_(std::in_place, std::forward<_Args>(__args)...), __has_val_(true) {} template requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... > - _LIBCPP_HIDE_FROM_ABI constexpr explicit - expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened : __union_(std::in_place, __il, std::forward<_Args>(__args)...), __has_val_(true) {} template requires is_constructible_v<_Err, _Args...> - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Err, _Args...>) // strengthened : __union_(std::unexpect, std::forward<_Args>(__args)...), __has_val_(false) {} template requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > - _LIBCPP_HIDE_FROM_ABI constexpr explicit - expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened : __union_(std::unexpect, __il, std::forward<_Args>(__args)...), __has_val_(false) {} // [expected.object.dtor], destructor @@ -286,17 +274,12 @@ public: // [expected.object.assign], assignment _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; - _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) - noexcept(is_nothrow_copy_assignable_v<_Tp> && - is_nothrow_copy_constructible_v<_Tp> && - is_nothrow_copy_assignable_v<_Err> && - is_nothrow_copy_constructible_v<_Err>) // strengthened - requires(is_copy_assignable_v<_Tp> && - is_copy_constructible_v<_Tp> && - is_copy_assignable_v<_Err> && + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) noexcept( + is_nothrow_copy_assignable_v<_Tp> && is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_assignable_v<_Err> && + is_nothrow_copy_constructible_v<_Err>) // strengthened + requires(is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp> && is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err> && - (is_nothrow_move_constructible_v<_Tp> || - is_nothrow_move_constructible_v<_Err>)) + (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) { if (__has_val_ && __rhs.__has_val_) { __union_.__val_ = __rhs.__union_.__val_; @@ -312,17 +295,12 @@ public: return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs) - noexcept(is_nothrow_move_assignable_v<_Tp> && - is_nothrow_move_constructible_v<_Tp> && - is_nothrow_move_assignable_v<_Err> && - is_nothrow_move_constructible_v<_Err>) - requires(is_move_constructible_v<_Tp> && - is_move_assignable_v<_Tp> && - is_move_constructible_v<_Err> && + _LIBCPP_HIDE_FROM_ABI constexpr expected& + operator=(expected&& __rhs) noexcept(is_nothrow_move_assignable_v<_Tp> && is_nothrow_move_constructible_v<_Tp> && + is_nothrow_move_assignable_v<_Err> && is_nothrow_move_constructible_v<_Err>) + requires(is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp> && is_move_constructible_v<_Err> && is_move_assignable_v<_Err> && - (is_nothrow_move_constructible_v<_Tp> || - is_nothrow_move_constructible_v<_Err>)) + (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) { if (__has_val_ && __rhs.__has_val_) { __union_.__val_ = std::move(__rhs.__union_.__val_); @@ -340,12 +318,9 @@ public: template _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v) - requires(!is_same_v> && - !__is_std_unexpected>::value && - is_constructible_v<_Tp, _Up> && - is_assignable_v<_Tp&, _Up> && - (is_nothrow_constructible_v<_Tp, _Up> || - is_nothrow_move_constructible_v<_Tp> || + requires(!is_same_v> && !__is_std_unexpected>::value && + is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up> && + (is_nothrow_constructible_v<_Tp, _Up> || is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) { if (__has_val_) { @@ -418,20 +393,14 @@ public: return __union_.__val_; } - public: // [expected.object.swap], swap - _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs) - noexcept(is_nothrow_move_constructible_v<_Tp> && - is_nothrow_swappable_v<_Tp> && - is_nothrow_move_constructible_v<_Err> && - is_nothrow_swappable_v<_Err>) - requires(is_swappable_v<_Tp> && - is_swappable_v<_Err> && - is_move_constructible_v<_Tp> && + _LIBCPP_HIDE_FROM_ABI constexpr void + swap(expected& __rhs) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp> && + is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) + requires(is_swappable_v<_Tp> && is_swappable_v<_Err> && is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && - (is_nothrow_move_constructible_v<_Tp> || - is_nothrow_move_constructible_v<_Err>)) + (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) { auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) { if constexpr (is_nothrow_move_constructible_v<_Err>) { @@ -479,8 +448,7 @@ public: } } - _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) - noexcept(noexcept(__x.swap(__y))) + _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) noexcept(noexcept(__x.swap(__y))) requires requires { __x.swap(__y); } { __x.swap(__y); @@ -724,7 +692,8 @@ public: return expected<_Up, _Err>(unexpect, error()); } if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), __union_.__val_); + return expected<_Up, _Err>( + __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), __union_.__val_); } else { std::invoke(std::forward<_Func>(__f), __union_.__val_); return expected<_Up, _Err>(); @@ -739,7 +708,8 @@ public: return expected<_Up, _Err>(unexpect, error()); } if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), __union_.__val_); + return expected<_Up, _Err>( + __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), __union_.__val_); } else { std::invoke(std::forward<_Func>(__f), __union_.__val_); return expected<_Up, _Err>(); @@ -900,7 +870,7 @@ private: template requires(is_trivially_move_constructible_v<_ValueType> && is_trivially_move_constructible_v<_ErrorType>) union __union_t<_ValueType, _ErrorType> { - _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = default; _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = default; template @@ -982,8 +952,8 @@ public: requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>) = default; - _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) - noexcept(is_nothrow_copy_constructible_v<_Err>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) noexcept( + is_nothrow_copy_constructible_v<_Err>) // strengthened requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>) : __union_(__rhs.__has_val_, __rhs.__union_), __has_val_(__rhs.__has_val_) {} @@ -991,51 +961,47 @@ public: requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>) = default; - _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) - noexcept(is_nothrow_move_constructible_v<_Err>) + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) noexcept(is_nothrow_move_constructible_v<_Err>) requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>) : __union_(__rhs.__has_val_, std::move(__rhs.__union_)), __has_val_(__rhs.__has_val_) {} template requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) - expected(const expected<_Up, _OtherErr>& __rhs) - noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + expected(const expected<_Up, _OtherErr>& __rhs) noexcept( + is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened : __union_(__rhs.__has_val_, __rhs.__union_), __has_val_(__rhs.__has_val_) {} template requires __can_convert<_Up, _OtherErr, _OtherErr>::value _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) - expected(expected<_Up, _OtherErr>&& __rhs) - noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + expected(expected<_Up, _OtherErr>&& __rhs) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened : __union_(__rhs.__has_val_, std::move(__rhs.__union_)), __has_val_(__rhs.__has_val_) {} template requires is_constructible_v<_Err, const _OtherErr&> - _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) - expected(const unexpected<_OtherErr>& __unex) - noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) expected( + const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened : __union_(std::unexpect, __unex.error()), __has_val_(false) {} template requires is_constructible_v<_Err, _OtherErr> _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) - expected(unexpected<_OtherErr>&& __unex) - noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened : __union_(std::unexpect, std::move(__unex.error())), __has_val_(false) {} _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {} template requires is_constructible_v<_Err, _Args...> - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Err, _Args...>) // strengthened : __union_(std::unexpect, std::forward<_Args>(__args)...), __has_val_(false) {} template requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened : __union_(std::unexpect, __il, std::forward<_Args>(__args)...), __has_val_(false) {} private: @@ -1069,8 +1035,8 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; - _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) - noexcept(is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) noexcept( + is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>) { if (__has_val_) { @@ -1091,11 +1057,9 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete; - _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs) - noexcept(is_nothrow_move_assignable_v<_Err> && - is_nothrow_move_constructible_v<_Err>) - requires(is_move_assignable_v<_Err> && - is_move_constructible_v<_Err>) + _LIBCPP_HIDE_FROM_ABI constexpr expected& + operator=(expected&& __rhs) noexcept(is_nothrow_move_assignable_v<_Err> && is_nothrow_move_constructible_v<_Err>) + requires(is_move_assignable_v<_Err> && is_move_constructible_v<_Err>) { if (__has_val_) { if (!__rhs.__has_val_) { @@ -1145,8 +1109,8 @@ public: } // [expected.void.swap], swap - _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs) - noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) + _LIBCPP_HIDE_FROM_ABI constexpr void + swap(expected& __rhs) noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>) { auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) { @@ -1170,8 +1134,7 @@ public: } } - _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) - noexcept(noexcept(__x.swap(__y))) + _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) noexcept(noexcept(__x.swap(__y))) requires requires { __x.swap(__y); } { __x.swap(__y); @@ -1318,8 +1281,8 @@ public: template _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && { using _Gp = remove_cvref_t>; - static_assert(__is_std_expected<_Gp>::value, - "The result of f(std::move(error())) must be a specialization of std::expected"); + static_assert( + __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected"); static_assert(is_same_v, "The result of f(std::move(error())) must have the same value_type as this expected"); if (has_value()) { @@ -1331,8 +1294,8 @@ public: template _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& { using _Gp = remove_cvref_t>; - static_assert(__is_std_expected<_Gp>::value, - "The result of f(std::move(error())) must be a specialization of std::expected"); + static_assert( + __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected"); static_assert(is_same_v, "The result of f(std::move(error())) must have the same value_type as this expected"); if (has_value()) { @@ -1506,7 +1469,7 @@ private: requires is_trivially_move_constructible_v<_ErrorType> union __union_t<_ErrorType> { _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} - _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = default; _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = default; template diff --git a/libcxx/include/__filesystem/copy_options.h b/libcxx/include/__filesystem/copy_options.h index 60cab4ee69737a41ecd64adedcf89bc6d24628de..1bf71292c8a66b089dc19e2630b6137a61459561 100644 --- a/libcxx/include/__filesystem/copy_options.h +++ b/libcxx/include/__filesystem/copy_options.h @@ -22,54 +22,44 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM enum class copy_options : unsigned short { - none = 0, - skip_existing = 1, - overwrite_existing = 2, - update_existing = 4, - recursive = 8, - copy_symlinks = 16, - skip_symlinks = 32, - directories_only = 64, - create_symlinks = 128, - create_hard_links = 256, + none = 0, + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + recursive = 8, + copy_symlinks = 16, + skip_symlinks = 32, + directories_only = 64, + create_symlinks = 128, + create_hard_links = 256, __in_recursive_copy = 512, }; -_LIBCPP_HIDE_FROM_ABI -inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) { - return static_cast(static_cast(__lhs) & - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) & static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) { - return static_cast(static_cast(__lhs) | - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) | static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) { - return static_cast(static_cast(__lhs) ^ - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) ^ static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr copy_options operator~(copy_options __lhs) { +_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator~(copy_options __lhs) { return static_cast(~static_cast(__lhs)); } -_LIBCPP_HIDE_FROM_ABI -inline copy_options& operator&=(copy_options& __lhs, copy_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline copy_options& operator&=(copy_options& __lhs, copy_options __rhs) { return __lhs = __lhs & __rhs; } -_LIBCPP_HIDE_FROM_ABI -inline copy_options& operator|=(copy_options& __lhs, copy_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline copy_options& operator|=(copy_options& __lhs, copy_options __rhs) { return __lhs = __lhs | __rhs; } -_LIBCPP_HIDE_FROM_ABI -inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) { return __lhs = __lhs ^ __rhs; } diff --git a/libcxx/include/__filesystem/directory_entry.h b/libcxx/include/__filesystem/directory_entry.h index fe3cace853d65b23f977f3206b0525ddc0736ddd..016ad94a853dc273213b93f24539e78b7b75fde9 100644 --- a/libcxx/include/__filesystem/directory_entry.h +++ b/libcxx/include/__filesystem/directory_entry.h @@ -45,219 +45,149 @@ class directory_entry { public: // constructors and destructors - _LIBCPP_HIDE_FROM_ABI directory_entry() noexcept = default; - _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry const&) = default; + _LIBCPP_HIDE_FROM_ABI directory_entry() noexcept = default; + _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry const&) = default; _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry&&) noexcept = default; - _LIBCPP_HIDE_FROM_ABI - explicit directory_entry(_Path const& __p) : __p_(__p) { + _LIBCPP_HIDE_FROM_ABI explicit directory_entry(_Path const& __p) : __p_(__p) { error_code __ec; __refresh(&__ec); } - _LIBCPP_HIDE_FROM_ABI - directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { - __refresh(&__ec); - } + _LIBCPP_HIDE_FROM_ABI directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { __refresh(&__ec); } _LIBCPP_HIDE_FROM_ABI ~directory_entry() {} - _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry const&) = default; + _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry const&) = default; _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry&&) noexcept = default; - _LIBCPP_HIDE_FROM_ABI - void assign(_Path const& __p) { + _LIBCPP_HIDE_FROM_ABI void assign(_Path const& __p) { __p_ = __p; error_code __ec; __refresh(&__ec); } - _LIBCPP_HIDE_FROM_ABI - void assign(_Path const& __p, error_code& __ec) { + _LIBCPP_HIDE_FROM_ABI void assign(_Path const& __p, error_code& __ec) { __p_ = __p; __refresh(&__ec); } - _LIBCPP_HIDE_FROM_ABI - void replace_filename(_Path const& __p) { + _LIBCPP_HIDE_FROM_ABI void replace_filename(_Path const& __p) { __p_.replace_filename(__p); error_code __ec; __refresh(&__ec); } - _LIBCPP_HIDE_FROM_ABI - void replace_filename(_Path const& __p, error_code& __ec) { + _LIBCPP_HIDE_FROM_ABI void replace_filename(_Path const& __p, error_code& __ec) { __p_ = __p_.parent_path() / __p; __refresh(&__ec); } - _LIBCPP_HIDE_FROM_ABI - void refresh() { __refresh(); } + _LIBCPP_HIDE_FROM_ABI void refresh() { __refresh(); } - _LIBCPP_HIDE_FROM_ABI - void refresh(error_code& __ec) noexcept { __refresh(&__ec); } + _LIBCPP_HIDE_FROM_ABI void refresh(error_code& __ec) noexcept { __refresh(&__ec); } - _LIBCPP_HIDE_FROM_ABI - _Path const& path() const noexcept { return __p_; } + _LIBCPP_HIDE_FROM_ABI _Path const& path() const noexcept { return __p_; } - _LIBCPP_HIDE_FROM_ABI - operator const _Path&() const noexcept { return __p_; } + _LIBCPP_HIDE_FROM_ABI operator const _Path&() const noexcept { return __p_; } - _LIBCPP_HIDE_FROM_ABI - bool exists() const { return filesystem::exists(file_status{__get_ft()}); } + _LIBCPP_HIDE_FROM_ABI bool exists() const { return filesystem::exists(file_status{__get_ft()}); } - _LIBCPP_HIDE_FROM_ABI - bool exists(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool exists(error_code& __ec) const noexcept { return filesystem::exists(file_status{__get_ft(&__ec)}); } - _LIBCPP_HIDE_FROM_ABI - bool is_block_file() const { return __get_ft() == file_type::block; } + _LIBCPP_HIDE_FROM_ABI bool is_block_file() const { return __get_ft() == file_type::block; } - _LIBCPP_HIDE_FROM_ABI - bool is_block_file(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_block_file(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::block; } - _LIBCPP_HIDE_FROM_ABI - bool is_character_file() const { return __get_ft() == file_type::character; } + _LIBCPP_HIDE_FROM_ABI bool is_character_file() const { return __get_ft() == file_type::character; } - _LIBCPP_HIDE_FROM_ABI - bool is_character_file(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_character_file(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::character; } - _LIBCPP_HIDE_FROM_ABI - bool is_directory() const { return __get_ft() == file_type::directory; } + _LIBCPP_HIDE_FROM_ABI bool is_directory() const { return __get_ft() == file_type::directory; } - _LIBCPP_HIDE_FROM_ABI - bool is_directory(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_directory(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::directory; } - _LIBCPP_HIDE_FROM_ABI - bool is_fifo() const { return __get_ft() == file_type::fifo; } + _LIBCPP_HIDE_FROM_ABI bool is_fifo() const { return __get_ft() == file_type::fifo; } - _LIBCPP_HIDE_FROM_ABI - bool is_fifo(error_code& __ec) const noexcept { - return __get_ft(&__ec) == file_type::fifo; - } + _LIBCPP_HIDE_FROM_ABI bool is_fifo(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::fifo; } - _LIBCPP_HIDE_FROM_ABI - bool is_other() const { return filesystem::is_other(file_status{__get_ft()}); } + _LIBCPP_HIDE_FROM_ABI bool is_other() const { return filesystem::is_other(file_status{__get_ft()}); } - _LIBCPP_HIDE_FROM_ABI - bool is_other(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_other(error_code& __ec) const noexcept { return filesystem::is_other(file_status{__get_ft(&__ec)}); } - _LIBCPP_HIDE_FROM_ABI - bool is_regular_file() const { return __get_ft() == file_type::regular; } + _LIBCPP_HIDE_FROM_ABI bool is_regular_file() const { return __get_ft() == file_type::regular; } - _LIBCPP_HIDE_FROM_ABI - bool is_regular_file(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_regular_file(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::regular; } - _LIBCPP_HIDE_FROM_ABI - bool is_socket() const { return __get_ft() == file_type::socket; } + _LIBCPP_HIDE_FROM_ABI bool is_socket() const { return __get_ft() == file_type::socket; } - _LIBCPP_HIDE_FROM_ABI - bool is_socket(error_code& __ec) const noexcept { - return __get_ft(&__ec) == file_type::socket; - } + _LIBCPP_HIDE_FROM_ABI bool is_socket(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::socket; } - _LIBCPP_HIDE_FROM_ABI - bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } + _LIBCPP_HIDE_FROM_ABI bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } - _LIBCPP_HIDE_FROM_ABI - bool is_symlink(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_symlink(error_code& __ec) const noexcept { return __get_sym_ft(&__ec) == file_type::symlink; } - _LIBCPP_HIDE_FROM_ABI - uintmax_t file_size() const { return __get_size(); } + _LIBCPP_HIDE_FROM_ABI uintmax_t file_size() const { return __get_size(); } - _LIBCPP_HIDE_FROM_ABI - uintmax_t file_size(error_code& __ec) const noexcept { - return __get_size(&__ec); - } + _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(error_code& __ec) const noexcept { return __get_size(&__ec); } - _LIBCPP_HIDE_FROM_ABI - uintmax_t hard_link_count() const { return __get_nlink(); } + _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count() const { return __get_nlink(); } - _LIBCPP_HIDE_FROM_ABI - uintmax_t hard_link_count(error_code& __ec) const noexcept { - return __get_nlink(&__ec); - } + _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(error_code& __ec) const noexcept { return __get_nlink(&__ec); } - _LIBCPP_HIDE_FROM_ABI - file_time_type last_write_time() const { return __get_write_time(); } + _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time() const { return __get_write_time(); } - _LIBCPP_HIDE_FROM_ABI - file_time_type last_write_time(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(error_code& __ec) const noexcept { return __get_write_time(&__ec); } - _LIBCPP_HIDE_FROM_ABI - file_status status() const { return __get_status(); } + _LIBCPP_HIDE_FROM_ABI file_status status() const { return __get_status(); } - _LIBCPP_HIDE_FROM_ABI - file_status status(error_code& __ec) const noexcept { - return __get_status(&__ec); - } + _LIBCPP_HIDE_FROM_ABI file_status status(error_code& __ec) const noexcept { return __get_status(&__ec); } - _LIBCPP_HIDE_FROM_ABI - file_status symlink_status() const { return __get_symlink_status(); } + _LIBCPP_HIDE_FROM_ABI file_status symlink_status() const { return __get_symlink_status(); } - _LIBCPP_HIDE_FROM_ABI - file_status symlink_status(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI file_status symlink_status(error_code& __ec) const noexcept { return __get_symlink_status(&__ec); } + _LIBCPP_HIDE_FROM_ABI bool operator==(directory_entry const& __rhs) const noexcept { return __p_ == __rhs.__p_; } - _LIBCPP_HIDE_FROM_ABI - bool operator==(directory_entry const& __rhs) const noexcept { - return __p_ == __rhs.__p_; - } +# if _LIBCPP_STD_VER <= 17 + _LIBCPP_HIDE_FROM_ABI bool operator!=(directory_entry const& __rhs) const noexcept { return __p_ != __rhs.__p_; } -#if _LIBCPP_STD_VER <= 17 - _LIBCPP_HIDE_FROM_ABI - bool operator!=(directory_entry const& __rhs) const noexcept { - return __p_ != __rhs.__p_; - } + _LIBCPP_HIDE_FROM_ABI bool operator<(directory_entry const& __rhs) const noexcept { return __p_ < __rhs.__p_; } - _LIBCPP_HIDE_FROM_ABI - bool operator<(directory_entry const& __rhs) const noexcept { - return __p_ < __rhs.__p_; - } + _LIBCPP_HIDE_FROM_ABI bool operator<=(directory_entry const& __rhs) const noexcept { return __p_ <= __rhs.__p_; } - _LIBCPP_HIDE_FROM_ABI - bool operator<=(directory_entry const& __rhs) const noexcept { - return __p_ <= __rhs.__p_; - } + _LIBCPP_HIDE_FROM_ABI bool operator>(directory_entry const& __rhs) const noexcept { return __p_ > __rhs.__p_; } - _LIBCPP_HIDE_FROM_ABI - bool operator>(directory_entry const& __rhs) const noexcept { - return __p_ > __rhs.__p_; - } + _LIBCPP_HIDE_FROM_ABI bool operator>=(directory_entry const& __rhs) const noexcept { return __p_ >= __rhs.__p_; } - _LIBCPP_HIDE_FROM_ABI - bool operator>=(directory_entry const& __rhs) const noexcept { - return __p_ >= __rhs.__p_; - } - -#else // _LIBCPP_STD_VER <= 17 +# else // _LIBCPP_STD_VER <= 17 - _LIBCPP_HIDE_FROM_ABI - strong_ordering operator<=>(const directory_entry& __rhs) const noexcept { + _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const directory_entry& __rhs) const noexcept { return __p_ <=> __rhs.__p_; } -#endif // _LIBCPP_STD_VER <= 17 +# endif // _LIBCPP_STD_VER <= 17 template - _LIBCPP_HIDE_FROM_ABI - friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { + _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { return __os << __d.path(); } @@ -284,23 +214,20 @@ private: file_type __type_; _CacheType __cache_type_; - _LIBCPP_HIDE_FROM_ABI - __cached_data() noexcept { __reset(); } + _LIBCPP_HIDE_FROM_ABI __cached_data() noexcept { __reset(); } - _LIBCPP_HIDE_FROM_ABI - void __reset() { + _LIBCPP_HIDE_FROM_ABI void __reset() { __cache_type_ = _Empty; - __type_ = file_type::none; + __type_ = file_type::none; __sym_perms_ = __non_sym_perms_ = perms::unknown; __size_ = __nlink_ = uintmax_t(-1); - __write_time_ = file_time_type::min(); + __write_time_ = file_time_type::min(); } }; - _LIBCPP_HIDE_FROM_ABI - static __cached_data __create_iter_result(file_type __ft) { + _LIBCPP_HIDE_FROM_ABI static __cached_data __create_iter_result(file_type __ft) { __cached_data __data; - __data.__type_ = __ft; + __data.__type_ = __ft; __data.__cache_type_ = [&]() { switch (__ft) { case file_type::none: @@ -314,16 +241,14 @@ private: return __data; } - _LIBCPP_HIDE_FROM_ABI - void __assign_iter_entry(_Path&& __p, __cached_data __dt) { - __p_ = std::move(__p); + _LIBCPP_HIDE_FROM_ABI void __assign_iter_entry(_Path&& __p, __cached_data __dt) { + __p_ = std::move(__p); __data_ = __dt; } _LIBCPP_EXPORTED_FROM_ABI error_code __do_refresh() noexcept; - _LIBCPP_HIDE_FROM_ABI - static bool __is_dne_error(error_code const& __ec) { + _LIBCPP_HIDE_FROM_ABI static bool __is_dne_error(error_code const& __ec) { if (!__ec) return true; switch (static_cast(__ec.value())) { @@ -335,9 +260,8 @@ private: } } - _LIBCPP_HIDE_FROM_ABI - void __handle_error(const char* __msg, error_code* __dest_ec, - error_code const& __ec, bool __allow_dne = false) const { + _LIBCPP_HIDE_FROM_ABI void + __handle_error(const char* __msg, error_code* __dest_ec, error_code const& __ec, bool __allow_dne = false) const { if (__dest_ec) { *__dest_ec = __ec; return; @@ -346,14 +270,14 @@ private: __throw_filesystem_error(__msg, __p_, __ec); } - _LIBCPP_HIDE_FROM_ABI - void __refresh(error_code* __ec = nullptr) { - __handle_error("in directory_entry::refresh", __ec, __do_refresh(), + _LIBCPP_HIDE_FROM_ABI void __refresh(error_code* __ec = nullptr) { + __handle_error("in directory_entry::refresh", + __ec, + __do_refresh(), /*allow_dne*/ true); } - _LIBCPP_HIDE_FROM_ABI - file_type __get_sym_ft(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI file_type __get_sym_ft(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: return __symlink_status(__p_, __ec).type(); @@ -375,8 +299,7 @@ private: __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI - file_type __get_ft(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI file_type __get_ft(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterSymlink: @@ -396,8 +319,7 @@ private: __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI - file_status __get_status(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI file_status __get_status(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterNonSymlink: @@ -411,8 +333,7 @@ private: __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI - file_status __get_symlink_status(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI file_status __get_symlink_status(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterNonSymlink: @@ -427,8 +348,7 @@ private: __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI - uintmax_t __get_size(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI uintmax_t __get_size(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterNonSymlink: @@ -441,10 +361,8 @@ private: file_status __st(__get_ft(&__m_ec)); __handle_error("in directory_entry::file_size", __ec, __m_ec); if (filesystem::exists(__st) && !filesystem::is_regular_file(__st)) { - errc __err_kind = filesystem::is_directory(__st) ? errc::is_a_directory - : errc::not_supported; - __handle_error("in directory_entry::file_size", __ec, - make_error_code(__err_kind)); + errc __err_kind = filesystem::is_directory(__st) ? errc::is_a_directory : errc::not_supported; + __handle_error("in directory_entry::file_size", __ec, make_error_code(__err_kind)); } return __data_.__size_; } @@ -452,8 +370,7 @@ private: __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI - uintmax_t __get_nlink(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI uintmax_t __get_nlink(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterNonSymlink: @@ -471,8 +388,7 @@ private: __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI - file_time_type __get_write_time(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI file_time_type __get_write_time(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterNonSymlink: @@ -484,10 +400,8 @@ private: error_code __m_ec; file_status __st(__get_ft(&__m_ec)); __handle_error("in directory_entry::last_write_time", __ec, __m_ec); - if (filesystem::exists(__st) && - __data_.__write_time_ == file_time_type::min()) - __handle_error("in directory_entry::last_write_time", __ec, - make_error_code(errc::value_too_large)); + if (filesystem::exists(__st) && __data_.__write_time_ == file_time_type::min()) + __handle_error("in directory_entry::last_write_time", __ec, make_error_code(errc::value_too_large)); return __data_.__write_time_; } } @@ -501,16 +415,13 @@ private: class __dir_element_proxy { public: - inline _LIBCPP_HIDE_FROM_ABI directory_entry operator*() { - return std::move(__elem_); - } + inline _LIBCPP_HIDE_FROM_ABI directory_entry operator*() { return std::move(__elem_); } private: friend class directory_iterator; friend class recursive_directory_iterator; _LIBCPP_HIDE_FROM_ABI explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} - _LIBCPP_HIDE_FROM_ABI __dir_element_proxy(__dir_element_proxy&& __o) - : __elem_(std::move(__o.__elem_)) {} + _LIBCPP_HIDE_FROM_ABI __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(std::move(__o.__elem_)) {} directory_entry __elem_; }; diff --git a/libcxx/include/__filesystem/directory_iterator.h b/libcxx/include/__filesystem/directory_iterator.h index a2a48e59330766072329e35301d9b012ebda1212..29bd8da6caa467caa9e7e7165dd45cb9759417dd 100644 --- a/libcxx/include/__filesystem/directory_iterator.h +++ b/libcxx/include/__filesystem/directory_iterator.h @@ -45,33 +45,24 @@ public: typedef input_iterator_tag iterator_category; public: - //ctor & dtor - _LIBCPP_HIDE_FROM_ABI - directory_iterator() noexcept {} + // ctor & dtor + _LIBCPP_HIDE_FROM_ABI directory_iterator() noexcept {} - _LIBCPP_HIDE_FROM_ABI - explicit directory_iterator(const path& __p) - : directory_iterator(__p, nullptr) {} + _LIBCPP_HIDE_FROM_ABI explicit directory_iterator(const path& __p) : directory_iterator(__p, nullptr) {} - _LIBCPP_HIDE_FROM_ABI - directory_iterator(const path& __p, directory_options __opts) + _LIBCPP_HIDE_FROM_ABI directory_iterator(const path& __p, directory_options __opts) : directory_iterator(__p, nullptr, __opts) {} - _LIBCPP_HIDE_FROM_ABI - directory_iterator(const path& __p, error_code& __ec) - : directory_iterator(__p, &__ec) {} + _LIBCPP_HIDE_FROM_ABI directory_iterator(const path& __p, error_code& __ec) : directory_iterator(__p, &__ec) {} - _LIBCPP_HIDE_FROM_ABI - directory_iterator(const path& __p, directory_options __opts, - error_code& __ec) + _LIBCPP_HIDE_FROM_ABI directory_iterator(const path& __p, directory_options __opts, error_code& __ec) : directory_iterator(__p, &__ec, __opts) {} - _LIBCPP_HIDE_FROM_ABI directory_iterator(const directory_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI directory_iterator(directory_iterator&&) = default; + _LIBCPP_HIDE_FROM_ABI directory_iterator(const directory_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI directory_iterator(directory_iterator&&) = default; _LIBCPP_HIDE_FROM_ABI directory_iterator& operator=(const directory_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI - directory_iterator& operator=(directory_iterator&& __o) noexcept { + _LIBCPP_HIDE_FROM_ABI directory_iterator& operator=(directory_iterator&& __o) noexcept { // non-default implementation provided to support self-move assign. if (this != &__o) { __imp_ = std::move(__o.__imp_); @@ -81,27 +72,22 @@ public: _LIBCPP_HIDE_FROM_ABI ~directory_iterator() = default; - _LIBCPP_HIDE_FROM_ABI - const directory_entry& operator*() const { + _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const { _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "The end iterator cannot be dereferenced"); return __dereference(); } - _LIBCPP_HIDE_FROM_ABI - const directory_entry* operator->() const { return &**this; } + _LIBCPP_HIDE_FROM_ABI const directory_entry* operator->() const { return &**this; } - _LIBCPP_HIDE_FROM_ABI - directory_iterator& operator++() { return __increment(); } + _LIBCPP_HIDE_FROM_ABI directory_iterator& operator++() { return __increment(); } - _LIBCPP_HIDE_FROM_ABI - __dir_element_proxy operator++(int) { + _LIBCPP_HIDE_FROM_ABI __dir_element_proxy operator++(int) { __dir_element_proxy __p(**this); __increment(); return __p; } - _LIBCPP_HIDE_FROM_ABI - directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } + _LIBCPP_HIDE_FROM_ABI directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } # if _LIBCPP_STD_VER >= 20 @@ -111,8 +97,7 @@ public: private: inline _LIBCPP_HIDE_FROM_ABI friend bool - operator==(const directory_iterator& __lhs, - const directory_iterator& __rhs) noexcept; + operator==(const directory_iterator& __lhs, const directory_iterator& __rhs) noexcept; // construct the dir_stream _LIBCPP_EXPORTED_FROM_ABI directory_iterator(const path&, error_code*, directory_options = directory_options::none); @@ -126,43 +111,35 @@ private: }; inline _LIBCPP_HIDE_FROM_ABI bool -operator==(const directory_iterator& __lhs, - const directory_iterator& __rhs) noexcept { +operator==(const directory_iterator& __lhs, const directory_iterator& __rhs) noexcept { return __lhs.__imp_ == __rhs.__imp_; } inline _LIBCPP_HIDE_FROM_ABI bool -operator!=(const directory_iterator& __lhs, - const directory_iterator& __rhs) noexcept { +operator!=(const directory_iterator& __lhs, const directory_iterator& __rhs) noexcept { return !(__lhs == __rhs); } // enable directory_iterator range-based for statements -inline _LIBCPP_HIDE_FROM_ABI directory_iterator -begin(directory_iterator __iter) noexcept { - return __iter; -} +inline _LIBCPP_HIDE_FROM_ABI directory_iterator begin(directory_iterator __iter) noexcept { return __iter; } -inline _LIBCPP_HIDE_FROM_ABI directory_iterator -end(directory_iterator) noexcept { - return directory_iterator(); -} +inline _LIBCPP_HIDE_FROM_ABI directory_iterator end(directory_iterator) noexcept { return directory_iterator(); } _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_END_NAMESPACE_FILESYSTEM -#if _LIBCPP_STD_VER >= 20 +# if _LIBCPP_STD_VER >= 20 template <> -_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY -inline constexpr bool std::ranges::enable_borrowed_range = true; +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool + std::ranges::enable_borrowed_range = true; template <> -_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY -inline constexpr bool std::ranges::enable_view = true; +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool + std::ranges::enable_view = true; -#endif // _LIBCPP_STD_VER >= 20 +# endif // _LIBCPP_STD_VER >= 20 #endif // _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) diff --git a/libcxx/include/__filesystem/directory_options.h b/libcxx/include/__filesystem/directory_options.h index 05885bc488b0aecd797115eaa94a3d6355281a21..683c4678e083bc85704813d711e499a1b535f9ab 100644 --- a/libcxx/include/__filesystem/directory_options.h +++ b/libcxx/include/__filesystem/directory_options.h @@ -21,53 +21,33 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -enum class directory_options : unsigned char { - none = 0, - follow_directory_symlink = 1, - skip_permission_denied = 2 -}; - -_LIBCPP_HIDE_FROM_ABI -inline constexpr directory_options operator&(directory_options __lhs, - directory_options __rhs) { - return static_cast(static_cast(__lhs) & - static_cast(__rhs)); +enum class directory_options : unsigned char { none = 0, follow_directory_symlink = 1, skip_permission_denied = 2 }; + +_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator&(directory_options __lhs, directory_options __rhs) { + return static_cast(static_cast(__lhs) & static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr directory_options operator|(directory_options __lhs, - directory_options __rhs) { - return static_cast(static_cast(__lhs) | - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator|(directory_options __lhs, directory_options __rhs) { + return static_cast(static_cast(__lhs) | static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr directory_options operator^(directory_options __lhs, - directory_options __rhs) { - return static_cast(static_cast(__lhs) ^ - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator^(directory_options __lhs, directory_options __rhs) { + return static_cast(static_cast(__lhs) ^ static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr directory_options operator~(directory_options __lhs) { +_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator~(directory_options __lhs) { return static_cast(~static_cast(__lhs)); } -_LIBCPP_HIDE_FROM_ABI -inline directory_options& operator&=(directory_options& __lhs, - directory_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline directory_options& operator&=(directory_options& __lhs, directory_options __rhs) { return __lhs = __lhs & __rhs; } -_LIBCPP_HIDE_FROM_ABI -inline directory_options& operator|=(directory_options& __lhs, - directory_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline directory_options& operator|=(directory_options& __lhs, directory_options __rhs) { return __lhs = __lhs | __rhs; } -_LIBCPP_HIDE_FROM_ABI -inline directory_options& operator^=(directory_options& __lhs, - directory_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline directory_options& operator^=(directory_options& __lhs, directory_options __rhs) { return __lhs = __lhs ^ __rhs; } diff --git a/libcxx/include/__filesystem/file_status.h b/libcxx/include/__filesystem/file_status.h index 2a1ce85a37543c406386e48db79c9f5c4798bc4e..3e2b32eef82e024431230bf6ac9d4c5271a48ecf 100644 --- a/libcxx/include/__filesystem/file_status.h +++ b/libcxx/include/__filesystem/file_status.h @@ -26,35 +26,27 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM class _LIBCPP_EXPORTED_FROM_ABI file_status { public: // constructors - _LIBCPP_HIDE_FROM_ABI - file_status() noexcept : file_status(file_type::none) {} - _LIBCPP_HIDE_FROM_ABI - explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept - : __ft_(__ft), - __prms_(__prms) {} + _LIBCPP_HIDE_FROM_ABI file_status() noexcept : file_status(file_type::none) {} + _LIBCPP_HIDE_FROM_ABI explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept + : __ft_(__ft), __prms_(__prms) {} _LIBCPP_HIDE_FROM_ABI file_status(const file_status&) noexcept = default; - _LIBCPP_HIDE_FROM_ABI file_status(file_status&&) noexcept = default; + _LIBCPP_HIDE_FROM_ABI file_status(file_status&&) noexcept = default; - _LIBCPP_HIDE_FROM_ABI - ~file_status() {} + _LIBCPP_HIDE_FROM_ABI ~file_status() {} _LIBCPP_HIDE_FROM_ABI file_status& operator=(const file_status&) noexcept = default; - _LIBCPP_HIDE_FROM_ABI file_status& operator=(file_status&&) noexcept = default; + _LIBCPP_HIDE_FROM_ABI file_status& operator=(file_status&&) noexcept = default; // observers - _LIBCPP_HIDE_FROM_ABI - file_type type() const noexcept { return __ft_; } + _LIBCPP_HIDE_FROM_ABI file_type type() const noexcept { return __ft_; } - _LIBCPP_HIDE_FROM_ABI - perms permissions() const noexcept { return __prms_; } + _LIBCPP_HIDE_FROM_ABI perms permissions() const noexcept { return __prms_; } // modifiers - _LIBCPP_HIDE_FROM_ABI - void type(file_type __ft) noexcept { __ft_ = __ft; } + _LIBCPP_HIDE_FROM_ABI void type(file_type __ft) noexcept { __ft_ = __ft; } - _LIBCPP_HIDE_FROM_ABI - void permissions(perms __p) noexcept { __prms_ = __p; } + _LIBCPP_HIDE_FROM_ABI void permissions(perms __p) noexcept { __prms_ = __p; } # if _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__filesystem/file_type.h b/libcxx/include/__filesystem/file_type.h index f456552db54371c6d90f3c479b6b922cba35a6ae..c509085d90de0d3821bb6fc577713b243dcfd597 100644 --- a/libcxx/include/__filesystem/file_type.h +++ b/libcxx/include/__filesystem/file_type.h @@ -24,16 +24,16 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM // On Windows, the library never identifies files as block, character, fifo // or socket. enum class file_type : signed char { - none = 0, + none = 0, not_found = -1, - regular = 1, + regular = 1, directory = 2, - symlink = 3, - block = 4, + symlink = 3, + block = 4, character = 5, - fifo = 6, - socket = 7, - unknown = 8 + fifo = 6, + socket = 7, + unknown = 8 }; _LIBCPP_END_NAMESPACE_FILESYSTEM diff --git a/libcxx/include/__filesystem/operations.h b/libcxx/include/__filesystem/operations.h index ebe816549a9eca46c97af5b09fae7210ae79326e..9bb83576f54bc044ab9b0e472d92e508e881ce01 100644 --- a/libcxx/include/__filesystem/operations.h +++ b/libcxx/include/__filesystem/operations.h @@ -36,15 +36,21 @@ _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH _LIBCPP_EXPORTED_FROM_ABI path __absolute(const path&, error_code* __ec = nullptr); _LIBCPP_EXPORTED_FROM_ABI path __canonical(const path&, error_code* __ec = nullptr); -_LIBCPP_EXPORTED_FROM_ABI bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); -_LIBCPP_EXPORTED_FROM_ABI void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); -_LIBCPP_EXPORTED_FROM_ABI void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI bool +__copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void +__copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void +__copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); _LIBCPP_EXPORTED_FROM_ABI bool __create_directories(const path&, error_code* = nullptr); -_LIBCPP_EXPORTED_FROM_ABI void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void +__create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); _LIBCPP_EXPORTED_FROM_ABI bool __create_directory(const path&, error_code* = nullptr); _LIBCPP_EXPORTED_FROM_ABI bool __create_directory(const path&, const path& __attributes, error_code* = nullptr); -_LIBCPP_EXPORTED_FROM_ABI void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); -_LIBCPP_EXPORTED_FROM_ABI void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void +__create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void +__create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); _LIBCPP_EXPORTED_FROM_ABI path __current_path(error_code* __ec = nullptr); _LIBCPP_EXPORTED_FROM_ABI void __current_path(const path&, error_code* __ec = nullptr); _LIBCPP_EXPORTED_FROM_ABI bool __equivalent(const path&, const path&, error_code* __ec = nullptr); @@ -64,38 +70,85 @@ _LIBCPP_EXPORTED_FROM_ABI path __temp_directory_path(error_code* __ec = nullptr) inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); } inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); } +inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); } inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p, error_code& __ec) { return __canonical(__p, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to) { return __copy_file(__from, __to, copy_options::none); } -inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, error_code& __ec) { return __copy_file(__from, __to, copy_options::none, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt) { return __copy_file(__from, __to, __opt); } -inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { return __copy_file(__from, __to, __opt, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to) { + return __copy_file(__from, __to, copy_options::none); +} +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, error_code& __ec) { + return __copy_file(__from, __to, copy_options::none, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt) { + return __copy_file(__from, __to, __opt); +} +inline _LIBCPP_HIDE_FROM_ABI bool +copy_file(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { + return __copy_file(__from, __to, __opt, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to) { __copy_symlink(__from, __to); } -inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to, error_code& __ec) noexcept { __copy_symlink(__from, __to, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to) { __copy(__from, __to, copy_options::none); } -inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, error_code& __ec) { __copy(__from, __to, copy_options::none, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt) { __copy(__from, __to, __opt); } -inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { __copy(__from, __to, __opt, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to, error_code& __ec) noexcept { + __copy_symlink(__from, __to, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to) { + __copy(__from, __to, copy_options::none); +} +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, error_code& __ec) { + __copy(__from, __to, copy_options::none, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt) { + __copy(__from, __to, __opt); +} +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { + __copy(__from, __to, __opt, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p) { return __create_directories(__p); } -inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p, error_code& __ec) { return __create_directories(__p, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link) { __create_directory_symlink(__target, __link); } -inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { __create_directory_symlink(__target, __link, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p, error_code& __ec) { + return __create_directories(__p, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link) { + __create_directory_symlink(__target, __link); +} +inline _LIBCPP_HIDE_FROM_ABI void +create_directory_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { + __create_directory_symlink(__target, __link, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p) { return __create_directory(__p); } -inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, error_code& __ec) noexcept { return __create_directory(__p, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs) { return __create_directory(__p, __attrs); } -inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs, error_code& __ec) noexcept { return __create_directory(__p, __attrs, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link) { __create_hard_link(__target, __link); } -inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link, error_code& __ec) noexcept { __create_hard_link(__target, __link, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link) { __create_symlink(__target, __link); } -inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { return __create_symlink(__target, __link, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, error_code& __ec) noexcept { + return __create_directory(__p, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs) { + return __create_directory(__p, __attrs); +} +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs, error_code& __ec) noexcept { + return __create_directory(__p, __attrs, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link) { + __create_hard_link(__target, __link); +} +inline _LIBCPP_HIDE_FROM_ABI void +create_hard_link(const path& __target, const path& __link, error_code& __ec) noexcept { + __create_hard_link(__target, __link, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link) { + __create_symlink(__target, __link); +} +inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { + return __create_symlink(__target, __link, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI path current_path() { return __current_path(); } inline _LIBCPP_HIDE_FROM_ABI path current_path(error_code& __ec) { return __current_path(&__ec); } inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p) { __current_path(__p); } -inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p, error_code& __ec) noexcept { __current_path(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p, error_code& __ec) noexcept { + __current_path(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2) { return __equivalent(__p1, __p2); } -inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { return __equivalent(__p1, __p2, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { + return __equivalent(__p1, __p2, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; } -inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept { return status_known(__s) && __s.type() != file_type::not_found; } +inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept { + return status_known(__s) && __s.type() != file_type::not_found; +} inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p) { return exists(__status(__p)); } inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p, error_code& __ec) noexcept { @@ -106,44 +159,79 @@ inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p, error_code& __ec) noex } inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p) { return __file_size(__p); } -inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept { return __file_size(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept { + return __file_size(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); } -inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept { return __hard_link_count(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept { + return __hard_link_count(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; } inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p) { return is_block_file(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept { return is_block_file(__status(__p, &__ec)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept { return __s.type() == file_type::character; } +inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept { + return is_block_file(__status(__p, &__ec)); +} +inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept { + return __s.type() == file_type::character; +} inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p) { return is_character_file(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code& __ec) noexcept { return is_character_file(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code& __ec) noexcept { + return is_character_file(__status(__p, &__ec)); +} inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; } inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { + return is_directory(__status(__p, &__ec)); +} _LIBCPP_EXPORTED_FROM_ABI bool __fs_is_empty(const path& __p, error_code* __ec = nullptr); inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); } inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); } inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; } inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p) { return is_fifo(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p, error_code& __ec) noexcept { return is_fifo(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p, error_code& __ec) noexcept { + return is_fifo(__status(__p, &__ec)); +} inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(file_status __s) noexcept { return __s.type() == file_type::regular; } inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p) { return is_regular_file(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p, error_code& __ec) noexcept { return is_regular_file(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p, error_code& __ec) noexcept { + return is_regular_file(__status(__p, &__ec)); +} inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(file_status __s) noexcept { return __s.type() == file_type::symlink; } inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p) { return is_symlink(__symlink_status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p, error_code& __ec) noexcept { return is_symlink(__symlink_status(__p, &__ec)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_other(file_status __s) noexcept { return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); } +inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p, error_code& __ec) noexcept { + return is_symlink(__symlink_status(__p, &__ec)); +} +inline _LIBCPP_HIDE_FROM_ABI bool is_other(file_status __s) noexcept { + return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); +} inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p) { return is_other(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p, error_code& __ec) noexcept { return is_other(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p, error_code& __ec) noexcept { + return is_other(__status(__p, &__ec)); +} inline _LIBCPP_HIDE_FROM_ABI bool is_socket(file_status __s) noexcept { return __s.type() == file_type::socket; } inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p) { return is_socket(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p, error_code& __ec) noexcept { return is_socket(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p, error_code& __ec) noexcept { + return is_socket(__status(__p, &__ec)); +} inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p) { return __last_write_time(__p); } -inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { + return __last_write_time(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); } -inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { + __last_write_time(__p, __t, &__ec); +} _LIBCPP_EXPORTED_FROM_ABI void __permissions(const path&, perms, perm_options, error_code* = nullptr); -inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); } -inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void +permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { + __permissions(__p, __prms, __opts); +} +inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { + __permissions(__p, __prms, perm_options::replace, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { + __permissions(__p, __prms, __opts, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base, error_code& __ec) { path __tmp = __weakly_canonical(__p, &__ec); @@ -155,8 +243,12 @@ inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base, return __tmp.lexically_proximate(__tmp_base); } -inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, error_code& __ec) { return proximate(__p, current_path(), __ec); } -inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base)); } +inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, error_code& __ec) { + return proximate(__p, current_path(), __ec); +} +inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base = current_path()) { + return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base)); +} inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p) { return __read_symlink(__p); } inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p, error_code& __ec) { return __read_symlink(__p, &__ec); } @@ -170,27 +262,45 @@ inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base, return __tmp.lexically_relative(__tmpbase); } -inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, error_code& __ec) { return relative(__p, current_path(), __ec); } -inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); } +inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, error_code& __ec) { + return relative(__p, current_path(), __ec); +} +inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base = current_path()) { + return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); +} inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p) { return __remove_all(__p); } -inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p, error_code& __ec) { return __remove_all(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p, error_code& __ec) { + return __remove_all(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool remove(const path& __p) { return __remove(__p); } inline _LIBCPP_HIDE_FROM_ABI bool remove(const path& __p, error_code& __ec) noexcept { return __remove(__p, &__ec); } inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to) { return __rename(__from, __to); } -inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to, error_code& __ec) noexcept { + return __rename(__from, __to, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); } -inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { + return __resize_file(__p, __ns, &__ec); +} _LIBCPP_EXPORTED_FROM_ABI space_info __space(const path&, error_code* __ec = nullptr); inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p) { return __space(__p); } -inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept { + return __space(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p) { return __status(__p); } -inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p, error_code& __ec) noexcept { return __status(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p, error_code& __ec) noexcept { + return __status(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p) { return __symlink_status(__p); } -inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p, error_code& __ec) noexcept { return __symlink_status(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p, error_code& __ec) noexcept { + return __symlink_status(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path() { return __temp_directory_path(); } inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path(error_code& __ec) { return __temp_directory_path(&__ec); } inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p) { return __weakly_canonical(__p); } -inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) { + return __weakly_canonical(__p, &__ec); +} _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP diff --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h index 466fa25a38ed159bb7e3d034c890230c727c037d..1ff992dd64e6d7be8ecd95ee07c6650d2d1bc2b3 100644 --- a/libcxx/include/__filesystem/path.h +++ b/libcxx/include/__filesystem/path.h @@ -28,8 +28,8 @@ #include #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) -# include // for quoted -# include +# include // for quoted +# include #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -51,47 +51,45 @@ struct __can_convert_char : public __can_convert_char<_Tp> {}; template <> struct __can_convert_char { static const bool value = true; - using __char_type = char; + using __char_type = char; }; template <> struct __can_convert_char { static const bool value = true; - using __char_type = wchar_t; + using __char_type = wchar_t; }; -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T template <> struct __can_convert_char { static const bool value = true; - using __char_type = char8_t; + using __char_type = char8_t; }; -#endif +# endif template <> struct __can_convert_char { static const bool value = true; - using __char_type = char16_t; + using __char_type = char16_t; }; template <> struct __can_convert_char { static const bool value = true; - using __char_type = char32_t; + using __char_type = char32_t; }; template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI -bool -__is_separator(_ECharT __e) { -#if defined(_LIBCPP_WIN32API) +_LIBCPP_HIDE_FROM_ABI bool __is_separator(_ECharT __e) { +# if defined(_LIBCPP_WIN32API) return __e == _ECharT('/') || __e == _ECharT('\\'); -#else +# else return __e == _ECharT('/'); -#endif +# endif } -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T typedef u8string __u8_string; -#else +# else typedef string __u8_string; -#endif +# endif struct _NullSentinel {}; @@ -102,99 +100,75 @@ template struct __is_pathable_string : public false_type {}; template -struct __is_pathable_string< - basic_string<_ECharT, _Traits, _Alloc>, - _Void::__char_type> > +struct __is_pathable_string< basic_string<_ECharT, _Traits, _Alloc>, + _Void::__char_type> > : public __can_convert_char<_ECharT> { using _Str = basic_string<_ECharT, _Traits, _Alloc>; - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_end(_Str const& __s) { - return __s.data() + __s.length(); - } + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); } - _LIBCPP_HIDE_FROM_ABI - static _ECharT __first_or_null(_Str const& __s) { - return __s.empty() ? _ECharT{} : __s[0]; - } + _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(_Str const& __s) { return __s.empty() ? _ECharT{} : __s[0]; } }; template -struct __is_pathable_string< - basic_string_view<_ECharT, _Traits>, - _Void::__char_type> > +struct __is_pathable_string< basic_string_view<_ECharT, _Traits>, + _Void::__char_type> > : public __can_convert_char<_ECharT> { using _Str = basic_string_view<_ECharT, _Traits>; - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_end(_Str const& __s) { - return __s.data() + __s.length(); - } + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); } - _LIBCPP_HIDE_FROM_ABI - static _ECharT __first_or_null(_Str const& __s) { - return __s.empty() ? _ECharT{} : __s[0]; - } + _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(_Str const& __s) { return __s.empty() ? _ECharT{} : __s[0]; } }; -template , - class _UnqualPtrType = - __remove_const_t<__remove_pointer_t<_DS> >, - bool _IsCharPtr = is_pointer<_DS>::value&& - __can_convert_char<_UnqualPtrType>::value> +template , + class _UnqualPtrType = __remove_const_t<__remove_pointer_t<_DS> >, + bool _IsCharPtr = is_pointer<_DS>::value && __can_convert_char<_UnqualPtrType>::value> struct __is_pathable_char_array : false_type {}; template -struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> - : __can_convert_char<__remove_const_t<_ECharT> > { - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } - - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_end(const _ECharT* __b) { - using _Iter = const _ECharT*; +struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> : __can_convert_char<__remove_const_t<_ECharT> > { + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } + + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_end(const _ECharT* __b) { + using _Iter = const _ECharT*; const _ECharT __sentinel = _ECharT{}; - _Iter __e = __b; + _Iter __e = __b; for (; *__e != __sentinel; ++__e) ; return __e; } - _LIBCPP_HIDE_FROM_ABI - static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } + _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } }; -template ::value, - class = void> +template ::value, class = void> struct __is_pathable_iter : false_type {}; template struct __is_pathable_iter< - _Iter, true, - _Void::value_type>::__char_type> > + _Iter, + true, + _Void::value_type>::__char_type> > : __can_convert_char::value_type> { using _ECharT = typename iterator_traits<_Iter>::value_type; - _LIBCPP_HIDE_FROM_ABI - static _Iter __range_begin(_Iter __b) { return __b; } + _LIBCPP_HIDE_FROM_ABI static _Iter __range_begin(_Iter __b) { return __b; } - _LIBCPP_HIDE_FROM_ABI - static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; } + _LIBCPP_HIDE_FROM_ABI static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; } - _LIBCPP_HIDE_FROM_ABI - static _ECharT __first_or_null(_Iter __b) { return *__b; } + _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(_Iter __b) { return *__b; } }; -template ::value, +template ::value, bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, - bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> + bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> struct __is_pathable : false_type { static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); }; @@ -203,72 +177,64 @@ template struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; template -struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> { -}; +struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {}; template struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) typedef wstring __path_string; typedef wchar_t __path_value; -#else +# else typedef string __path_string; typedef char __path_value; -#endif +# endif -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) _LIBCPP_EXPORTED_FROM_ABI size_t __wide_to_char(const wstring&, char*, size_t); _LIBCPP_EXPORTED_FROM_ABI size_t __char_to_wide(const string&, wchar_t*, size_t); -#endif +# endif template struct _PathCVT; -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) +# if !defined(_LIBCPP_HAS_NO_LOCALIZATION) template struct _PathCVT { - static_assert(__can_convert_char<_ECharT>::value, - "Char type not convertible"); + static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible"); typedef __narrow_to_utf8 _Narrower; -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) typedef __widen_from_utf8 _Widener; -#endif +# endif - _LIBCPP_HIDE_FROM_ABI - static void __append_range(__path_string& __dest, _ECharT const* __b, - _ECharT const* __e) { -#if defined(_LIBCPP_WIN32API) + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _ECharT const* __b, _ECharT const* __e) { +# if defined(_LIBCPP_WIN32API) string __utf8; _Narrower()(back_inserter(__utf8), __b, __e); _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); -#else +# else _Narrower()(back_inserter(__dest), __b, __e); -#endif +# endif } template - _LIBCPP_HIDE_FROM_ABI - static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); if (__b == __e) return; basic_string<_ECharT> __tmp(__b, __e); -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) string __utf8; - _Narrower()(back_inserter(__utf8), __tmp.data(), - __tmp.data() + __tmp.length()); + _Narrower()(back_inserter(__utf8), __tmp.data(), __tmp.data() + __tmp.length()); _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); -#else - _Narrower()(back_inserter(__dest), __tmp.data(), - __tmp.data() + __tmp.length()); -#endif +# else + _Narrower()(back_inserter(__dest), __tmp.data(), __tmp.data() + __tmp.length()); +# endif } template - _LIBCPP_HIDE_FROM_ABI - static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); const _ECharT __sentinel = _ECharT{}; if (*__b == __sentinel) @@ -276,94 +242,74 @@ struct _PathCVT { basic_string<_ECharT> __tmp; for (; *__b != __sentinel; ++__b) __tmp.push_back(*__b); -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) string __utf8; - _Narrower()(back_inserter(__utf8), __tmp.data(), - __tmp.data() + __tmp.length()); + _Narrower()(back_inserter(__utf8), __tmp.data(), __tmp.data() + __tmp.length()); _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); -#else - _Narrower()(back_inserter(__dest), __tmp.data(), - __tmp.data() + __tmp.length()); -#endif +# else + _Narrower()(back_inserter(__dest), __tmp.data(), __tmp.data() + __tmp.length()); +# endif } template - _LIBCPP_HIDE_FROM_ABI - static void __append_source(__path_string& __dest, _Source const& __s) { + _LIBCPP_HIDE_FROM_ABI static void __append_source(__path_string& __dest, _Source const& __s) { using _Traits = __is_pathable<_Source>; - __append_range(__dest, _Traits::__range_begin(__s), - _Traits::__range_end(__s)); + __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); } }; -#endif // !_LIBCPP_HAS_NO_LOCALIZATION +# endif // !_LIBCPP_HAS_NO_LOCALIZATION template <> struct _PathCVT<__path_value> { - template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI - static void - __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { for (; __b != __e; ++__b) __dest.push_back(*__b); } template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI - static void - __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { __dest.append(__b, __e); } template - _LIBCPP_HIDE_FROM_ABI - static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { const char __sentinel = char{}; for (; *__b != __sentinel; ++__b) __dest.push_back(*__b); } template - _LIBCPP_HIDE_FROM_ABI - static void __append_source(__path_string& __dest, _Source const& __s) { + _LIBCPP_HIDE_FROM_ABI static void __append_source(__path_string& __dest, _Source const& __s) { using _Traits = __is_pathable<_Source>; - __append_range(__dest, _Traits::__range_begin(__s), - _Traits::__range_end(__s)); + __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); } }; -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) template <> struct _PathCVT { - - _LIBCPP_HIDE_FROM_ABI - static void - __append_string(__path_string& __dest, const basic_string &__str) { - size_t __size = __char_to_wide(__str, nullptr, 0); - size_t __pos = __dest.size(); - __dest.resize(__pos + __size); - __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size); + _LIBCPP_HIDE_FROM_ABI static void __append_string(__path_string& __dest, const basic_string& __str) { + size_t __size = __char_to_wide(__str, nullptr, 0); + size_t __pos = __dest.size(); + __dest.resize(__pos + __size); + __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size); } template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI - static void - __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { basic_string __tmp(__b, __e); __append_string(__dest, __tmp); } template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI - static void - __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { basic_string __tmp(__b, __e); __append_string(__dest, __tmp); } template - _LIBCPP_HIDE_FROM_ABI - static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { const char __sentinel = char{}; basic_string __tmp; for (; *__b != __sentinel; ++__b) @@ -372,11 +318,9 @@ struct _PathCVT { } template - _LIBCPP_HIDE_FROM_ABI - static void __append_source(__path_string& __dest, _Source const& __s) { + _LIBCPP_HIDE_FROM_ABI static void __append_source(__path_string& __dest, _Source const& __s) { using _Traits = __is_pathable<_Source>; - __append_range(__dest, _Traits::__range_begin(__s), - _Traits::__range_end(__s)); + __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); } }; @@ -386,8 +330,7 @@ struct _PathExport { typedef __widen_from_utf8 _Widener; template - _LIBCPP_HIDE_FROM_ABI - static void __append(_Str& __dest, const __path_string& __src) { + _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) { string __utf8; _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size()); _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); @@ -397,10 +340,9 @@ struct _PathExport { template <> struct _PathExport { template - _LIBCPP_HIDE_FROM_ABI - static void __append(_Str& __dest, const __path_string& __src) { + _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) { size_t __size = __wide_to_char(__src, nullptr, 0); - size_t __pos = __dest.size(); + size_t __pos = __dest.size(); __dest.resize(__size); __wide_to_char(__src, const_cast(__dest.data()) + __pos, __size); } @@ -409,8 +351,7 @@ struct _PathExport { template <> struct _PathExport { template - _LIBCPP_HIDE_FROM_ABI - static void __append(_Str& __dest, const __path_string& __src) { + _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) { __dest.append(__src.begin(), __src.end()); } }; @@ -418,25 +359,23 @@ struct _PathExport { template <> struct _PathExport { template - _LIBCPP_HIDE_FROM_ABI - static void __append(_Str& __dest, const __path_string& __src) { + _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) { __dest.append(__src.begin(), __src.end()); } }; -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T template <> struct _PathExport { typedef __narrow_to_utf8 _Narrower; template - _LIBCPP_HIDE_FROM_ABI - static void __append(_Str& __dest, const __path_string& __src) { + _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) { _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size()); } }; -#endif /* !_LIBCPP_HAS_NO_CHAR8_T */ -#endif /* _LIBCPP_WIN32API */ +# endif /* !_LIBCPP_HAS_NO_CHAR8_T */ +# endif /* _LIBCPP_WIN32API */ class _LIBCPP_EXPORTED_FROM_ABI path { template @@ -449,101 +388,84 @@ class _LIBCPP_EXPORTED_FROM_ABI path { using _SourceCVT = _PathCVT<_SourceChar<_Tp> >; public: -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) typedef wchar_t value_type; static constexpr value_type preferred_separator = L'\\'; -#else +# else typedef char value_type; static constexpr value_type preferred_separator = '/'; -#endif +# endif typedef basic_string string_type; typedef basic_string_view __string_view; - enum format : unsigned char { - auto_format, - native_format, - generic_format - }; + enum format : unsigned char { auto_format, native_format, generic_format }; // constructors and destructor _LIBCPP_HIDE_FROM_ABI path() noexcept {} _LIBCPP_HIDE_FROM_ABI path(const path& __p) : __pn_(__p.__pn_) {} - _LIBCPP_HIDE_FROM_ABI path(path&& __p) noexcept - : __pn_(std::move(__p.__pn_)) {} + _LIBCPP_HIDE_FROM_ABI path(path&& __p) noexcept : __pn_(std::move(__p.__pn_)) {} - _LIBCPP_HIDE_FROM_ABI - path(string_type&& __s, format = format::auto_format) noexcept - : __pn_(std::move(__s)) {} + _LIBCPP_HIDE_FROM_ABI path(string_type&& __s, format = format::auto_format) noexcept : __pn_(std::move(__s)) {} template > - _LIBCPP_HIDE_FROM_ABI - path(const _Source& __src, format = format::auto_format) { + _LIBCPP_HIDE_FROM_ABI path(const _Source& __src, format = format::auto_format) { _SourceCVT<_Source>::__append_source(__pn_, __src); } template - _LIBCPP_HIDE_FROM_ABI - path(_InputIt __first, _InputIt __last, format = format::auto_format) { + _LIBCPP_HIDE_FROM_ABI path(_InputIt __first, _InputIt __last, format = format::auto_format) { typedef typename iterator_traits<_InputIt>::value_type _ItVal; _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); } -/* -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - // TODO Implement locale conversions. - template > - path(const _Source& __src, const locale& __loc, format = format::auto_format); - template - path(_InputIt __first, _InputIt _last, const locale& __loc, - format = format::auto_format); -#endif -*/ + /* + #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + // TODO Implement locale conversions. + template > + path(const _Source& __src, const locale& __loc, format = format::auto_format); + template + path(_InputIt __first, _InputIt _last, const locale& __loc, + format = format::auto_format); + #endif + */ - _LIBCPP_HIDE_FROM_ABI - ~path() = default; + _LIBCPP_HIDE_FROM_ABI ~path() = default; // assignments - _LIBCPP_HIDE_FROM_ABI - path& operator=(const path& __p) { + _LIBCPP_HIDE_FROM_ABI path& operator=(const path& __p) { __pn_ = __p.__pn_; return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator=(path&& __p) noexcept { + _LIBCPP_HIDE_FROM_ABI path& operator=(path&& __p) noexcept { __pn_ = std::move(__p.__pn_); return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator=(string_type&& __s) noexcept { + _LIBCPP_HIDE_FROM_ABI path& operator=(string_type&& __s) noexcept { __pn_ = std::move(__s); return *this; } - _LIBCPP_HIDE_FROM_ABI - path& assign(string_type&& __s) noexcept { + _LIBCPP_HIDE_FROM_ABI path& assign(string_type&& __s) noexcept { __pn_ = std::move(__s); return *this; } template - _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> - operator=(const _Source& __src) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator=(const _Source& __src) { return this->assign(__src); } template - _LIBCPP_HIDE_FROM_ABI - _EnableIfPathable<_Source> assign(const _Source& __src) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> assign(const _Source& __src) { __pn_.clear(); _SourceCVT<_Source>::__append_source(__pn_, __src); return *this; } template - _LIBCPP_HIDE_FROM_ABI - path& assign(_InputIt __first, _InputIt __last) { + _LIBCPP_HIDE_FROM_ABI path& assign(_InputIt __first, _InputIt __last) { typedef typename iterator_traits<_InputIt>::value_type _ItVal; __pn_.clear(); _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); @@ -552,19 +474,17 @@ public: public: // appends -#if defined(_LIBCPP_WIN32API) - _LIBCPP_HIDE_FROM_ABI - path& operator/=(const path& __p) { - auto __p_root_name = __p.__root_name(); +# if defined(_LIBCPP_WIN32API) + _LIBCPP_HIDE_FROM_ABI path& operator/=(const path& __p) { + auto __p_root_name = __p.__root_name(); auto __p_root_name_size = __p_root_name.size(); - if (__p.is_absolute() || - (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) { + if (__p.is_absolute() || (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) { __pn_ = __p.__pn_; return *this; } if (__p.has_root_directory()) { path __root_name_str = root_name(); - __pn_ = __root_name_str.native(); + __pn_ = __root_name_str.native(); __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); return *this; } @@ -574,25 +494,21 @@ public: return *this; } template - _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> - operator/=(const _Source& __src) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator/=(const _Source& __src) { return operator/=(path(__src)); } template - _LIBCPP_HIDE_FROM_ABI - _EnableIfPathable<_Source> append(const _Source& __src) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& __src) { return operator/=(path(__src)); } template - _LIBCPP_HIDE_FROM_ABI - path& append(_InputIt __first, _InputIt __last) { + _LIBCPP_HIDE_FROM_ABI path& append(_InputIt __first, _InputIt __last) { return operator/=(path(__first, __last)); } -#else - _LIBCPP_HIDE_FROM_ABI - path& operator/=(const path& __p) { +# else + _LIBCPP_HIDE_FROM_ABI path& operator/=(const path& __p) { if (__p.is_absolute()) { __pn_ = __p.__pn_; return *this; @@ -607,16 +523,14 @@ public: // is known at compile time to be "/' since the user almost certainly intended // to append a separator instead of overwriting the path with "/" template - _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> - operator/=(const _Source& __src) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator/=(const _Source& __src) { return this->append(__src); } template - _LIBCPP_HIDE_FROM_ABI - _EnableIfPathable<_Source> append(const _Source& __src) { - using _Traits = __is_pathable<_Source>; - using _CVT = _PathCVT<_SourceChar<_Source> >; + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& __src) { + using _Traits = __is_pathable<_Source>; + using _CVT = _PathCVT<_SourceChar<_Source> >; bool __source_is_absolute = filesystem::__is_separator(_Traits::__first_or_null(__src)); if (__source_is_absolute) __pn_.clear(); @@ -627,8 +541,7 @@ public: } template - _LIBCPP_HIDE_FROM_ABI - path& append(_InputIt __first, _InputIt __last) { + _LIBCPP_HIDE_FROM_ABI path& append(_InputIt __first, _InputIt __last) { typedef typename iterator_traits<_InputIt>::value_type _ItVal; static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); using _CVT = _PathCVT<_ItVal>; @@ -639,91 +552,76 @@ public: _CVT::__append_range(__pn_, __first, __last); return *this; } -#endif +# endif // concatenation - _LIBCPP_HIDE_FROM_ABI - path& operator+=(const path& __x) { + _LIBCPP_HIDE_FROM_ABI path& operator+=(const path& __x) { __pn_ += __x.__pn_; return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator+=(const string_type& __x) { + _LIBCPP_HIDE_FROM_ABI path& operator+=(const string_type& __x) { __pn_ += __x; return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator+=(__string_view __x) { + _LIBCPP_HIDE_FROM_ABI path& operator+=(__string_view __x) { __pn_ += __x; return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator+=(const value_type* __x) { + _LIBCPP_HIDE_FROM_ABI path& operator+=(const value_type* __x) { __pn_ += __x; return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator+=(value_type __x) { + _LIBCPP_HIDE_FROM_ABI path& operator+=(value_type __x) { __pn_ += __x; return *this; } template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI - path& - operator+=(_ECharT __x) { - _PathCVT<_ECharT>::__append_source(__pn_, - basic_string_view<_ECharT>(&__x, 1)); + _LIBCPP_HIDE_FROM_ABI path& operator+=(_ECharT __x) { + _PathCVT<_ECharT>::__append_source(__pn_, basic_string_view<_ECharT>(&__x, 1)); return *this; } template - _LIBCPP_HIDE_FROM_ABI - _EnableIfPathable<_Source> operator+=(const _Source& __x) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator+=(const _Source& __x) { return this->concat(__x); } template - _LIBCPP_HIDE_FROM_ABI - _EnableIfPathable<_Source> concat(const _Source& __x) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> concat(const _Source& __x) { _SourceCVT<_Source>::__append_source(__pn_, __x); return *this; } template - _LIBCPP_HIDE_FROM_ABI - path& concat(_InputIt __first, _InputIt __last) { + _LIBCPP_HIDE_FROM_ABI path& concat(_InputIt __first, _InputIt __last) { typedef typename iterator_traits<_InputIt>::value_type _ItVal; _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); return *this; } // modifiers - _LIBCPP_HIDE_FROM_ABI - void clear() noexcept { __pn_.clear(); } + _LIBCPP_HIDE_FROM_ABI void clear() noexcept { __pn_.clear(); } - _LIBCPP_HIDE_FROM_ABI - path& make_preferred() { -#if defined(_LIBCPP_WIN32API) + _LIBCPP_HIDE_FROM_ABI path& make_preferred() { +# if defined(_LIBCPP_WIN32API) std::replace(__pn_.begin(), __pn_.end(), L'/', L'\\'); -#endif +# endif return *this; } - _LIBCPP_HIDE_FROM_ABI - path& remove_filename() { + _LIBCPP_HIDE_FROM_ABI path& remove_filename() { auto __fname = __filename(); if (!__fname.empty()) __pn_.erase(__fname.data() - __pn_.data()); return *this; } - _LIBCPP_HIDE_FROM_ABI - path& replace_filename(const path& __replacement) { + _LIBCPP_HIDE_FROM_ABI path& replace_filename(const path& __replacement) { remove_filename(); return (*this /= __replacement); } @@ -749,7 +647,7 @@ public: friend _LIBCPP_HIDE_FROM_ABI bool operator>=(const path& __lhs, const path& __rhs) noexcept { return __lhs.__compare(__rhs.__pn_) >= 0; } -# else // _LIBCPP_STD_VER <= 17 +# else // _LIBCPP_STD_VER <= 17 friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const path& __lhs, const path& __rhs) noexcept { return __lhs.__compare(__rhs.__pn_) <=> 0; } @@ -761,39 +659,31 @@ public: return __result; } - _LIBCPP_HIDE_FROM_ABI - void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } + _LIBCPP_HIDE_FROM_ABI void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } // private helper to allow reserving memory in the path - _LIBCPP_HIDE_FROM_ABI - void __reserve(size_t __s) { __pn_.reserve(__s); } + _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __s) { __pn_.reserve(__s); } // native format observers - _LIBCPP_HIDE_FROM_ABI - const string_type& native() const noexcept { return __pn_; } + _LIBCPP_HIDE_FROM_ABI const string_type& native() const noexcept { return __pn_; } - _LIBCPP_HIDE_FROM_ABI - const value_type* c_str() const noexcept { return __pn_.c_str(); } + _LIBCPP_HIDE_FROM_ABI const value_type* c_str() const noexcept { return __pn_.c_str(); } _LIBCPP_HIDE_FROM_ABI operator string_type() const { return __pn_; } -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { return __pn_; } - _LIBCPP_HIDE_FROM_ABI - std::wstring generic_wstring() const { + _LIBCPP_HIDE_FROM_ABI std::wstring generic_wstring() const { std::wstring __s; __s.resize(__pn_.size()); std::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/'); return __s; } -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - template , - class _Allocator = allocator<_ECharT> > - _LIBCPP_HIDE_FROM_ABI - basic_string<_ECharT, _Traits, _Allocator> - string(const _Allocator& __a = _Allocator()) const { +# if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> string(const _Allocator& __a = _Allocator()) const { using _Str = basic_string<_ECharT, _Traits, _Allocator>; _Str __s(__a); __s.reserve(__pn_.size()); @@ -801,9 +691,7 @@ public: return __s; } - _LIBCPP_HIDE_FROM_ABI std::string string() const { - return string(); - } + _LIBCPP_HIDE_FROM_ABI std::string string() const { return string(); } _LIBCPP_HIDE_FROM_ABI __u8_string u8string() const { using _CVT = __narrow_to_utf8; __u8_string __s; @@ -812,54 +700,43 @@ public: return __s; } - _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { - return string(); - } - _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { - return string(); - } + _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { return string(); } + _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { return string(); } // generic format observers - template , - class _Allocator = allocator<_ECharT> > - _LIBCPP_HIDE_FROM_ABI - basic_string<_ECharT, _Traits, _Allocator> + template , class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> generic_string(const _Allocator& __a = _Allocator()) const { using _Str = basic_string<_ECharT, _Traits, _Allocator>; - _Str __s = string<_ECharT, _Traits, _Allocator>(__a); + _Str __s = string<_ECharT, _Traits, _Allocator>(__a); // Note: This (and generic_u8string below) is slightly suboptimal as // it iterates twice over the string; once to convert it to the right // character type, and once to replace path delimiters. - std::replace(__s.begin(), __s.end(), - static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); + std::replace(__s.begin(), __s.end(), static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); return __s; } _LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return generic_string(); } _LIBCPP_HIDE_FROM_ABI std::u16string generic_u16string() const { return generic_string(); } _LIBCPP_HIDE_FROM_ABI std::u32string generic_u32string() const { return generic_string(); } - _LIBCPP_HIDE_FROM_ABI - __u8_string generic_u8string() const { + _LIBCPP_HIDE_FROM_ABI __u8_string generic_u8string() const { __u8_string __s = u8string(); std::replace(__s.begin(), __s.end(), '\\', '/'); return __s; } -#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ -#else /* _LIBCPP_WIN32API */ +# endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +# else /* _LIBCPP_WIN32API */ _LIBCPP_HIDE_FROM_ABI std::string string() const { return __pn_; } -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T _LIBCPP_HIDE_FROM_ABI std::u8string u8string() const { return std::u8string(__pn_.begin(), __pn_.end()); } -#else +# else _LIBCPP_HIDE_FROM_ABI std::string u8string() const { return __pn_; } -#endif +# endif -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - template , - class _Allocator = allocator<_ECharT> > - _LIBCPP_HIDE_FROM_ABI - basic_string<_ECharT, _Traits, _Allocator> - string(const _Allocator& __a = _Allocator()) const { +# if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> string(const _Allocator& __a = _Allocator()) const { using _CVT = __widen_from_utf8; using _Str = basic_string<_ECharT, _Traits, _Allocator>; _Str __s(__a); @@ -868,43 +745,35 @@ public: return __s; } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS - _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { - return string(); - } -#endif - _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { - return string(); - } - _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { - return string(); - } -#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { return string(); } +# endif + _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { return string(); } + _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { return string(); } +# endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ // generic format observers _LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return __pn_; } -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T _LIBCPP_HIDE_FROM_ABI std::u8string generic_u8string() const { return std::u8string(__pn_.begin(), __pn_.end()); } -#else +# else _LIBCPP_HIDE_FROM_ABI std::string generic_u8string() const { return __pn_; } -#endif +# endif -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - template , - class _Allocator = allocator<_ECharT> > - _LIBCPP_HIDE_FROM_ABI - basic_string<_ECharT, _Traits, _Allocator> +# if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> generic_string(const _Allocator& __a = _Allocator()) const { return string<_ECharT, _Traits, _Allocator>(__a); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS _LIBCPP_HIDE_FROM_ABI std::wstring generic_wstring() const { return string(); } -#endif +# endif _LIBCPP_HIDE_FROM_ABI std::u16string generic_u16string() const { return string(); } _LIBCPP_HIDE_FROM_ABI std::u32string generic_u32string() const { return string(); } -#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ -#endif /* !_LIBCPP_WIN32API */ +# endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +# endif /* !_LIBCPP_WIN32API */ private: int __compare(__string_view) const; @@ -919,80 +788,43 @@ private: public: // compare - _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept { - return __compare(__p.__pn_); - } - _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { - return __compare(__s); - } - _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const { - return __compare(__s); - } - _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { - return __compare(__s); - } + _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept { return __compare(__p.__pn_); } + _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { return __compare(__s); } + _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const { return __compare(__s); } + _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { return __compare(__s); } // decomposition - _LIBCPP_HIDE_FROM_ABI path root_name() const { - return string_type(__root_name()); - } - _LIBCPP_HIDE_FROM_ABI path root_directory() const { - return string_type(__root_directory()); - } + _LIBCPP_HIDE_FROM_ABI path root_name() const { return string_type(__root_name()); } + _LIBCPP_HIDE_FROM_ABI path root_directory() const { return string_type(__root_directory()); } _LIBCPP_HIDE_FROM_ABI path root_path() const { -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) return string_type(__root_path_raw()); -#else +# else return root_name().append(string_type(__root_directory())); -#endif - } - _LIBCPP_HIDE_FROM_ABI path relative_path() const { - return string_type(__relative_path()); - } - _LIBCPP_HIDE_FROM_ABI path parent_path() const { - return string_type(__parent_path()); - } - _LIBCPP_HIDE_FROM_ABI path filename() const { - return string_type(__filename()); +# endif } + _LIBCPP_HIDE_FROM_ABI path relative_path() const { return string_type(__relative_path()); } + _LIBCPP_HIDE_FROM_ABI path parent_path() const { return string_type(__parent_path()); } + _LIBCPP_HIDE_FROM_ABI path filename() const { return string_type(__filename()); } _LIBCPP_HIDE_FROM_ABI path stem() const { return string_type(__stem()); } - _LIBCPP_HIDE_FROM_ABI path extension() const { - return string_type(__extension()); - } + _LIBCPP_HIDE_FROM_ABI path extension() const { return string_type(__extension()); } // query - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool - empty() const noexcept { - return __pn_.empty(); - } - - _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { - return !__root_name().empty(); - } - _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { - return !__root_directory().empty(); - } - _LIBCPP_HIDE_FROM_ABI bool has_root_path() const { - return !__root_path_raw().empty(); - } - _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const { - return !__relative_path().empty(); - } - _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const { - return !__parent_path().empty(); - } - _LIBCPP_HIDE_FROM_ABI bool has_filename() const { - return !__filename().empty(); - } + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __pn_.empty(); } + + _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { return !__root_name().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { return !__root_directory().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_root_path() const { return !__root_path_raw().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const { return !__relative_path().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const { return !__parent_path().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_filename() const { return !__filename().empty(); } _LIBCPP_HIDE_FROM_ABI bool has_stem() const { return !__stem().empty(); } - _LIBCPP_HIDE_FROM_ABI bool has_extension() const { - return !__extension().empty(); - } + _LIBCPP_HIDE_FROM_ABI bool has_extension() const { return !__extension().empty(); } _LIBCPP_HIDE_FROM_ABI bool is_absolute() const { -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) __string_view __root_name_str = __root_name(); - __string_view __root_dir = __root_directory(); + __string_view __root_dir = __root_directory(); if (__root_name_str.size() == 2 && __root_name_str[1] == ':') { // A drive letter with no root directory is relative, e.g. x:example. return !__root_dir.empty(); @@ -1009,9 +841,9 @@ public: return false; // Seems to be a server root name return true; -#else +# else return has_root_directory(); -#endif +# endif } _LIBCPP_HIDE_FROM_ABI bool is_relative() const { return !is_absolute(); } @@ -1033,21 +865,23 @@ public: iterator begin() const; iterator end() const; -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - template ::value && - is_same<_Traits, char_traits >::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { +# if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template < + class _CharT, + class _Traits, + __enable_if_t::value && is_same<_Traits, char_traits >::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { __os << std::__quoted(__p.native()); return __os; } - template ::value || - !is_same<_Traits, char_traits >::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI friend - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + template < + class _CharT, + class _Traits, + __enable_if_t::value || !is_same<_Traits, char_traits >::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { __os << std::__quoted(__p.string<_CharT, _Traits>()); return __os; } @@ -1060,7 +894,7 @@ public: __p = __tmp; return __is; } -#endif // !_LIBCPP_HAS_NO_LOCALIZATION +# endif // !_LIBCPP_HAS_NO_LOCALIZATION private: inline _LIBCPP_HIDE_FROM_ABI path& __assign_view(__string_view const& __s) { @@ -1070,9 +904,7 @@ private: string_type __pn_; }; -inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept { - __lhs.swap(__rhs); -} +inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); } _LIBCPP_EXPORTED_FROM_ABI size_t hash_value(const path& __p) noexcept; diff --git a/libcxx/include/__filesystem/path_iterator.h b/libcxx/include/__filesystem/path_iterator.h index 598d65d3d72e4e14ce76679ae67fc60dfedc826b..1a9aaf0e7d99e6920f780d4bdb59f972899943bc 100644 --- a/libcxx/include/__filesystem/path_iterator.h +++ b/libcxx/include/__filesystem/path_iterator.h @@ -49,49 +49,37 @@ public: typedef path reference; public: - _LIBCPP_HIDE_FROM_ABI - iterator() - : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), - __state_(_Singular) {} + _LIBCPP_HIDE_FROM_ABI iterator() : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), __state_(_Singular) {} _LIBCPP_HIDE_FROM_ABI iterator(const iterator&) = default; - _LIBCPP_HIDE_FROM_ABI ~iterator() = default; + _LIBCPP_HIDE_FROM_ABI ~iterator() = default; _LIBCPP_HIDE_FROM_ABI iterator& operator=(const iterator&) = default; - _LIBCPP_HIDE_FROM_ABI - reference operator*() const { return __stashed_elem_; } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __stashed_elem_; } - _LIBCPP_HIDE_FROM_ABI - pointer operator->() const { return &__stashed_elem_; } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return &__stashed_elem_; } - _LIBCPP_HIDE_FROM_ABI - iterator& operator++() { - _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _Singular, - "attempting to increment a singular iterator"); - _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _AtEnd, - "attempting to increment the end iterator"); + _LIBCPP_HIDE_FROM_ABI iterator& operator++() { + _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _Singular, "attempting to increment a singular iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _AtEnd, "attempting to increment the end iterator"); return __increment(); } - _LIBCPP_HIDE_FROM_ABI - iterator operator++(int) { + _LIBCPP_HIDE_FROM_ABI iterator operator++(int) { iterator __it(*this); this->operator++(); return __it; } - _LIBCPP_HIDE_FROM_ABI - iterator& operator--() { - _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _Singular, - "attempting to decrement a singular iterator"); - _LIBCPP_ASSERT_UNCATEGORIZED(__entry_.data() != __path_ptr_->native().data(), - "attempting to decrement the begin iterator"); + _LIBCPP_HIDE_FROM_ABI iterator& operator--() { + _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _Singular, "attempting to decrement a singular iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED( + __entry_.data() != __path_ptr_->native().data(), "attempting to decrement the begin iterator"); return __decrement(); } - _LIBCPP_HIDE_FROM_ABI - iterator operator--(int) { + _LIBCPP_HIDE_FROM_ABI iterator operator--(int) { iterator __it(*this); this->operator--(); return __it; @@ -100,8 +88,7 @@ public: private: friend class path; - inline _LIBCPP_HIDE_FROM_ABI friend bool operator==(const iterator&, - const iterator&); + inline _LIBCPP_HIDE_FROM_ABI friend bool operator==(const iterator&, const iterator&); iterator& __increment(); iterator& __decrement(); @@ -113,15 +100,12 @@ private: }; _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY -inline _LIBCPP_HIDE_FROM_ABI bool operator==(const path::iterator& __lhs, - const path::iterator& __rhs) { - return __lhs.__path_ptr_ == __rhs.__path_ptr_ && - __lhs.__entry_.data() == __rhs.__entry_.data(); +inline _LIBCPP_HIDE_FROM_ABI bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) { + return __lhs.__path_ptr_ == __rhs.__path_ptr_ && __lhs.__entry_.data() == __rhs.__entry_.data(); } _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY -inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const path::iterator& __lhs, - const path::iterator& __rhs) { +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) { return !(__lhs == __rhs); } diff --git a/libcxx/include/__filesystem/perm_options.h b/libcxx/include/__filesystem/perm_options.h index ecf506fa4e8fcabb4d71264dac72af1bbf906e92..529ef13558e97272ffe5cc9c9fd4aaf7df6aab8c 100644 --- a/libcxx/include/__filesystem/perm_options.h +++ b/libcxx/include/__filesystem/perm_options.h @@ -21,48 +21,33 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -enum class perm_options : unsigned char { - replace = 1, - add = 2, - remove = 4, - nofollow = 8 -}; - -_LIBCPP_HIDE_FROM_ABI -inline constexpr perm_options operator&(perm_options __lhs, perm_options __rhs) { - return static_cast(static_cast(__lhs) & - static_cast(__rhs)); +enum class perm_options : unsigned char { replace = 1, add = 2, remove = 4, nofollow = 8 }; + +_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator&(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) & static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr perm_options operator|(perm_options __lhs, perm_options __rhs) { - return static_cast(static_cast(__lhs) | - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator|(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) | static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr perm_options operator^(perm_options __lhs, perm_options __rhs) { - return static_cast(static_cast(__lhs) ^ - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator^(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) ^ static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr perm_options operator~(perm_options __lhs) { +_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator~(perm_options __lhs) { return static_cast(~static_cast(__lhs)); } -_LIBCPP_HIDE_FROM_ABI -inline perm_options& operator&=(perm_options& __lhs, perm_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline perm_options& operator&=(perm_options& __lhs, perm_options __rhs) { return __lhs = __lhs & __rhs; } -_LIBCPP_HIDE_FROM_ABI -inline perm_options& operator|=(perm_options& __lhs, perm_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline perm_options& operator|=(perm_options& __lhs, perm_options __rhs) { return __lhs = __lhs | __rhs; } -_LIBCPP_HIDE_FROM_ABI -inline perm_options& operator^=(perm_options& __lhs, perm_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline perm_options& operator^=(perm_options& __lhs, perm_options __rhs) { return __lhs = __lhs ^ __rhs; } diff --git a/libcxx/include/__filesystem/perms.h b/libcxx/include/__filesystem/perms.h index 9f45f0c25f034233acfb02c3962764c075b05448..8f5f9a7e8248ef0d449fdf2b58b80fbffadd9e49 100644 --- a/libcxx/include/__filesystem/perms.h +++ b/libcxx/include/__filesystem/perms.h @@ -28,61 +28,51 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM enum class perms : unsigned { none = 0, - owner_read = 0400, + owner_read = 0400, owner_write = 0200, - owner_exec = 0100, - owner_all = 0700, + owner_exec = 0100, + owner_all = 0700, - group_read = 040, + group_read = 040, group_write = 020, - group_exec = 010, - group_all = 070, + group_exec = 010, + group_all = 070, - others_read = 04, + others_read = 04, others_write = 02, - others_exec = 01, - others_all = 07, + others_exec = 01, + others_all = 07, all = 0777, - set_uid = 04000, - set_gid = 02000, + set_uid = 04000, + set_gid = 02000, sticky_bit = 01000, - mask = 07777, - unknown = 0xFFFF, + mask = 07777, + unknown = 0xFFFF, }; -_LIBCPP_HIDE_FROM_ABI -inline constexpr perms operator&(perms __lhs, perms __rhs) { - return static_cast(static_cast(__lhs) & - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator&(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) & static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr perms operator|(perms __lhs, perms __rhs) { - return static_cast(static_cast(__lhs) | - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator|(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) | static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr perms operator^(perms __lhs, perms __rhs) { - return static_cast(static_cast(__lhs) ^ - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator^(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) ^ static_cast(__rhs)); } -_LIBCPP_HIDE_FROM_ABI -inline constexpr perms operator~(perms __lhs) { +_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator~(perms __lhs) { return static_cast(~static_cast(__lhs)); } -_LIBCPP_HIDE_FROM_ABI -inline perms& operator&=(perms& __lhs, perms __rhs) { return __lhs = __lhs & __rhs; } +_LIBCPP_HIDE_FROM_ABI inline perms& operator&=(perms& __lhs, perms __rhs) { return __lhs = __lhs & __rhs; } -_LIBCPP_HIDE_FROM_ABI -inline perms& operator|=(perms& __lhs, perms __rhs) { return __lhs = __lhs | __rhs; } +_LIBCPP_HIDE_FROM_ABI inline perms& operator|=(perms& __lhs, perms __rhs) { return __lhs = __lhs | __rhs; } -_LIBCPP_HIDE_FROM_ABI -inline perms& operator^=(perms& __lhs, perms __rhs) { return __lhs = __lhs ^ __rhs; } +_LIBCPP_HIDE_FROM_ABI inline perms& operator^=(perms& __lhs, perms __rhs) { return __lhs = __lhs ^ __rhs; } _LIBCPP_END_NAMESPACE_FILESYSTEM diff --git a/libcxx/include/__filesystem/recursive_directory_iterator.h b/libcxx/include/__filesystem/recursive_directory_iterator.h index e0aac636db8c8449a8cc403db0f0f46062fa14d6..7519cc2f2932f2c1c079f2d1a87333b6a33cb34d 100644 --- a/libcxx/include/__filesystem/recursive_directory_iterator.h +++ b/libcxx/include/__filesystem/recursive_directory_iterator.h @@ -36,40 +36,32 @@ _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH class recursive_directory_iterator { public: - using value_type = directory_entry; - using difference_type = ptrdiff_t; - using pointer = directory_entry const*; - using reference = directory_entry const&; + using value_type = directory_entry; + using difference_type = ptrdiff_t; + using pointer = directory_entry const*; + using reference = directory_entry const&; using iterator_category = input_iterator_tag; public: // constructors and destructor - _LIBCPP_HIDE_FROM_ABI - recursive_directory_iterator() noexcept : __rec_(false) {} + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator() noexcept : __rec_(false) {} - _LIBCPP_HIDE_FROM_ABI - explicit recursive_directory_iterator( + _LIBCPP_HIDE_FROM_ABI explicit recursive_directory_iterator( const path& __p, directory_options __xoptions = directory_options::none) : recursive_directory_iterator(__p, __xoptions, nullptr) {} - _LIBCPP_HIDE_FROM_ABI - recursive_directory_iterator(const path& __p, directory_options __xoptions, - error_code& __ec) + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __xoptions, error_code& __ec) : recursive_directory_iterator(__p, __xoptions, &__ec) {} - _LIBCPP_HIDE_FROM_ABI - recursive_directory_iterator(const path& __p, error_code& __ec) + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const path& __p, error_code& __ec) : recursive_directory_iterator(__p, directory_options::none, &__ec) {} _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const recursive_directory_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(recursive_directory_iterator&&) = default; + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(recursive_directory_iterator&&) = default; - _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& - operator=(const recursive_directory_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator=(const recursive_directory_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI - recursive_directory_iterator& - operator=(recursive_directory_iterator&& __o) noexcept { + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator=(recursive_directory_iterator&& __o) noexcept { // non-default implementation provided to support self-move assign. if (this != &__o) { __imp_ = std::move(__o.__imp_); @@ -80,40 +72,30 @@ public: _LIBCPP_HIDE_FROM_ABI ~recursive_directory_iterator() = default; - _LIBCPP_HIDE_FROM_ABI - const directory_entry& operator*() const { return __dereference(); } + _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const { return __dereference(); } - _LIBCPP_HIDE_FROM_ABI - const directory_entry* operator->() const { return &__dereference(); } + _LIBCPP_HIDE_FROM_ABI const directory_entry* operator->() const { return &__dereference(); } _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator++() { return __increment(); } - _LIBCPP_HIDE_FROM_ABI - __dir_element_proxy operator++(int) { + _LIBCPP_HIDE_FROM_ABI __dir_element_proxy operator++(int) { __dir_element_proxy __p(**this); __increment(); return __p; } - _LIBCPP_HIDE_FROM_ABI - recursive_directory_iterator& increment(error_code& __ec) { - return __increment(&__ec); - } + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } _LIBCPP_EXPORTED_FROM_ABI directory_options options() const; _LIBCPP_EXPORTED_FROM_ABI int depth() const; - _LIBCPP_HIDE_FROM_ABI - void pop() { __pop(); } + _LIBCPP_HIDE_FROM_ABI void pop() { __pop(); } - _LIBCPP_HIDE_FROM_ABI - void pop(error_code& __ec) { __pop(&__ec); } + _LIBCPP_HIDE_FROM_ABI void pop(error_code& __ec) { __pop(&__ec); } - _LIBCPP_HIDE_FROM_ABI - bool recursion_pending() const { return __rec_; } + _LIBCPP_HIDE_FROM_ABI bool recursion_pending() const { return __rec_; } - _LIBCPP_HIDE_FROM_ABI - void disable_recursion_pending() { __rec_ = false; } + _LIBCPP_HIDE_FROM_ABI void disable_recursion_pending() { __rec_ = false; } # if _LIBCPP_STD_VER >= 20 @@ -132,8 +114,7 @@ private: _LIBCPP_EXPORTED_FROM_ABI void __pop(error_code* __ec = nullptr); inline _LIBCPP_HIDE_FROM_ABI friend bool - operator==(const recursive_directory_iterator&, - const recursive_directory_iterator&) noexcept; + operator==(const recursive_directory_iterator&, const recursive_directory_iterator&) noexcept; struct _LIBCPP_HIDDEN __shared_imp; shared_ptr<__shared_imp> __imp_; @@ -141,24 +122,20 @@ private: }; // class recursive_directory_iterator inline _LIBCPP_HIDE_FROM_ABI bool -operator==(const recursive_directory_iterator& __lhs, - const recursive_directory_iterator& __rhs) noexcept { +operator==(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs) noexcept { return __lhs.__imp_ == __rhs.__imp_; } -_LIBCPP_HIDE_FROM_ABI -inline bool operator!=(const recursive_directory_iterator& __lhs, - const recursive_directory_iterator& __rhs) noexcept { +_LIBCPP_HIDE_FROM_ABI inline bool +operator!=(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs) noexcept { return !(__lhs == __rhs); } // enable recursive_directory_iterator range-based for statements -inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator -begin(recursive_directory_iterator __iter) noexcept { +inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator begin(recursive_directory_iterator __iter) noexcept { return __iter; } -inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator -end(recursive_directory_iterator) noexcept { +inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator end(recursive_directory_iterator) noexcept { return recursive_directory_iterator(); } @@ -166,17 +143,17 @@ _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_END_NAMESPACE_FILESYSTEM -#if _LIBCPP_STD_VER >= 20 +# if _LIBCPP_STD_VER >= 20 template <> -_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY -inline constexpr bool std::ranges::enable_borrowed_range = true; +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool + std::ranges::enable_borrowed_range = true; template <> -_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY -inline constexpr bool std::ranges::enable_view = true; +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool + std::ranges::enable_view = true; -#endif // _LIBCPP_STD_VER >= 20 +# endif // _LIBCPP_STD_VER >= 20 #endif // _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) diff --git a/libcxx/include/__filesystem/u8path.h b/libcxx/include/__filesystem/u8path.h index a79007e969ca8f4dddab8aa81b9ee38cdd50aec0..bde878054865e15e1829c431b2d739db0633ccc2 100644 --- a/libcxx/include/__filesystem/u8path.h +++ b/libcxx/include/__filesystem/u8path.h @@ -19,7 +19,7 @@ // Only required on Windows for __widen_from_utf8, and included conservatively // because it requires support for localization. #if defined(_LIBCPP_WIN32API) -# include +# include #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -33,38 +33,34 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T - path - u8path(_InputIt __f, _InputIt __l) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _InputIt __l) { static_assert( -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T is_same::__char_type, char8_t>::value || -#endif - is_same::__char_type, char>::value, +# endif + is_same::__char_type, char>::value, "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" " or 'char8_t'"); -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) string __tmp(__f, __l); using _CVT = __widen_from_utf8; std::wstring __w; __w.reserve(__tmp.size()); _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); return path(__w); -#else +# else return path(__f, __l); -#endif /* !_LIBCPP_WIN32API */ +# endif /* !_LIBCPP_WIN32API */ } -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T - path - u8path(_InputIt __f, _NullSentinel) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _NullSentinel) { static_assert( -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T is_same::__char_type, char8_t>::value || -#endif - is_same::__char_type, char>::value, +# endif + is_same::__char_type, char>::value, "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" " or 'char8_t'"); string __tmp; @@ -77,25 +73,23 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); return path(__w); } -#endif /* _LIBCPP_WIN32API */ +# endif /* _LIBCPP_WIN32API */ template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T - path - u8path(const _Source& __s) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(const _Source& __s) { static_assert( -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T is_same::__char_type, char8_t>::value || -#endif - is_same::__char_type, char>::value, +# endif + is_same::__char_type, char>::value, "u8path(Source const&) requires Source have a character type of type " "'char' or 'char8_t'"); -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) using _Traits = __is_pathable<_Source>; return u8path(std::__unwrap_iter(_Traits::__range_begin(__s)), std::__unwrap_iter(_Traits::__range_end(__s))); -#else +# else return path(__s); -#endif +# endif } _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP diff --git a/libcxx/include/__format/buffer.h b/libcxx/include/__format/buffer.h index 8aa58d6464bbf759137ca102ce73621c66fe1480..7ee583d8139455acb0119429cba7756854ef5893 100644 --- a/libcxx/include/__format/buffer.h +++ b/libcxx/include/__format/buffer.h @@ -71,7 +71,7 @@ public: __obj_(__obj) {} _LIBCPP_HIDE_FROM_ABI void __reset(_CharT* __ptr, size_t __capacity) { - __ptr_ = __ptr; + __ptr_ = __ptr; __capacity_ = __capacity; } @@ -130,8 +130,10 @@ public: /// A std::transform wrapper. /// /// Like @ref __copy it may need to do type conversion. - template <__fmt_char_type _InCharT, class _UnaryOperation> - _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) { + template ::value_type> + _LIBCPP_HIDE_FROM_ABI void __transform(_Iterator __first, _Iterator __last, _UnaryOperation __operation) { _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "not a valid range"); size_t __n = static_cast(__last - __first); @@ -251,19 +253,18 @@ template <__fmt_char_type _CharT> class _LIBCPP_TEMPLATE_VIS __direct_storage {}; template -concept __enable_direct_output = __fmt_char_type<_CharT> && +concept __enable_direct_output = + __fmt_char_type<_CharT> && (same_as<_OutIt, _CharT*> // TODO(hardening): the following check might not apply to hardened iterators and might need to be wrapped in an // `#ifdef`. - || same_as<_OutIt, __wrap_iter<_CharT*>> - ); + || same_as<_OutIt, __wrap_iter<_CharT*>>); /// Write policy for directly writing to the underlying output. template class _LIBCPP_TEMPLATE_VIS __writer_direct { public: - _LIBCPP_HIDE_FROM_ABI explicit __writer_direct(_OutIt __out_it) - : __out_it_(__out_it) {} + _LIBCPP_HIDE_FROM_ABI explicit __writer_direct(_OutIt __out_it) : __out_it_(__out_it) {} _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() { return __out_it_; } @@ -281,8 +282,7 @@ private: template class _LIBCPP_TEMPLATE_VIS __writer_iterator { public: - _LIBCPP_HIDE_FROM_ABI explicit __writer_iterator(_OutIt __out_it) - : __out_it_{std::move(__out_it)} {} + _LIBCPP_HIDE_FROM_ABI explicit __writer_iterator(_OutIt __out_it) : __out_it_{std::move(__out_it)} {} _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { return std::move(__out_it_); } @@ -304,7 +304,8 @@ private: template concept __insertable = __enable_insertable<_Container> && __fmt_char_type && - requires(_Container& __t, add_pointer_t __first, + requires(_Container& __t, + add_pointer_t __first, add_pointer_t __last) { __t.insert(__t.end(), __first, __last); }; /// Extract the container type of a \ref back_insert_iterator. @@ -343,28 +344,29 @@ class _LIBCPP_TEMPLATE_VIS __writer_selector { using _Container = typename __back_insert_iterator_container<_OutIt>::type; public: - using type = conditional_t, __writer_container<_Container>, - conditional_t<__enable_direct_output<_OutIt, _CharT>, __writer_direct<_OutIt, _CharT>, - __writer_iterator<_OutIt, _CharT>>>; + using type = + conditional_t, + __writer_container<_Container>, + conditional_t<__enable_direct_output<_OutIt, _CharT>, + __writer_direct<_OutIt, _CharT>, + __writer_iterator<_OutIt, _CharT>>>; }; /// The generic formatting buffer. template -requires(output_iterator<_OutIt, const _CharT&>) class _LIBCPP_TEMPLATE_VIS - __format_buffer { + requires(output_iterator<_OutIt, const _CharT&>) +class _LIBCPP_TEMPLATE_VIS __format_buffer { using _Storage = - conditional_t<__enable_direct_output<_OutIt, _CharT>, - __direct_storage<_CharT>, __internal_storage<_CharT>>; + conditional_t<__enable_direct_output<_OutIt, _CharT>, __direct_storage<_CharT>, __internal_storage<_CharT>>; public: _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) requires(same_as<_Storage, __internal_storage<_CharT>>) : __output_(__storage_.__begin(), __storage_.__buffer_size, this), __writer_(std::move(__out_it)) {} - _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) requires( - same_as<_Storage, __direct_storage<_CharT>>) - : __output_(std::__unwrap_iter(__out_it), size_t(-1), this), - __writer_(std::move(__out_it)) {} + _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) + requires(same_as<_Storage, __direct_storage<_CharT>>) + : __output_(std::__unwrap_iter(__out_it), size_t(-1), this), __writer_(std::move(__out_it)) {} _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return __output_.__make_output_iterator(); } @@ -590,8 +592,10 @@ public: __size_ += __n; } - template <__fmt_char_type _InCharT, class _UnaryOperation> - _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) { + template ::value_type> + _LIBCPP_HIDE_FROM_ABI void __transform(_Iterator __first, _Iterator __last, _UnaryOperation __operation) { _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "not a valid range"); size_t __n = static_cast(__last - __first); diff --git a/libcxx/include/__format/concepts.h b/libcxx/include/__format/concepts.h index ae96b6a198118c463785e839eca5a1b5106e6508..299c5f40ee35b4ea843e55d76beb6e5bb4838783 100644 --- a/libcxx/include/__format/concepts.h +++ b/libcxx/include/__format/concepts.h @@ -74,7 +74,7 @@ concept __fmt_pair_like = __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2); # endif //_LIBCPP_STD_VER >= 23 -#endif //_LIBCPP_STD_VER >= 20 +#endif //_LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__format/format_arg.h b/libcxx/include/__format/format_arg.h index cc6be7a25660fb22d01942ca4c8c4c009a00215b..280c91082417548cdc8bad84cacccd1218ed7903 100644 --- a/libcxx/include/__format/format_arg.h +++ b/libcxx/include/__format/format_arg.h @@ -73,16 +73,16 @@ enum class __arg_t : uint8_t { }; inline constexpr unsigned __packed_arg_t_bits = 5; -inline constexpr uint8_t __packed_arg_t_mask = 0x1f; +inline constexpr uint8_t __packed_arg_t_mask = 0x1f; inline constexpr unsigned __packed_types_storage_bits = 64; -inline constexpr unsigned __packed_types_max = __packed_types_storage_bits / __packed_arg_t_bits; +inline constexpr unsigned __packed_types_max = __packed_types_storage_bits / __packed_arg_t_bits; -_LIBCPP_HIDE_FROM_ABI -constexpr bool __use_packed_format_arg_store(size_t __size) { return __size <= __packed_types_max; } +_LIBCPP_HIDE_FROM_ABI constexpr bool __use_packed_format_arg_store(size_t __size) { + return __size <= __packed_types_max; +} -_LIBCPP_HIDE_FROM_ABI -constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) { +_LIBCPP_HIDE_FROM_ABI constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) { _LIBCPP_ASSERT_UNCATEGORIZED(__id <= __packed_types_max, ""); if (__id > 0) @@ -96,8 +96,7 @@ constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) { // This function is not user obervable, so it can directly use the non-standard // types of the "variant". See __arg_t for more details. template -_LIBCPP_HIDE_FROM_ABI decltype(auto) -__visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { +_LIBCPP_HIDE_FROM_ABI decltype(auto) __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { switch (__arg.__type_) { case __format::__arg_t::__none: return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__monostate_); @@ -138,8 +137,8 @@ __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { case __format::__arg_t::__ptr: return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__ptr_); case __format::__arg_t::__handle: - return std::invoke(std::forward<_Visitor>(__vis), - typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_}); + return std::invoke( + std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_}); } __libcpp_unreachable(); @@ -224,12 +223,9 @@ class _LIBCPP_TEMPLATE_VIS basic_format_arg { public: class _LIBCPP_TEMPLATE_VIS handle; - _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept - : __type_{__format::__arg_t::__none} {} + _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept : __type_{__format::__arg_t::__none} {} - _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { - return __type_ != __format::__arg_t::__none; - } + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { return __type_ != __format::__arg_t::__none; } private: using char_type = typename _Context::char_type; @@ -257,8 +253,7 @@ public: template class _LIBCPP_TEMPLATE_VIS basic_format_arg<_Context>::handle { public: - _LIBCPP_HIDE_FROM_ABI - void format(basic_format_parse_context& __parse_ctx, _Context& __ctx) const { + _LIBCPP_HIDE_FROM_ABI void format(basic_format_parse_context& __parse_ctx, _Context& __ctx) const { __handle_.__format_(__parse_ctx, __ctx, __handle_.__ptr_); } @@ -272,8 +267,7 @@ private: // This function is user facing, so it must wrap the non-standard types of // the "variant" in a handle to stay conforming. See __arg_t for more details. template -_LIBCPP_HIDE_FROM_ABI decltype(auto) -visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { +_LIBCPP_HIDE_FROM_ABI decltype(auto) visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { switch (__arg.__type_) { # ifndef _LIBCPP_HAS_NO_INT128 case __format::__arg_t::__i128: { diff --git a/libcxx/include/__format/format_arg_store.h b/libcxx/include/__format/format_arg_store.h index 64ee12440b62f8f578ce30c055625ceae8c13587..c481992d2d719ac57a222ba04733a7e22ee0501f 100644 --- a/libcxx/include/__format/format_arg_store.h +++ b/libcxx/include/__format/format_arg_store.h @@ -243,8 +243,7 @@ struct __unpacked_format_arg_store { template struct _LIBCPP_TEMPLATE_VIS __format_arg_store { - _LIBCPP_HIDE_FROM_ABI - __format_arg_store(_Args&... __args) noexcept { + _LIBCPP_HIDE_FROM_ABI __format_arg_store(_Args&... __args) noexcept { if constexpr (sizeof...(_Args) != 0) { if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args))) __format::__create_packed_storage(__storage.__types_, __storage.__values_, __args...); @@ -253,9 +252,10 @@ struct _LIBCPP_TEMPLATE_VIS __format_arg_store { } } - using _Storage = conditional_t<__format::__use_packed_format_arg_store(sizeof...(_Args)), - __format::__packed_format_arg_store<_Context, sizeof...(_Args)>, - __format::__unpacked_format_arg_store<_Context, sizeof...(_Args)>>; + using _Storage = + conditional_t<__format::__use_packed_format_arg_store(sizeof...(_Args)), + __format::__packed_format_arg_store<_Context, sizeof...(_Args)>, + __format::__unpacked_format_arg_store<_Context, sizeof...(_Args)>>; _Storage __storage; }; diff --git a/libcxx/include/__format/format_args.h b/libcxx/include/__format/format_args.h index defb42a4ab0067fc48246d8480a2ba49da4bef01..9e0afecc0ae967212fa88c954050308776063235 100644 --- a/libcxx/include/__format/format_args.h +++ b/libcxx/include/__format/format_args.h @@ -37,14 +37,13 @@ public: if constexpr (sizeof...(_Args) != 0) { if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args))) { __values_ = __store.__storage.__values_; - __types_ = __store.__storage.__types_; + __types_ = __store.__storage.__types_; } else __args_ = __store.__storage.__args_; } } - _LIBCPP_HIDE_FROM_ABI - basic_format_arg<_Context> get(size_t __id) const noexcept { + _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> get(size_t __id) const noexcept { if (__id >= __size_) return basic_format_arg<_Context>{}; diff --git a/libcxx/include/__format/format_context.h b/libcxx/include/__format/format_context.h index 4e3d15ec862e7065c866c23b4a6d4f494f6016b4..5b252b81f691bc18091c7a0895cf8cfa34759e13 100644 --- a/libcxx/include/__format/format_context.h +++ b/libcxx/include/__format/format_context.h @@ -27,8 +27,8 @@ #include #ifndef _LIBCPP_HAS_NO_LOCALIZATION -#include -#include +# include +# include #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -40,10 +40,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -requires output_iterator<_OutIt, const _CharT&> + requires output_iterator<_OutIt, const _CharT&> class _LIBCPP_TEMPLATE_VIS basic_format_context; -#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# ifndef _LIBCPP_HAS_NO_LOCALIZATION /** * Helper to create a basic_format_context. * @@ -51,32 +51,26 @@ class _LIBCPP_TEMPLATE_VIS basic_format_context; */ template _LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> -__format_context_create( - _OutIt __out_it, - basic_format_args> __args, - optional&& __loc = nullopt) { +__format_context_create(_OutIt __out_it, + basic_format_args> __args, + optional&& __loc = nullopt) { return std::basic_format_context(std::move(__out_it), __args, std::move(__loc)); } -#else +# else template _LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> -__format_context_create( - _OutIt __out_it, - basic_format_args> __args) { +__format_context_create(_OutIt __out_it, basic_format_args> __args) { return std::basic_format_context(std::move(__out_it), __args); } -#endif +# endif -using format_context = - basic_format_context>, - char>; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -using wformat_context = basic_format_context< - back_insert_iterator<__format::__output_buffer>, wchar_t>; -#endif +using format_context = basic_format_context>, char>; +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wformat_context = basic_format_context< back_insert_iterator<__format::__output_buffer>, wchar_t>; +# endif template -requires output_iterator<_OutIt, const _CharT&> + requires output_iterator<_OutIt, const _CharT&> class // clang-format off _LIBCPP_TEMPLATE_VIS @@ -85,29 +79,28 @@ class // clang-format on basic_format_context { public: - using iterator = _OutIt; + using iterator = _OutIt; using char_type = _CharT; template using formatter_type = formatter<_Tp, _CharT>; - _LIBCPP_HIDE_FROM_ABI basic_format_arg - arg(size_t __id) const noexcept { + _LIBCPP_HIDE_FROM_ABI basic_format_arg arg(size_t __id) const noexcept { return __args_.get(__id); } -#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# ifndef _LIBCPP_HAS_NO_LOCALIZATION _LIBCPP_HIDE_FROM_ABI std::locale locale() { if (!__loc_) __loc_ = std::locale{}; return *__loc_; } -#endif +# endif _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); } _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); } private: iterator __out_it_; basic_format_args __args_; -#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# ifndef _LIBCPP_HAS_NO_LOCALIZATION // The Standard doesn't specify how the locale is stored. // [format.context]/6 @@ -121,27 +114,21 @@ private: optional __loc_; template - friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT> - __format_context_create(_OtherOutIt, basic_format_args>, - optional&&); + friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT> __format_context_create( + _OtherOutIt, basic_format_args>, optional&&); // Note: the Standard doesn't specify the required constructors. - _LIBCPP_HIDE_FROM_ABI - explicit basic_format_context(_OutIt __out_it, - basic_format_args __args, - optional&& __loc) - : __out_it_(std::move(__out_it)), __args_(__args), - __loc_(std::move(__loc)) {} -#else + _LIBCPP_HIDE_FROM_ABI explicit basic_format_context( + _OutIt __out_it, basic_format_args __args, optional&& __loc) + : __out_it_(std::move(__out_it)), __args_(__args), __loc_(std::move(__loc)) {} +# else template friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT> __format_context_create(_OtherOutIt, basic_format_args>); - _LIBCPP_HIDE_FROM_ABI - explicit basic_format_context(_OutIt __out_it, - basic_format_args __args) + _LIBCPP_HIDE_FROM_ABI explicit basic_format_context(_OutIt __out_it, basic_format_args __args) : __out_it_(std::move(__out_it)), __args_(__args) {} -#endif +# endif }; // A specialization for __retarget_buffer @@ -161,8 +148,7 @@ private: // Here the width of an element in input is determined dynamically. // Note when the top-level element has no width the retargeting is not needed. template -class _LIBCPP_TEMPLATE_VIS - basic_format_context::__iterator, _CharT> { +class _LIBCPP_TEMPLATE_VIS basic_format_context::__iterator, _CharT> { public: using iterator = typename __format::__retarget_buffer<_CharT>::__iterator; using char_type = _CharT; diff --git a/libcxx/include/__format/format_error.h b/libcxx/include/__format/format_error.h index 51d6c58230910e794bfb494cc1b7f1cece932fd1..ed40e395d6af7255cba96d81bc951ba1c0bc9710 100644 --- a/libcxx/include/__format/format_error.h +++ b/libcxx/include/__format/format_error.h @@ -26,24 +26,21 @@ _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") class _LIBCPP_EXPORTED_FROM_ABI format_error : public runtime_error { public: - _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s) - : runtime_error(__s) {} - _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s) - : runtime_error(__s) {} - _LIBCPP_HIDE_FROM_ABI format_error(const format_error&) = default; + _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s) : runtime_error(__s) {} + _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s) : runtime_error(__s) {} + _LIBCPP_HIDE_FROM_ABI format_error(const format_error&) = default; _LIBCPP_HIDE_FROM_ABI format_error& operator=(const format_error&) = default; _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~format_error() noexcept override = default; }; _LIBCPP_DIAGNOSTIC_POP -_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void -__throw_format_error(const char* __s) { -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS +_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_format_error(const char* __s) { +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS throw format_error(__s); -#else +# else _LIBCPP_VERBOSE_ABORT("format_error was thrown in -fno-exceptions mode with message \"%s\"", __s); -#endif +# endif } #endif //_LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h index 8b2111f0e287cbd69117223d355a1f0a6e762746..015bff70f51d9772721aa8f19968c3588b0776b8 100644 --- a/libcxx/include/__format/format_functions.h +++ b/libcxx/include/__format/format_functions.h @@ -41,7 +41,7 @@ #include #ifndef _LIBCPP_HAS_NO_LOCALIZATION -#include +# include #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -58,9 +58,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD // to do this optimization now. using format_args = basic_format_args; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS using wformat_args = basic_format_args; -#endif +# endif template _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&... __args) { @@ -188,9 +188,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_validate_argument( // This function is not user facing, so it can directly use the non-standard types of the "variant". template -_LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_format_parse_context<_CharT>& __parse_ctx, - __compile_time_basic_format_context<_CharT>& __ctx, - __arg_t __type) { +_LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg( + basic_format_parse_context<_CharT>& __parse_ctx, + __compile_time_basic_format_context<_CharT>& __ctx, + __arg_t __type) { switch (__type) { case __arg_t::__none: std::__throw_format_error("Invalid argument"); @@ -203,22 +204,22 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma case __arg_t::__long_long: return __format::__compile_time_validate_argument<_CharT, long long>(__parse_ctx, __ctx); case __arg_t::__i128: -# ifndef _LIBCPP_HAS_NO_INT128 +# ifndef _LIBCPP_HAS_NO_INT128 return __format::__compile_time_validate_argument<_CharT, __int128_t>(__parse_ctx, __ctx); -# else +# else std::__throw_format_error("Invalid argument"); -# endif +# endif return; case __arg_t::__unsigned: return __format::__compile_time_validate_argument<_CharT, unsigned>(__parse_ctx, __ctx); case __arg_t::__unsigned_long_long: return __format::__compile_time_validate_argument<_CharT, unsigned long long>(__parse_ctx, __ctx); case __arg_t::__u128: -# ifndef _LIBCPP_HAS_NO_INT128 +# ifndef _LIBCPP_HAS_NO_INT128 return __format::__compile_time_validate_argument<_CharT, __uint128_t>(__parse_ctx, __ctx); -# else +# else std::__throw_format_error("Invalid argument"); -# endif +# endif return; case __arg_t::__float: return __format::__compile_time_validate_argument<_CharT, float, true>(__parse_ctx, __ctx); @@ -240,9 +241,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma template _LIBCPP_HIDE_FROM_ABI constexpr _Iterator -__handle_replacement_field(_Iterator __begin, _Iterator __end, - _ParseCtx& __parse_ctx, _Ctx& __ctx) { - using _CharT = iter_value_t<_Iterator>; +__handle_replacement_field(_Iterator __begin, _Iterator __end, _ParseCtx& __parse_ctx, _Ctx& __ctx) { + using _CharT = iter_value_t<_Iterator>; __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); if (__r.__last == __end) @@ -294,13 +294,12 @@ __handle_replacement_field(_Iterator __begin, _Iterator __end, } template -_LIBCPP_HIDE_FROM_ABI constexpr typename _Ctx::iterator -__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { +_LIBCPP_HIDE_FROM_ABI constexpr typename _Ctx::iterator __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { using _CharT = typename _ParseCtx::char_type; static_assert(same_as); - auto __begin = __parse_ctx.begin(); - auto __end = __parse_ctx.end(); + auto __begin = __parse_ctx.begin(); + auto __end = __parse_ctx.end(); typename _Ctx::iterator __out_it = __ctx.out(); while (__begin != __end) { switch (*__begin) { @@ -311,8 +310,7 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { if (*__begin != _CharT('{')) [[likely]] { __ctx.advance_to(std::move(__out_it)); - __begin = - __format::__handle_replacement_field(__begin, __end, __parse_ctx, __ctx); + __begin = __format::__handle_replacement_field(__begin, __end, __parse_ctx, __ctx); __out_it = __ctx.out(); // The output is written and __begin points to the next character. So @@ -371,9 +369,7 @@ struct _LIBCPP_TEMPLATE_VIS basic_format_string { _Context{__types_.data(), __handles_.data(), sizeof...(_Args)}); } - _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<_CharT> get() const noexcept { - return __str_; - } + _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<_CharT> get() const noexcept { return __str_; } # if _LIBCPP_STD_VER >= 26 _LIBCPP_HIDE_FROM_ABI basic_format_string(__runtime_format_string<_CharT> __s) noexcept : __str_(__s.__str_) {} # endif @@ -399,23 +395,23 @@ private: template using format_string = basic_format_string...>; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template using wformat_string = basic_format_string...>; -#endif +# endif template -requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt - __vformat_to( - _OutIt __out_it, basic_string_view<_CharT> __fmt, - basic_format_args> __args) { + requires(output_iterator<_OutIt, const _CharT&>) +_LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to(_OutIt __out_it, + basic_string_view<_CharT> __fmt, + basic_format_args> __args) { if constexpr (same_as<_OutIt, _FormatOutIt>) - return std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, - std::__format_context_create(std::move(__out_it), __args)); + return std::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, std::__format_context_create(std::move(__out_it), __args)); else { __format::__format_buffer<_OutIt, _CharT> __buffer{std::move(__out_it)}; std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, - std::__format_context_create(__buffer.__make_output_iterator(), __args)); + std::__format_context_create(__buffer.__make_output_iterator(), __args)); return std::move(__buffer).__out_it(); } } @@ -424,34 +420,31 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt // https://reviews.llvm.org/D110499#inline-1180704 // TODO FMT Evaluate whether we want to file a Clang bug report regarding this. template _OutIt> -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt -vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { return std::__vformat_to(std::move(__out_it), __fmt, __args); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) { return std::__vformat_to(std::move(__out_it), __fmt, __args); } -#endif +# endif template _OutIt, class... _Args> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) { - return std::vformat_to(std::move(__out_it), __fmt.get(), - std::make_format_args(__args...)); + return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_format_args(__args...)); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt, class... _Args> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) { - return std::vformat_to(std::move(__out_it), __fmt.get(), - std::make_wformat_args(__args...)); + return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_wformat_args(__args...)); } -#endif +# endif // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. @@ -490,12 +483,14 @@ format(wformat_string<_Args...> __fmt, _Args&&... __args) { # endif template -_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, - basic_string_view<_CharT> __fmt, - basic_format_args<_Context> __args) { +_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> +__vformat_to_n(_OutIt __out_it, + iter_difference_t<_OutIt> __n, + basic_string_view<_CharT> __fmt, + basic_format_args<_Context> __args) { __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{std::move(__out_it), __n}; std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, - std::__format_context_create(__buffer.__make_output_iterator(), __args)); + std::__format_context_create(__buffer.__make_output_iterator(), __args)); return std::move(__buffer).__result(); } @@ -505,20 +500,19 @@ format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args. return std::__vformat_to_n(std::move(__out_it), __n, __fmt.get(), std::make_format_args(__args...)); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt, class... _Args> _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> -format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, - _Args&&... __args) { +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, _Args&&... __args) { return std::__vformat_to_n(std::move(__out_it), __n, __fmt.get(), std::make_wformat_args(__args...)); } -#endif +# endif template _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, auto __args) { __format::__formatted_size_buffer<_CharT> __buffer; std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, - std::__format_context_create(__buffer.__make_output_iterator(), __args)); + std::__format_context_create(__buffer.__make_output_iterator(), __args)); return std::move(__buffer).__result(); } @@ -539,14 +533,15 @@ formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) { # ifndef _LIBCPP_HAS_NO_LOCALIZATION template -requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt - __vformat_to( - _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, - basic_format_args> __args) { + requires(output_iterator<_OutIt, const _CharT&>) +_LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to( + _OutIt __out_it, + locale __loc, + basic_string_view<_CharT> __fmt, + basic_format_args> __args) { if constexpr (same_as<_OutIt, _FormatOutIt>) - return std::__format::__vformat_to( - basic_format_parse_context{__fmt, __args.__size()}, - std::__format_context_create(std::move(__out_it), __args, std::move(__loc))); + return std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + std::__format_context_create(std::move(__out_it), __args, std::move(__loc))); else { __format::__format_buffer<_OutIt, _CharT> __buffer{std::move(__out_it)}; std::__format::__vformat_to( @@ -557,36 +552,32 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt } template _OutIt> -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to( - _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { - return std::__vformat_to(std::move(__out_it), std::move(__loc), __fmt, - __args); +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt +vformat_to(_OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { + return std::__vformat_to(std::move(__out_it), std::move(__loc), __fmt, __args); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt> -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to( - _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { - return std::__vformat_to(std::move(__out_it), std::move(__loc), __fmt, - __args); +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt +vformat_to(_OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { + return std::__vformat_to(std::move(__out_it), std::move(__loc), __fmt, __args); } -#endif +# endif template _OutIt, class... _Args> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { - return std::vformat_to(std::move(__out_it), std::move(__loc), __fmt.get(), - std::make_format_args(__args...)); + return std::vformat_to(std::move(__out_it), std::move(__loc), __fmt.get(), std::make_format_args(__args...)); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt, class... _Args> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { - return std::vformat_to(std::move(__out_it), std::move(__loc), __fmt.get(), - std::make_wformat_args(__args...)); + return std::vformat_to(std::move(__out_it), std::move(__loc), __fmt.get(), std::make_wformat_args(__args...)); } -#endif +# endif // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. @@ -594,8 +585,7 @@ template _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(locale __loc, string_view __fmt, format_args __args) { string __res; - std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, - __args); + std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args); return __res; } @@ -606,8 +596,7 @@ template _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring vformat(locale __loc, wstring_view __fmt, wformat_args __args) { wstring __res; - std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, - __args); + std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args); return __res; } # endif @@ -615,23 +604,24 @@ vformat(locale __loc, wstring_view __fmt, wformat_args __args) { template _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string format(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { - return std::vformat(std::move(__loc), __fmt.get(), - std::make_format_args(__args...)); + return std::vformat(std::move(__loc), __fmt.get(), std::make_format_args(__args...)); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { - return std::vformat(std::move(__loc), __fmt.get(), - std::make_wformat_args(__args...)); + return std::vformat(std::move(__loc), __fmt.get(), std::make_wformat_args(__args...)); } # endif template -_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, - locale __loc, basic_string_view<_CharT> __fmt, - basic_format_args<_Context> __args) { +_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n( + _OutIt __out_it, + iter_difference_t<_OutIt> __n, + locale __loc, + basic_string_view<_CharT> __fmt, + basic_format_args<_Context> __args) { __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{std::move(__out_it), __n}; std::__format::__vformat_to( basic_format_parse_context{__fmt, __args.__size()}, @@ -640,22 +630,20 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, } template _OutIt, class... _Args> -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> -format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt, - _Args&&... __args) { - return std::__vformat_to_n(std::move(__out_it), __n, std::move(__loc), __fmt.get(), - std::make_format_args(__args...)); +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> format_to_n( + _OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { + return std::__vformat_to_n( + std::move(__out_it), __n, std::move(__loc), __fmt.get(), std::make_format_args(__args...)); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt, class... _Args> -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> -format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt, - _Args&&... __args) { - return std::__vformat_to_n(std::move(__out_it), __n, std::move(__loc), __fmt.get(), - std::make_wformat_args(__args...)); +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> format_to_n( + _OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { + return std::__vformat_to_n( + std::move(__out_it), __n, std::move(__loc), __fmt.get(), std::make_wformat_args(__args...)); } -#endif +# endif template _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_CharT> __fmt, auto __args) { diff --git a/libcxx/include/__format/format_parse_context.h b/libcxx/include/__format/format_parse_context.h index 79f53f77d4a053b600c64e51feb15ab28ea2e021..aefcd5497f3b9b04ca1bdb7739be1462adf0b455 100644 --- a/libcxx/include/__format/format_parse_context.h +++ b/libcxx/include/__format/format_parse_context.h @@ -26,32 +26,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS basic_format_parse_context { public: - using char_type = _CharT; + using char_type = _CharT; using const_iterator = typename basic_string_view<_CharT>::const_iterator; - using iterator = const_iterator; + using iterator = const_iterator; - _LIBCPP_HIDE_FROM_ABI - constexpr explicit basic_format_parse_context(basic_string_view<_CharT> __fmt, - size_t __num_args = 0) noexcept + _LIBCPP_HIDE_FROM_ABI constexpr explicit basic_format_parse_context( + basic_string_view<_CharT> __fmt, size_t __num_args = 0) noexcept : __begin_(__fmt.begin()), __end_(__fmt.end()), __indexing_(__unknown), __next_arg_id_(0), __num_args_(__num_args) {} - basic_format_parse_context(const basic_format_parse_context&) = delete; - basic_format_parse_context& - operator=(const basic_format_parse_context&) = delete; + basic_format_parse_context(const basic_format_parse_context&) = delete; + basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; - _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { - return __begin_; - } - _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { - return __end_; - } - _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(const_iterator __it) { - __begin_ = __it; - } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { return __begin_; } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { return __end_; } + _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(const_iterator __it) { __begin_ = __it; } _LIBCPP_HIDE_FROM_ABI constexpr size_t next_arg_id() { if (__indexing_ == __manual) @@ -102,9 +94,9 @@ private: _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_parse_context); using format_parse_context = basic_format_parse_context; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS using wformat_parse_context = basic_format_parse_context; -#endif +# endif #endif //_LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__format/format_string.h b/libcxx/include/__format/format_string.h index 2e1c71b3d01b2479ce6b7a833a41ebefc8685b58..bdf3cff7f49b1824fb2ce68711f296cf1241bf68 100644 --- a/libcxx/include/__format/format_string.h +++ b/libcxx/include/__format/format_string.h @@ -38,8 +38,7 @@ template __parse_number_result(_Iterator, uint32_t) -> __parse_number_result<_Iterator>; template -_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> -__parse_number(_Iterator __begin, _Iterator __end); +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> __parse_number(_Iterator __begin, _Iterator __end); /** * The maximum value of a numeric argument. @@ -66,9 +65,7 @@ template _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> __parse_automatic(_Iterator __begin, _Iterator, auto& __parse_ctx) { size_t __value = __parse_ctx.next_arg_id(); - _LIBCPP_ASSERT_UNCATEGORIZED( - __value <= __number_max, - "Compilers don't support this number of arguments"); + _LIBCPP_ASSERT_UNCATEGORIZED(__value <= __number_max, "Compilers don't support this number of arguments"); return {__begin, uint32_t(__value)}; } @@ -93,8 +90,7 @@ template _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> __parse_number(_Iterator __begin, _Iterator __end_input) { using _CharT = iter_value_t<_Iterator>; - static_assert(__format::__number_max == INT32_MAX, - "The algorithm is implemented based on this value."); + static_assert(__format::__number_max == INT32_MAX, "The algorithm is implemented based on this value."); /* * Limit the input to 9 digits, otherwise we need two checks during every * iteration: @@ -102,7 +98,7 @@ __parse_number(_Iterator __begin, _Iterator __end_input) { * - Does the value exceed width of an uint32_t? (Switching to uint64_t would * have the same issue, but with a higher maximum.) */ - _Iterator __end = __end_input - __begin > 9 ? __begin + 9 : __end_input; + _Iterator __end = __end_input - __begin > 9 ? __begin + 9 : __end_input; uint32_t __value = *__begin - _CharT('0'); while (++__begin != __end) { if (*__begin < _CharT('0') || *__begin > _CharT('9')) @@ -111,9 +107,7 @@ __parse_number(_Iterator __begin, _Iterator __end_input) { __value = __value * 10 + *__begin - _CharT('0'); } - if (__begin != __end_input && *__begin >= _CharT('0') && - *__begin <= _CharT('9')) { - + if (__begin != __end_input && *__begin >= _CharT('0') && *__begin <= _CharT('9')) { /* * There are more than 9 digits, do additional validations: * - Does the 10th digit exceed the maximum allowed value? @@ -121,9 +115,7 @@ __parse_number(_Iterator __begin, _Iterator __end_input) { * (More than 10 digits always overflows the maximum.) */ uint64_t __v = uint64_t(__value) * 10 + *__begin++ - _CharT('0'); - if (__v > __number_max || - (__begin != __end_input && *__begin >= _CharT('0') && - *__begin <= _CharT('9'))) + if (__v > __number_max || (__begin != __end_input && *__begin >= _CharT('0') && *__begin <= _CharT('9'))) std::__throw_format_error("The numeric value of the format specifier is too large"); __value = __v; diff --git a/libcxx/include/__format/formatter.h b/libcxx/include/__format/formatter.h index 172b2d5f7b8a184632f77f2a9a85ee76755cf834..079befc5bd9ca61836d551acab034395a720870c 100644 --- a/libcxx/include/__format/formatter.h +++ b/libcxx/include/__format/formatter.h @@ -33,8 +33,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD /// - is_move_assignable. template struct _LIBCPP_TEMPLATE_VIS formatter { - formatter() = delete; - formatter(const formatter&) = delete; + formatter() = delete; + formatter(const formatter&) = delete; formatter& operator=(const formatter&) = delete; }; diff --git a/libcxx/include/__format/formatter_floating_point.h b/libcxx/include/__format/formatter_floating_point.h index b45c2a6ebd39be01d3b07b2cc98a73f2c23637da..33cc2a4ed661221cb275095f960be6eb3ebafcd9 100644 --- a/libcxx/include/__format/formatter_floating_point.h +++ b/libcxx/include/__format/formatter_floating_point.h @@ -116,8 +116,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr size_t __float_buffer_size(int __precision) { template <> struct __traits { - static constexpr int __max_integral = 38; - static constexpr int __max_fractional = 149; + static constexpr int __max_integral = 38; + static constexpr int __max_fractional = 149; static constexpr int __max_fractional_value = 3; static constexpr size_t __stack_buffer_size = 256; @@ -126,8 +126,8 @@ struct __traits { template <> struct __traits { - static constexpr int __max_integral = 308; - static constexpr int __max_fractional = 1074; + static constexpr int __max_integral = 308; + static constexpr int __max_fractional = 1074; static constexpr int __max_fractional_value = 4; static constexpr size_t __stack_buffer_size = 1024; @@ -153,7 +153,6 @@ public: // required. explicit _LIBCPP_HIDE_FROM_ABI __float_buffer(int __precision) : __precision_(__precision != -1 ? __precision : _Traits::__max_fractional) { - // When the precision is larger than _Traits::__max_fractional the digits in // the range (_Traits::__max_fractional, precision] will contain the value // zero. There's no need to request to_chars to write these zeros: @@ -165,7 +164,7 @@ public: // to be converted from a char to a wchar_t. if (__precision_ > _Traits::__max_fractional) { __num_trailing_zeros_ = __precision_ - _Traits::__max_fractional; - __precision_ = _Traits::__max_fractional; + __precision_ = _Traits::__max_fractional; } __size_ = __formatter::__float_buffer_size<_Fp>(__precision_); @@ -180,7 +179,7 @@ public: if (__size_ > _Traits::__stack_buffer_size) allocator{}.deallocate(__begin_, __size_); } - _LIBCPP_HIDE_FROM_ABI __float_buffer(const __float_buffer&) = delete; + _LIBCPP_HIDE_FROM_ABI __float_buffer(const __float_buffer&) = delete; _LIBCPP_HIDE_FROM_ABI __float_buffer& operator=(const __float_buffer&) = delete; _LIBCPP_HIDE_FROM_ABI char* begin() const { return __begin_; } @@ -234,8 +233,8 @@ constexpr inline _LIBCPP_HIDE_FROM_ABI char* __find_exponent(char* __first, char } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffer<_Fp>& __buffer, _Tp __value, - char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result +__format_buffer_default(const __float_buffer<_Fp>& __buffer, _Tp __value, char* __integral) { __float_result __result; __result.__integral = __integral; __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value); @@ -263,9 +262,8 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffe } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(const __float_buffer<_Fp>& __buffer, - _Tp __value, int __precision, - char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case( + const __float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result; __result.__integral = __integral; if (__precision == -1) @@ -297,12 +295,12 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(cons // 0123456789 static_assert(__traits<_Fp>::__hex_precision_digits <= 4, "Guard against possible underflow."); - char* __last = __result.__last - 2; - __first = __last - __traits<_Fp>::__hex_precision_digits; + char* __last = __result.__last - 2; + __first = __last - __traits<_Fp>::__hex_precision_digits; __result.__exponent = std::find(__first, __last, 'p'); } else { __result.__radix_point = __result.__last; - __result.__exponent = __first; + __result.__exponent = __first; } // clang-format off @@ -316,9 +314,8 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(cons } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case(const __float_buffer<_Fp>& __buffer, - _Tp __value, int __precision, - char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case( + const __float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result = __formatter::__format_buffer_hexadecimal_lower_case(__buffer, __value, __precision, __integral); std::transform(__result.__integral, __result.__exponent, __result.__integral, __hex_to_upper); @@ -327,9 +324,8 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case(cons } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const __float_buffer<_Fp>& __buffer, - _Tp __value, int __precision, - char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case( + const __float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result; __result.__integral = __integral; __result.__last = @@ -342,7 +338,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const __result.__exponent = __formatter::__find_exponent(__first + 1, __result.__last); } else { __result.__radix_point = __result.__last; - __result.__exponent = __first; + __result.__exponent = __first; } // clang-format off @@ -355,9 +351,8 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case(const __float_buffer<_Fp>& __buffer, - _Tp __value, int __precision, - char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case( + const __float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result = __formatter::__format_buffer_scientific_lower_case(__buffer, __value, __precision, __integral); *__result.__exponent = 'E'; @@ -365,8 +360,8 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case(const } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer<_Fp>& __buffer, _Tp __value, - int __precision, char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result +__format_buffer_fixed(const __float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result; __result.__integral = __integral; __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::fixed, __precision); @@ -376,7 +371,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer< // By converting __precision to a bool the subtraction can be done // unconditionally. __result.__radix_point = __result.__last - (__precision + bool(__precision)); - __result.__exponent = __result.__last; + __result.__exponent = __result.__last; // clang-format off _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) && @@ -388,9 +383,8 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer< } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_buffer<_Fp>& __buffer, _Tp __value, - int __precision, char* __integral) { - +_LIBCPP_HIDE_FROM_ABI __float_result +__format_buffer_general_lower_case(__float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __buffer.__remove_trailing_zeros(); __float_result __result; @@ -400,7 +394,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_ char* __first = __integral + 1; if (__first == __result.__last) { __result.__radix_point = __result.__last; - __result.__exponent = __result.__last; + __result.__exponent = __result.__last; } else { __result.__exponent = __formatter::__find_exponent(__first, __result.__last); if (__result.__exponent != __result.__last) @@ -426,8 +420,8 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_ } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_upper_case(__float_buffer<_Fp>& __buffer, _Tp __value, - int __precision, char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result +__format_buffer_general_upper_case(__float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result = __formatter::__format_buffer_general_lower_case(__buffer, __value, __precision, __integral); if (__result.__exponent != __result.__last) *__result.__exponent = 'E'; @@ -504,9 +498,9 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( const __float_result& __result, std::locale __loc, __format_spec::__parsed_specifications<_CharT> __specs) { - const auto& __np = std::use_facet>(__loc); + const auto& __np = std::use_facet>(__loc); string __grouping = __np.grouping(); - char* __first = __result.__integral; + char* __first = __result.__integral; // When no radix point or exponent are present __last will be __result.__last. char* __last = std::min(__result.__radix_point, __result.__exponent); @@ -524,11 +518,11 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( __grouping.size() - // Grouping contains one !__grouping.empty(); // additional character - __formatter::__padding_size_result __padding = {0, 0}; - bool __zero_padding = __specs.__alignment_ == __format_spec::__alignment::__zero_padding; + __formatter::__padding_size_result __padding = {0, 0}; + bool __zero_padding = __specs.__alignment_ == __format_spec::__alignment::__zero_padding; if (__size < __specs.__width_) { if (__zero_padding) { - __specs.__alignment_ = __format_spec::__alignment::__right; + __specs.__alignment_ = __format_spec::__alignment::__right; __specs.__fill_.__data[0] = _CharT('0'); } @@ -546,8 +540,8 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( if (__grouping.empty()) { __out_it = __formatter::__copy(__first, __digits, std::move(__out_it)); } else { - auto __r = __grouping.rbegin(); - auto __e = __grouping.rend() - 1; + auto __r = __grouping.rbegin(); + auto __e = __grouping.rend() - 1; _CharT __sep = __np.thousands_sep(); // The output is divided in small groups of numbers to write: // - A group before the first separator. @@ -627,8 +621,8 @@ _LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros( const _CharT* __exponent, size_t __num_trailing_zeros) -> decltype(__out_it) { _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range"); - _LIBCPP_ASSERT_UNCATEGORIZED(__num_trailing_zeros > 0, - "The overload not writing trailing zeros should have been used"); + _LIBCPP_ASSERT_UNCATEGORIZED( + __num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used"); __padding_size_result __padding = __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_); @@ -639,7 +633,6 @@ _LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros( return __formatter::__fill(std::move(__out_it), __padding.__after_, __specs.__fill_); } - template _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_floating_point(_Tp __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) { @@ -743,7 +736,7 @@ __format_floating_point(_Tp __value, _FormatContext& __ctx, __format_spec::__par *__out_it++ = *__first++; // After the sign is written, zero padding is the same a right alignment // with '0'. - __specs.__alignment_ = __format_spec::__alignment::__right; + __specs.__alignment_ = __format_spec::__alignment::__right; __specs.__fill_.__data[0] = _CharT('0'); } @@ -775,14 +768,11 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_floating_point<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_floating_point<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_floating_point<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_floating_point<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_floating_point<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_floating_point<_CharT> {}; #endif //_LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__format/formatter_integer.h b/libcxx/include/__format/formatter_integer.h index 5590bff5aa98becbcca80d7165a1cad1cac11c6d..d57082b3881baa282a04faddc18ce1bede6f5736 100644 --- a/libcxx/include/__format/formatter_integer.h +++ b/libcxx/include/__format/formatter_integer.h @@ -26,13 +26,12 @@ # pragma GCC system_header #endif - _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 - template <__fmt_char_type _CharT> - struct _LIBCPP_TEMPLATE_VIS __formatter_integer { - +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS __formatter_integer { public: template _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { @@ -60,44 +59,34 @@ public: // Signed integral types. template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> { -}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; # ifndef _LIBCPP_HAS_NO_INT128 template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter<__int128_t, _CharT> - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter<__int128_t, _CharT> : public __formatter_integer<_CharT> {}; # endif // Unsigned integral types. template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; # ifndef _LIBCPP_HAS_NO_INT128 template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT> - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT> : public __formatter_integer<_CharT> {}; # endif #endif //_LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__format/formatter_integral.h b/libcxx/include/__format/formatter_integral.h index 598decb0a95eadc03ebe5dcee5900224b13149cf..ca66e26ede107434121ec765c2b8014b03ac688d 100644 --- a/libcxx/include/__format/formatter_integral.h +++ b/libcxx/include/__format/formatter_integral.h @@ -20,6 +20,9 @@ #include <__format/format_error.h> #include <__format/formatter_output.h> #include <__format/parser_std_format_spec.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> #include <__system_error/errc.h> #include <__type_traits/make_unsigned.h> #include <__utility/unreachable.h> @@ -49,7 +52,9 @@ namespace __formatter { // Generic // -_LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, __format_spec::__sign __sign) { +template + requires same_as> +_LIBCPP_HIDE_FROM_ABI inline _Iterator __insert_sign(_Iterator __buf, bool __negative, __format_spec::__sign __sign) { if (__negative) *__buf++ = '-'; else @@ -85,9 +90,10 @@ _LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, _ * regardless whether the @c std::numpunct's type is @c char or @c wchar_t. */ _LIBCPP_HIDE_FROM_ABI inline string __determine_grouping(ptrdiff_t __size, const string& __grouping) { - _LIBCPP_ASSERT_UNCATEGORIZED(!__grouping.empty() && __size > __grouping[0], - "The slow grouping formatting is used while there will be no " - "separators written"); + _LIBCPP_ASSERT_UNCATEGORIZED( + !__grouping.empty() && __size > __grouping[0], + "The slow grouping formatting is used while there will be no " + "separators written"); string __r; auto __end = __grouping.end() - 1; auto __ptr = __grouping.begin(); @@ -119,10 +125,10 @@ _LIBCPP_HIDE_FROM_ABI inline string __determine_grouping(ptrdiff_t __size, const // template <__fmt_char_type _CharT> -_LIBCPP_HIDE_FROM_ABI auto __format_char( - integral auto __value, - output_iterator auto __out_it, - __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { +_LIBCPP_HIDE_FROM_ABI auto +__format_char(integral auto __value, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { using _Tp = decltype(__value); if constexpr (!same_as<_CharT, _Tp>) { // cmp_less and cmp_greater can't be used for character types. @@ -148,14 +154,16 @@ _LIBCPP_HIDE_FROM_ABI auto __format_char( // Integer // -/** Wrapper around @ref to_chars, returning the output pointer. */ -template -_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, int __base) { +/** Wrapper around @ref to_chars, returning the output iterator. */ +template + requires same_as> +_LIBCPP_HIDE_FROM_ABI _Iterator __to_buffer(_Iterator __first, _Iterator __last, _Tp __value, int __base) { // TODO FMT Evaluate code overhead due to not calling the internal function // directly. (Should be zero overhead.) - to_chars_result __r = std::to_chars(__first, __last, __value, __base); + to_chars_result __r = std::to_chars(std::to_address(__first), std::to_address(__last), __value, __base); _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small"); - return __r.ptr; + auto __diff = __r.ptr - std::to_address(__first); + return __first + __diff; } /** @@ -203,10 +211,16 @@ consteval size_t __buffer_size() noexcept + 1; // Reserve space for the sign. } -template -_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first, - const char* __last, string&& __grouping, _CharT __sep, - __format_spec::__parsed_specifications<_CharT> __specs) { +template + requires same_as> +_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators( + _OutIt __out_it, + _Iterator __begin, + _Iterator __first, + _Iterator __last, + string&& __grouping, + _CharT __sep, + __format_spec::__parsed_specifications<_CharT> __specs) { int __size = (__first - __begin) + // [sign][prefix] (__last - __first) + // data (__grouping.size() - 1); // number of separator characters @@ -234,8 +248,10 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, c auto __r = __grouping.rbegin(); auto __e = __grouping.rend() - 1; - _LIBCPP_ASSERT_UNCATEGORIZED(__r != __e, "The slow grouping formatting is used while " - "there will be no separators written."); + _LIBCPP_ASSERT_UNCATEGORIZED( + __r != __e, + "The slow grouping formatting is used while " + "there will be no separators written."); // The output is divided in small groups of numbers to write: // - A group before the first separator. // - A separator and a group, repeated for the number of separators. @@ -249,9 +265,9 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, c // hoisting the invariant is worth the effort. while (true) { if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) { - __last = __first + *__r; + __last = __first + *__r; __out_it = __formatter::__transform(__first, __last, std::move(__out_it), __hex_to_upper); - __first = __last; + __first = __last; } else { __out_it = __formatter::__copy(__first, *__r, std::move(__out_it)); __first += *__r; @@ -267,24 +283,23 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, c return __formatter::__fill(std::move(__out_it), __padding.__after_, __specs.__fill_); } - - -template +template + requires same_as> _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_integer( _Tp __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative, - char* __begin, - char* __end, + _Iterator __begin, + _Iterator __end, const char* __prefix, int __base) { - char* __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_); + _Iterator __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_); if (__specs.__std_.__alternate_form_ && __prefix) while (*__prefix) *__first++ = *__prefix++; - char* __last = __formatter::__to_buffer(__first, __end, __value, __base); + _Iterator __last = __formatter::__to_buffer(__first, __end, __value, __base); # ifndef _LIBCPP_HAS_NO_LOCALIZATION if (__specs.__std_.__locale_specific_form_) { @@ -315,10 +330,10 @@ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_integer( // The zero padding is done like: // - Write [sign][prefix] // - Write data right aligned with '0' as fill character. - __out_it = __formatter::__copy(__begin, __first, std::move(__out_it)); - __specs.__alignment_ = __format_spec::__alignment::__right; + __out_it = __formatter::__copy(__begin, __first, std::move(__out_it)); + __specs.__alignment_ = __format_spec::__alignment::__right; __specs.__fill_.__data[0] = _CharT('0'); - int32_t __size = __first - __begin; + int32_t __size = __first - __begin; __specs.__width_ -= std::min(__size, __specs.__width_); } diff --git a/libcxx/include/__format/formatter_output.h b/libcxx/include/__format/formatter_output.h index 2909fcd9baf1ebe7cbbcccd131bd359c8c5425b9..89854f67f5fc19f8f14d4d16111d7cd07795ac38 100644 --- a/libcxx/include/__format/formatter_output.h +++ b/libcxx/include/__format/formatter_output.h @@ -23,8 +23,9 @@ #include <__format/unicode.h> #include <__iterator/back_insert_iterator.h> #include <__iterator/concepts.h> -#include <__iterator/iterator_traits.h> // iter_value_t +#include <__iterator/iterator_traits.h> #include <__memory/addressof.h> +#include <__memory/pointer_traits.h> #include <__utility/move.h> #include <__utility/unreachable.h> #include @@ -101,8 +102,7 @@ _LIBCPP_HIDE_FROM_ABI auto __copy(basic_string_view<_CharT> __str, output_iterat if constexpr (std::same_as>>) { __out_it.__get_container()->__copy(__str); return __out_it; - } else if constexpr (std::same_as::__iterator>) { + } else if constexpr (std::same_as::__iterator>) { __out_it.__buffer_->__copy(__str); return __out_it; } else { @@ -110,33 +110,36 @@ _LIBCPP_HIDE_FROM_ABI auto __copy(basic_string_view<_CharT> __str, output_iterat } } -template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> -_LIBCPP_HIDE_FROM_ABI auto -__copy(const _CharT* __first, const _CharT* __last, output_iterator auto __out_it) +template ::value_type, + __fmt_char_type _OutCharT = _CharT> +_LIBCPP_HIDE_FROM_ABI auto __copy(_Iterator __first, _Iterator __last, output_iterator auto __out_it) -> decltype(__out_it) { return __formatter::__copy(basic_string_view{__first, __last}, std::move(__out_it)); } -template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> -_LIBCPP_HIDE_FROM_ABI auto __copy(const _CharT* __first, size_t __n, output_iterator auto __out_it) +template ::value_type, + __fmt_char_type _OutCharT = _CharT> +_LIBCPP_HIDE_FROM_ABI auto __copy(_Iterator __first, size_t __n, output_iterator auto __out_it) -> decltype(__out_it) { - return __formatter::__copy(basic_string_view{__first, __n}, std::move(__out_it)); + return __formatter::__copy(basic_string_view{std::to_address(__first), __n}, std::move(__out_it)); } /// Transform wrapper. /// /// This uses a "mass output function" of __format::__output_buffer when possible. -template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT, class _UnaryOperation> -_LIBCPP_HIDE_FROM_ABI auto -__transform(const _CharT* __first, - const _CharT* __last, - output_iterator auto __out_it, - _UnaryOperation __operation) -> decltype(__out_it) { +template ::value_type, + __fmt_char_type _OutCharT = _CharT, + class _UnaryOperation> +_LIBCPP_HIDE_FROM_ABI auto __transform( + _Iterator __first, _Iterator __last, output_iterator auto __out_it, _UnaryOperation __operation) + -> decltype(__out_it) { if constexpr (std::same_as>>) { __out_it.__get_container()->__transform(__first, __last, std::move(__operation)); return __out_it; - } else if constexpr (std::same_as::__iterator>) { + } else if constexpr (std::same_as::__iterator>) { __out_it.__buffer_->__transform(__first, __last, std::move(__operation)); return __out_it; } else { @@ -260,11 +263,16 @@ __write(_Iterator __first, return __formatter::__write(__first, __last, std::move(__out_it), __specs, __last - __first); } -template -_LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _CharT* __last, - output_iterator auto __out_it, - __format_spec::__parsed_specifications<_ParserCharT> __specs, - _UnaryOperation __op) -> decltype(__out_it) { +template ::value_type, + class _ParserCharT, + class _UnaryOperation> +_LIBCPP_HIDE_FROM_ABI auto __write_transformed( + _Iterator __first, + _Iterator __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + _UnaryOperation __op) -> decltype(__out_it) { _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range"); ptrdiff_t __size = __last - __first; diff --git a/libcxx/include/__format/formatter_pointer.h b/libcxx/include/__format/formatter_pointer.h index a2212611df488e3df15e046621869926a875cea2..3373996ec3d5fa234c073f47c1bd9c414383169a 100644 --- a/libcxx/include/__format/formatter_pointer.h +++ b/libcxx/include/__format/formatter_pointer.h @@ -60,14 +60,11 @@ public: // - template<> struct formatter; // - template<> struct formatter; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_pointer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_pointer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_pointer<_CharT> { -}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_pointer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_pointer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_pointer<_CharT> {}; #endif //_LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__format/formatter_string.h b/libcxx/include/__format/formatter_string.h index ba64a64af80a7cb37749fa318a28cb5ec0702d04..4ba5617a49c8d5968b3406efa99031bdff807fb8 100644 --- a/libcxx/include/__format/formatter_string.h +++ b/libcxx/include/__format/formatter_string.h @@ -59,14 +59,15 @@ public: // Formatter const char*. template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_string<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_string<_CharT> { using _Base = __formatter_string<_CharT>; template _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _CharT* __str, _FormatContext& __ctx) const { - _LIBCPP_ASSERT_UNCATEGORIZED(__str, "The basic_format_arg constructor should have " - "prevented an invalid pointer."); + _LIBCPP_ASSERT_UNCATEGORIZED( + __str, + "The basic_format_arg constructor should have " + "prevented an invalid pointer."); __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx); # if _LIBCPP_STD_VER >= 23 @@ -98,8 +99,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter // Formatter char*. template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> - : public formatter { +struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> : public formatter { using _Base = formatter; template @@ -110,8 +110,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> // Formatter char[]. template <__fmt_char_type _CharT, size_t _Size> -struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT> - : public __formatter_string<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT> : public __formatter_string<_CharT> { using _Base = __formatter_string<_CharT>; template @@ -137,8 +136,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter, // Formatter std::string_view. template <__fmt_char_type _CharT, class _Traits> -struct _LIBCPP_TEMPLATE_VIS formatter, _CharT> - : public __formatter_string<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter, _CharT> : public __formatter_string<_CharT> { using _Base = __formatter_string<_CharT>; template diff --git a/libcxx/include/__format/parser_std_format_spec.h b/libcxx/include/__format/parser_std_format_spec.h index ea5dfdf30511c3fc117e5fbc4a0653a0af2fd8c5..9a91179fdfb52db4206195d48028684647ba9b2a 100644 --- a/libcxx/include/__format/parser_std_format_spec.h +++ b/libcxx/include/__format/parser_std_format_spec.h @@ -82,8 +82,7 @@ __parse_arg_id(_Iterator __begin, _Iterator __end, _ParseContext& __ctx) { } template -_LIBCPP_HIDE_FROM_ABI constexpr uint32_t -__substitute_arg_id(basic_format_arg<_Context> __format_arg) { +_LIBCPP_HIDE_FROM_ABI constexpr uint32_t __substitute_arg_id(basic_format_arg<_Context> __format_arg) { // [format.string.std]/8 // If the corresponding formatting argument is not of integral type... // This wording allows char and bool too. LWG-3720 changes the wording to @@ -240,22 +239,22 @@ inline constexpr uint32_t __type_mask_integer = __create_type_mask(__type::__hexadecimal_upper_case); struct __std { - __alignment __alignment_ : 3; - __sign __sign_ : 2; - bool __alternate_form_ : 1; + __alignment __alignment_ : 3; + __sign __sign_ : 2; + bool __alternate_form_ : 1; bool __locale_specific_form_ : 1; __type __type_; }; struct __chrono { - __alignment __alignment_ : 3; + __alignment __alignment_ : 3; bool __locale_specific_form_ : 1; bool __hour_ : 1; - bool __weekday_name_ : 1; + bool __weekday_name_ : 1; bool __weekday_ : 1; bool __day_of_year_ : 1; bool __week_of_year_ : 1; - bool __month_name_ : 1; + bool __month_name_ : 1; }; // The fill UCS scalar value. @@ -495,8 +494,7 @@ public: } /// \returns the `__parsed_specifications` with the resolved dynamic sizes.. - _LIBCPP_HIDE_FROM_ABI - __parsed_specifications<_CharT> __get_parsed_std_specifications(auto& __ctx) const { + _LIBCPP_HIDE_FROM_ABI __parsed_specifications<_CharT> __get_parsed_std_specifications(auto& __ctx) const { return __parsed_specifications<_CharT>{ .__std_ = __std{.__alignment_ = __alignment_, .__sign_ = __sign_, @@ -524,9 +522,9 @@ public: .__fill_{__fill_}}; } - __alignment __alignment_ : 3 {__alignment::__default}; - __sign __sign_ : 2 {__sign::__default}; - bool __alternate_form_ : 1 {false}; + __alignment __alignment_ : 3 {__alignment::__default}; + __sign __sign_ : 2 {__sign::__default}; + bool __alternate_form_ : 1 {false}; bool __locale_specific_form_ : 1 {false}; bool __clear_brackets_ : 1 {false}; __type __type_{__type::__default}; @@ -547,7 +545,7 @@ public: uint8_t __reserved_1_ : 6 {0}; // These two flags are only used internally and not part of the // __parsed_specifications. Therefore put them at the end. - bool __width_as_arg_ : 1 {false}; + bool __width_as_arg_ : 1 {false}; bool __precision_as_arg_ : 1 {false}; /// The requested width, either the value or the arg-id. @@ -593,9 +591,10 @@ private: || (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2) # endif _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) { - _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end, - "when called with an empty input the function will cause " - "undefined behavior by evaluating data not in the input"); + _LIBCPP_ASSERT_UNCATEGORIZED( + __begin != __end, + "when called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); __unicode::__code_point_view<_CharT> __view{__begin, __end}; __unicode::__consume_result __consumed = __view.__consume(); if (__consumed.__status != __unicode::__consume_result::__ok) @@ -625,9 +624,10 @@ private: template requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4) _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) { - _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end, - "when called with an empty input the function will cause " - "undefined behavior by evaluating data not in the input"); + _LIBCPP_ASSERT_UNCATEGORIZED( + __begin != __end, + "when called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); if (__begin + 1 != __end && __parse_alignment(*(__begin + 1))) { if (!__unicode::__is_scalar_value(*__begin)) std::__throw_format_error("The fill option contains an invalid value"); @@ -652,9 +652,10 @@ private: // range-fill and tuple-fill are identical template _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) { - _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end, - "when called with an empty input the function will cause " - "undefined behavior by evaluating data not in the input"); + _LIBCPP_ASSERT_UNCATEGORIZED( + __begin != __end, + "when called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); if (__begin + 1 != __end) { if (__parse_alignment(*(__begin + 1))) { __validate_fill_character(*__begin, __use_range_fill); @@ -721,9 +722,9 @@ private: if (*__begin == _CharT('{')) { __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __ctx); - __width_as_arg_ = true; - __width_ = __r.__value; - __begin = __r.__last; + __width_as_arg_ = true; + __width_ = __r.__value; + __begin = __r.__last; return true; } @@ -731,9 +732,11 @@ private: return false; __format::__parse_number_result __r = __format::__parse_number(__begin, __end); - __width_ = __r.__value; - _LIBCPP_ASSERT_UNCATEGORIZED(__width_ != 0, "A zero value isn't allowed and should be impossible, " - "due to validations in this function"); + __width_ = __r.__value; + _LIBCPP_ASSERT_UNCATEGORIZED( + __width_ != 0, + "A zero value isn't allowed and should be impossible, " + "due to validations in this function"); __begin = __r.__last; return true; } @@ -749,9 +752,9 @@ private: if (*__begin == _CharT('{')) { __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __ctx); - __precision_as_arg_ = true; - __precision_ = __arg_id.__value; - __begin = __arg_id.__last; + __precision_as_arg_ = true; + __precision_ = __arg_id.__value; + __begin = __arg_id.__last; return true; } @@ -759,9 +762,9 @@ private: std::__throw_format_error("The precision option does not contain a value or an argument index"); __format::__parse_number_result __r = __format::__parse_number(__begin, __end); - __precision_ = __r.__value; - __precision_as_arg_ = false; - __begin = __r.__last; + __precision_ = __r.__value; + __precision_as_arg_ = false; + __begin = __r.__last; return true; } @@ -858,16 +861,14 @@ private: ++__begin; } - _LIBCPP_HIDE_FROM_ABI - int32_t __get_width(auto& __ctx) const { + _LIBCPP_HIDE_FROM_ABI int32_t __get_width(auto& __ctx) const { if (!__width_as_arg_) return __width_; return __format_spec::__substitute_arg_id(__ctx.arg(__width_)); } - _LIBCPP_HIDE_FROM_ABI - int32_t __get_precision(auto& __ctx) const { + _LIBCPP_HIDE_FROM_ABI int32_t __get_precision(auto& __ctx) const { if (!__precision_as_arg_) return __precision_; diff --git a/libcxx/include/__format/unicode.h b/libcxx/include/__format/unicode.h index 8666f80c78a288f723db195464fbdcab66d7e930..8e1e7bb192a001d6da88fa74ee1d6615f4c0c6a4 100644 --- a/libcxx/include/__format/unicode.h +++ b/libcxx/include/__format/unicode.h @@ -319,9 +319,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __at_extended_grapheme_cluster_break( return true; // *** Do not break Hangul syllable sequences. *** - if (__prev == __property::__L && - (__next == __property::__L || __next == __property::__V || __next == __property::__LV || - __next == __property::__LVT)) // GB6 + if (__prev == __property::__L && (__next == __property::__L || __next == __property::__V || + __next == __property::__LV || __next == __property::__LVT)) // GB6 return false; if ((__prev == __property::__LV || __prev == __property::__V) && @@ -402,9 +401,8 @@ public: }; _LIBCPP_HIDE_FROM_ABI constexpr __cluster __consume() { - _LIBCPP_ASSERT_UNCATEGORIZED( - __next_prop_ != __extended_grapheme_custer_property_boundary::__property::__eot, - "can't move beyond the end of input"); + _LIBCPP_ASSERT_UNCATEGORIZED(__next_prop_ != __extended_grapheme_custer_property_boundary::__property::__eot, + "can't move beyond the end of input"); char32_t __code_point = __next_code_point_; if (!__code_point_view_.__at_end()) diff --git a/libcxx/include/__format/write_escaped.h b/libcxx/include/__format/write_escaped.h index 51bae3cb238fb49f92baf8b8d7ad66f5bb285d0e..15141eebc02928a1656e2b47105cbf3a5aca08bb 100644 --- a/libcxx/include/__format/write_escaped.h +++ b/libcxx/include/__format/write_escaped.h @@ -32,7 +32,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD - namespace __formatter { #if _LIBCPP_STD_VER >= 20 @@ -42,10 +41,10 @@ namespace __formatter { /// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the /// input is ASCII. template -_LIBCPP_HIDE_FROM_ABI auto __write_string( - basic_string_view<_CharT> __str, - output_iterator auto __out_it, - __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { +_LIBCPP_HIDE_FROM_ABI auto +__write_string(basic_string_view<_CharT> __str, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { if (!__specs.__has_precision()) return __formatter::__write_string_no_precision(__str, std::move(__out_it), __specs); @@ -54,8 +53,8 @@ _LIBCPP_HIDE_FROM_ABI auto __write_string( return __formatter::__write(__str.begin(), __str.end(), std::move(__out_it), __specs, __size); } -# endif // _LIBCPP_STD_VER >= 20 -# if _LIBCPP_STD_VER >= 23 +#endif // _LIBCPP_STD_VER >= 20 +#if _LIBCPP_STD_VER >= 23 struct __nul_terminator {}; @@ -100,11 +99,11 @@ _LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_Cha template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value) { -# ifdef _LIBCPP_HAS_NO_UNICODE +# ifdef _LIBCPP_HAS_NO_UNICODE // For ASCII assume everything above 127 is printable. if (__value > 127) return false; -# endif +# endif if (!__escaped_output_table::__needs_escape(__value)) return false; @@ -213,7 +212,7 @@ __format_escaped_string(basic_string_view<_CharT> __values, return __formatter::__write_string(basic_string_view{__str}, std::move(__out_it), __specs); } -# endif // _LIBCPP_STD_VER >= 23 +#endif // _LIBCPP_STD_VER >= 23 } // namespace __formatter diff --git a/libcxx/include/__functional/binary_function.h b/libcxx/include/__functional/binary_function.h index fdedb8b177daec696092346b48e0a8703df2743c..ddee3b170311f057ed9589f98bd764e6d30c8e3b 100644 --- a/libcxx/include/__functional/binary_function.h +++ b/libcxx/include/__functional/binary_function.h @@ -21,20 +21,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) template -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binary_function -{ - typedef _Arg1 first_argument_type; - typedef _Arg2 second_argument_type; - typedef _Result result_type; +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binary_function { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; }; #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) -template struct __binary_function_keep_layout_base { +template +struct __binary_function_keep_layout_base { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using first_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg1; + using first_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg1; using second_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg2; - using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; + using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; #endif }; diff --git a/libcxx/include/__functional/binary_negate.h b/libcxx/include/__functional/binary_negate.h index 3180284fc3822630a75636530083a32749212b9e..ce52b5ae9fc499d0a3f386826884a5761e0858ed 100644 --- a/libcxx/include/__functional/binary_negate.h +++ b/libcxx/include/__functional/binary_negate.h @@ -25,23 +25,24 @@ template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate : public __binary_function -{ - _Predicate __pred_; + bool> { + _Predicate __pred_; + public: - _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR_SINCE_CXX14 - binary_negate(const _Predicate& __pred) : __pred_(__pred) {} + _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR_SINCE_CXX14 binary_negate(const _Predicate& __pred) + : __pred_(__pred) {} - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const typename _Predicate::first_argument_type& __x, - const typename _Predicate::second_argument_type& __y) const - {return !__pred_(__x, __y);} + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()( + const typename _Predicate::first_argument_type& __x, const typename _Predicate::second_argument_type& __y) const { + return !__pred_(__x, __y); + } }; template -_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI -binary_negate<_Predicate> -not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);} +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI binary_negate<_Predicate> +not2(const _Predicate& __pred) { + return binary_negate<_Predicate>(__pred); +} #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) diff --git a/libcxx/include/__functional/bind.h b/libcxx/include/__functional/bind.h index 61d99e1fd564fa27a0e9cf6b60c501858a93d7a3..19e7d82155ec97dd439d4cbbc739db5834c12420 100644 --- a/libcxx/include/__functional/bind.h +++ b/libcxx/include/__functional/bind.h @@ -25,34 +25,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -struct is_bind_expression : _If< - _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, - false_type, - is_bind_expression<__remove_cvref_t<_Tp> > -> {}; +template +struct is_bind_expression + : _If< _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, false_type, is_bind_expression<__remove_cvref_t<_Tp> > > {}; #if _LIBCPP_STD_VER >= 17 template inline constexpr bool is_bind_expression_v = is_bind_expression<_Tp>::value; #endif -template -struct is_placeholder : _If< - _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, - integral_constant, - is_placeholder<__remove_cvref_t<_Tp> > -> {}; +template +struct is_placeholder + : _If< _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, + integral_constant, + is_placeholder<__remove_cvref_t<_Tp> > > {}; #if _LIBCPP_STD_VER >= 17 template inline constexpr int is_placeholder_v = is_placeholder<_Tp>::value; #endif -namespace placeholders -{ +namespace placeholders { -template struct __ph {}; +template +struct __ph {}; // C++17 recommends that we implement placeholders as `inline constexpr`, but allows // implementing them as `extern `. Libc++ implements them as @@ -62,291 +58,234 @@ template struct __ph {}; // // In practice, since placeholders are empty, `extern const` is almost impossible // to distinguish from `inline constexpr` from a usage stand point. -_LIBCPP_EXPORTED_FROM_ABI extern const __ph<1> _1; -_LIBCPP_EXPORTED_FROM_ABI extern const __ph<2> _2; -_LIBCPP_EXPORTED_FROM_ABI extern const __ph<3> _3; -_LIBCPP_EXPORTED_FROM_ABI extern const __ph<4> _4; -_LIBCPP_EXPORTED_FROM_ABI extern const __ph<5> _5; -_LIBCPP_EXPORTED_FROM_ABI extern const __ph<6> _6; -_LIBCPP_EXPORTED_FROM_ABI extern const __ph<7> _7; -_LIBCPP_EXPORTED_FROM_ABI extern const __ph<8> _8; -_LIBCPP_EXPORTED_FROM_ABI extern const __ph<9> _9; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<1> _1; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<2> _2; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<3> _3; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<4> _4; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<5> _5; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<6> _6; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<7> _7; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<8> _8; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<9> _9; _LIBCPP_EXPORTED_FROM_ABI extern const __ph<10> _10; } // namespace placeholders -template -struct is_placeholder > - : public integral_constant {}; - +template +struct is_placeholder > : public integral_constant {}; #ifndef _LIBCPP_CXX03_LANG template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_Tp& -__mu(reference_wrapper<_Tp> __t, _Uj&) -{ - return __t.get(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __mu(reference_wrapper<_Tp> __t, _Uj&) { + return __t.get(); } -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename __invoke_of<_Ti&, _Uj...>::type -__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) -{ - return __ti(std::forward<_Uj>(std::get<_Indx>(__uj))...); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of<_Ti&, _Uj...>::type +__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) { + return __ti(std::forward<_Uj>(std::get<_Indx>(__uj))...); } -template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename __invoke_of<_Ti&, _Uj...>::type -__mu(_Ti& __ti, tuple<_Uj...>& __uj) -{ - typedef typename __make_tuple_indices::type __indices; - return std::__mu_expand(__ti, __uj, __indices()); +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of<_Ti&, _Uj...>::type +__mu(_Ti& __ti, tuple<_Uj...>& __uj) { + typedef typename __make_tuple_indices::type __indices; + return std::__mu_expand(__ti, __uj, __indices()); } template struct __mu_return2 {}; template -struct __mu_return2 -{ - typedef typename tuple_element::value - 1, _Uj>::type type; +struct __mu_return2 { + typedef typename tuple_element::value - 1, _Uj>::type type; }; template ::value, int> = 0> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type -__mu(_Ti&, _Uj& __uj) -{ - const size_t __indx = is_placeholder<_Ti>::value - 1; - return std::forward::type>(std::get<__indx>(__uj)); + typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type + __mu(_Ti&, _Uj& __uj) { + const size_t __indx = is_placeholder<_Ti>::value - 1; + return std::forward::type>(std::get<__indx>(__uj)); } -template ::value && - is_placeholder<_Ti>::value == 0 && - !__is_reference_wrapper<_Ti>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_Ti& -__mu(_Ti& __ti, _Uj&) -{ - return __ti; +template ::value && is_placeholder<_Ti>::value == 0 && + !__is_reference_wrapper<_Ti>::value, + int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Ti& __mu(_Ti& __ti, _Uj&) { + return __ti; } -template +template struct __mu_return_impl; -template -struct __mu_return_invokable // false +template +struct __mu_return_invokable // false { - typedef __nat type; + typedef __nat type; }; -template -struct __mu_return_invokable -{ - typedef typename __invoke_of<_Ti&, _Uj...>::type type; +template +struct __mu_return_invokable { + typedef typename __invoke_of<_Ti&, _Uj...>::type type; }; -template +template struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> > - : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> -{ -}; + : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> {}; template -struct __mu_return_impl<_Ti, false, false, true, _TupleUj> -{ - typedef typename tuple_element::value - 1, - _TupleUj>::type&& type; +struct __mu_return_impl<_Ti, false, false, true, _TupleUj> { + typedef typename tuple_element::value - 1, _TupleUj>::type&& type; }; template -struct __mu_return_impl<_Ti, true, false, false, _TupleUj> -{ - typedef typename _Ti::type& type; +struct __mu_return_impl<_Ti, true, false, false, _TupleUj> { + typedef typename _Ti::type& type; }; template -struct __mu_return_impl<_Ti, false, false, false, _TupleUj> -{ - typedef _Ti& type; +struct __mu_return_impl<_Ti, false, false, false, _TupleUj> { + typedef _Ti& type; }; template struct __mu_return - : public __mu_return_impl<_Ti, - __is_reference_wrapper<_Ti>::value, - is_bind_expression<_Ti>::value, - 0 < is_placeholder<_Ti>::value && - is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value, - _TupleUj> -{ -}; + : public __mu_return_impl< + _Ti, + __is_reference_wrapper<_Ti>::value, + is_bind_expression<_Ti>::value, + 0 < is_placeholder<_Ti>::value && is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value, + _TupleUj> {}; template -struct __is_valid_bind_return -{ - static const bool value = false; +struct __is_valid_bind_return { + static const bool value = false; }; -template -struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> -{ - static const bool value = __invokable<_Fp, - typename __mu_return<_BoundArgs, _TupleUj>::type...>::value; +template +struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> { + static const bool value = __invokable<_Fp, typename __mu_return<_BoundArgs, _TupleUj>::type...>::value; }; -template -struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> -{ - static const bool value = __invokable<_Fp, - typename __mu_return::type...>::value; +template +struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> { + static const bool value = __invokable<_Fp, typename __mu_return::type...>::value; }; -template ::value> +template ::value> struct __bind_return; -template -struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true> -{ - typedef typename __invoke_of - < - _Fp&, - typename __mu_return - < - _BoundArgs, - _TupleUj - >::type... - >::type type; +template +struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true> { + typedef typename __invoke_of< _Fp&, typename __mu_return< _BoundArgs, _TupleUj >::type... >::type type; }; -template -struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> -{ - typedef typename __invoke_of - < - _Fp&, - typename __mu_return - < - const _BoundArgs, - _TupleUj - >::type... - >::type type; +template +struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> { + typedef typename __invoke_of< _Fp&, typename __mu_return< const _BoundArgs, _TupleUj >::type... >::type type; }; -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename __bind_return<_Fp, _BoundArgs, _Args>::type -__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, - _Args&& __args) -{ - return std::__invoke(__f, std::__mu(std::get<_Indx>(__bound_args), __args)...); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bind_return<_Fp, _BoundArgs, _Args>::type +__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, _Args&& __args) { + return std::__invoke(__f, std::__mu(std::get<_Indx>(__bound_args), __args)...); } -template -class __bind : public __weak_result_type<__decay_t<_Fp> > -{ +template +class __bind : public __weak_result_type<__decay_t<_Fp> > { protected: - using _Fd = __decay_t<_Fp>; - typedef tuple<__decay_t<_BoundArgs>...> _Td; + using _Fd = __decay_t<_Fp>; + typedef tuple<__decay_t<_BoundArgs>...> _Td; + private: - _Fd __f_; - _Td __bound_args_; + _Fd __f_; + _Td __bound_args_; + + typedef typename __make_tuple_indices::type __indices; - typedef typename __make_tuple_indices::type __indices; public: - template ::value && !is_same<__libcpp_remove_reference_t<_Gp>, __bind>::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - explicit __bind(_Gp&& __f, _BA&& ...__bound_args) - : __f_(std::forward<_Gp>(__f)), - __bound_args_(std::forward<_BA>(__bound_args)...) {} - - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type - operator()(_Args&& ...__args) - { - return std::__apply_functor(__f_, __bound_args_, __indices(), - tuple<_Args&&...>(std::forward<_Args>(__args)...)); - } - - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename __bind_return >::type - operator()(_Args&& ...__args) const - { - return std::__apply_functor(__f_, __bound_args_, __indices(), - tuple<_Args&&...>(std::forward<_Args>(__args)...)); - } + template < + class _Gp, + class... _BA, + __enable_if_t::value && !is_same<__libcpp_remove_reference_t<_Gp>, __bind>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bind(_Gp&& __f, _BA&&... __bound_args) + : __f_(std::forward<_Gp>(__f)), __bound_args_(std::forward<_BA>(__bound_args)...) {} + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type + operator()(_Args&&... __args) { + return std::__apply_functor(__f_, __bound_args_, __indices(), tuple<_Args&&...>(std::forward<_Args>(__args)...)); + } + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + typename __bind_return >::type + operator()(_Args&&... __args) const { + return std::__apply_functor(__f_, __bound_args_, __indices(), tuple<_Args&&...>(std::forward<_Args>(__args)...)); + } }; -template +template struct is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; -template -class __bind_r - : public __bind<_Fp, _BoundArgs...> -{ - typedef __bind<_Fp, _BoundArgs...> base; - typedef typename base::_Fd _Fd; - typedef typename base::_Td _Td; +template +class __bind_r : public __bind<_Fp, _BoundArgs...> { + typedef __bind<_Fp, _BoundArgs...> base; + typedef typename base::_Fd _Fd; + typedef typename base::_Td _Td; + public: - typedef _Rp result_type; - - - template ::value && !is_same<__libcpp_remove_reference_t<_Gp>, __bind_r>::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args) - : base(std::forward<_Gp>(__f), - std::forward<_BA>(__bound_args)...) {} - - template >::type, - result_type>::value || is_void<_Rp>::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - result_type - operator()(_Args&& ...__args) - { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(static_cast(*this), std::forward<_Args>(__args)...); - } - - template >::type, - result_type>::value || is_void<_Rp>::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - result_type - operator()(_Args&& ...__args) const - { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(static_cast(*this), std::forward<_Args>(__args)...); - } + typedef _Rp result_type; + + template < + class _Gp, + class... _BA, + __enable_if_t::value && !is_same<__libcpp_remove_reference_t<_Gp>, __bind_r>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bind_r(_Gp&& __f, _BA&&... __bound_args) + : base(std::forward<_Gp>(__f), std::forward<_BA>(__bound_args)...) {} + + template < + class... _Args, + __enable_if_t >::type, result_type>::value || + is_void<_Rp>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 result_type operator()(_Args&&... __args) { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(static_cast(*this), std::forward<_Args>(__args)...); + } + + template >::type, + result_type>::value || + is_void<_Rp>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 result_type operator()(_Args&&... __args) const { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(static_cast(*this), std::forward<_Args>(__args)...); + } }; -template +template struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -__bind<_Fp, _BoundArgs...> -bind(_Fp&& __f, _BoundArgs&&... __bound_args) -{ - typedef __bind<_Fp, _BoundArgs...> type; - return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...> +bind(_Fp&& __f, _BoundArgs&&... __bound_args) { + typedef __bind<_Fp, _BoundArgs...> type; + return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...); } -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -__bind_r<_Rp, _Fp, _BoundArgs...> -bind(_Fp&& __f, _BoundArgs&&... __bound_args) -{ - typedef __bind_r<_Rp, _Fp, _BoundArgs...> type; - return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...> +bind(_Fp&& __f, _BoundArgs&&... __bound_args) { + typedef __bind_r<_Rp, _Fp, _BoundArgs...> type; + return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...); } #endif // _LIBCPP_CXX03_LANG diff --git a/libcxx/include/__functional/bind_back.h b/libcxx/include/__functional/bind_back.h index 5b5b40520933b5256884c9f116cdd80a8d65241e..ce26d3b70630f3c5721ab0d6200633a197c19f8a 100644 --- a/libcxx/include/__functional/bind_back.h +++ b/libcxx/include/__functional/bind_back.h @@ -29,28 +29,38 @@ _LIBCPP_BEGIN_NAMESPACE_STD template > struct __bind_back_op; -template +template struct __bind_back_op<_NBound, index_sequence<_Ip...>> { - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&& __f, _BoundArgs&& __bound_args, _Args&&... __args) const - noexcept(noexcept(std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)..., std::get<_Ip>(std::forward<_BoundArgs>(__bound_args))...))) - -> decltype( std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)..., std::get<_Ip>(std::forward<_BoundArgs>(__bound_args))...)) - { return std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)..., std::get<_Ip>(std::forward<_BoundArgs>(__bound_args))...); } + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&& __f, _BoundArgs&& __bound_args, _Args&&... __args) const + noexcept(noexcept(std::invoke(std::forward<_Fn>(__f), + std::forward<_Args>(__args)..., + std::get<_Ip>(std::forward<_BoundArgs>(__bound_args))...))) + -> decltype(std::invoke(std::forward<_Fn>(__f), + std::forward<_Args>(__args)..., + std::get<_Ip>(std::forward<_BoundArgs>(__bound_args))...)) { + return std::invoke(std::forward<_Fn>(__f), + std::forward<_Args>(__args)..., + std::get<_Ip>(std::forward<_BoundArgs>(__bound_args))...); + } }; template struct __bind_back_t : __perfect_forward<__bind_back_op>, _Fn, _BoundArgs> { - using __perfect_forward<__bind_back_op>, _Fn, _BoundArgs>::__perfect_forward; + using __perfect_forward<__bind_back_op>, _Fn, _BoundArgs>::__perfect_forward; }; template requires is_constructible_v, _Fn> && is_move_constructible_v> && (is_constructible_v, _Args> && ...) && (is_move_constructible_v> && ...) -_LIBCPP_HIDE_FROM_ABI -constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) - noexcept(noexcept(__bind_back_t, tuple...>>(std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...)))) - -> decltype( __bind_back_t, tuple...>>(std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...))) - { return __bind_back_t, tuple...>>(std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...)); } +_LIBCPP_HIDE_FROM_ABI constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) noexcept( + noexcept(__bind_back_t, tuple...>>( + std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...)))) + -> decltype(__bind_back_t, tuple...>>( + std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...))) { + return __bind_back_t, tuple...>>( + std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...)); +} #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__functional/bind_front.h b/libcxx/include/__functional/bind_front.h index d4762434387684002b549b5f04d1e4ec807a93dd..30dda533615b28006024bf7f403f353dcb4763b7 100644 --- a/libcxx/include/__functional/bind_front.h +++ b/libcxx/include/__functional/bind_front.h @@ -29,25 +29,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 struct __bind_front_op { - template - _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Args&& ...__args) const - noexcept(noexcept(std::invoke(std::forward<_Args>(__args)...))) - -> decltype( std::invoke(std::forward<_Args>(__args)...)) - { return std::invoke(std::forward<_Args>(__args)...); } + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const + noexcept(noexcept(std::invoke(std::forward<_Args>(__args)...))) + -> decltype(std::invoke(std::forward<_Args>(__args)...)) { + return std::invoke(std::forward<_Args>(__args)...); + } }; -template +template struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> { - using __perfect_forward<__bind_front_op, _Fn, _BoundArgs...>::__perfect_forward; + using __perfect_forward<__bind_front_op, _Fn, _BoundArgs...>::__perfect_forward; }; template requires is_constructible_v, _Fn> && is_move_constructible_v> && (is_constructible_v, _Args> && ...) && (is_move_constructible_v> && ...) -_LIBCPP_HIDE_FROM_ABI -constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { - return __bind_front_t, decay_t<_Args>...>(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); +_LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { + return __bind_front_t, decay_t<_Args>...>(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); } #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__functional/binder1st.h b/libcxx/include/__functional/binder1st.h index 9f0dc08ba6b1d1945dfdeb5e899b7df0fcaf13d5..04b51fefab70a9195927261c4c8c1ccbb394fdc9 100644 --- a/libcxx/include/__functional/binder1st.h +++ b/libcxx/include/__functional/binder1st.h @@ -23,28 +23,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st - : public __unary_function -{ + : public __unary_function { protected: - _Operation op; - typename _Operation::first_argument_type value; + _Operation op; + typename _Operation::first_argument_type value; + public: - _LIBCPP_HIDE_FROM_ABI binder1st(const _Operation& __x, - const typename _Operation::first_argument_type __y) - : op(__x), value(__y) {} - _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type operator() - (typename _Operation::second_argument_type& __x) const - {return op(value, __x);} - _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type operator() - (const typename _Operation::second_argument_type& __x) const - {return op(value, __x);} + _LIBCPP_HIDE_FROM_ABI binder1st(const _Operation& __x, const typename _Operation::first_argument_type __y) + : op(__x), value(__y) {} + _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type + operator()(typename _Operation::second_argument_type& __x) const { + return op(value, __x); + } + _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const { + return op(value, __x); + } }; template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -binder1st<_Operation> -bind1st(const _Operation& __op, const _Tp& __x) - {return binder1st<_Operation>(__op, __x);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI binder1st<_Operation> +bind1st(const _Operation& __op, const _Tp& __x) { + return binder1st<_Operation>(__op, __x); +} #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) diff --git a/libcxx/include/__functional/binder2nd.h b/libcxx/include/__functional/binder2nd.h index cf80a55bc6a3d1766d249b970b899debf1c0ffad..9d22e4430b1b3405010b49d5b88bd7c7aaf3c3e9 100644 --- a/libcxx/include/__functional/binder2nd.h +++ b/libcxx/include/__functional/binder2nd.h @@ -23,28 +23,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd - : public __unary_function -{ + : public __unary_function { protected: - _Operation op; - typename _Operation::second_argument_type value; + _Operation op; + typename _Operation::second_argument_type value; + public: - _LIBCPP_HIDE_FROM_ABI - binder2nd(const _Operation& __x, const typename _Operation::second_argument_type __y) - : op(__x), value(__y) {} - _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type operator() - ( typename _Operation::first_argument_type& __x) const - {return op(__x, value);} - _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type operator() - (const typename _Operation::first_argument_type& __x) const - {return op(__x, value);} + _LIBCPP_HIDE_FROM_ABI binder2nd(const _Operation& __x, const typename _Operation::second_argument_type __y) + : op(__x), value(__y) {} + _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type + operator()(typename _Operation::first_argument_type& __x) const { + return op(__x, value); + } + _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const { + return op(__x, value); + } }; template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -binder2nd<_Operation> -bind2nd(const _Operation& __op, const _Tp& __x) - {return binder2nd<_Operation>(__op, __x);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI binder2nd<_Operation> +bind2nd(const _Operation& __op, const _Tp& __x) { + return binder2nd<_Operation>(__op, __x); +} #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) diff --git a/libcxx/include/__functional/boyer_moore_searcher.h b/libcxx/include/__functional/boyer_moore_searcher.h index 0165e062810fe2446b3d727d8d7ff4d7ddf97dbc..648b60c50521910e8edf4d5b5d7f19f5f21f4c88 100644 --- a/libcxx/include/__functional/boyer_moore_searcher.h +++ b/libcxx/include/__functional/boyer_moore_searcher.h @@ -29,39 +29,29 @@ #if _LIBCPP_STD_VER >= 17 _LIBCPP_PUSH_MACROS -#include <__undef_macros> +# include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD -template +template class _BMSkipTable; // General case for BM data searching; use a map -template +template class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> { private: using value_type = _Value; - using key_type = _Key; + using key_type = _Key; const value_type __default_value_; unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_; public: - _LIBCPP_HIDE_FROM_ABI - explicit _BMSkipTable(size_t __sz, value_type __default_value, _Hash __hash, _BinaryPredicate __pred) - : __default_value_(__default_value), - __table_(__sz, __hash, __pred) {} + _LIBCPP_HIDE_FROM_ABI explicit _BMSkipTable( + size_t __sz, value_type __default_value, _Hash __hash, _BinaryPredicate __pred) + : __default_value_(__default_value), __table_(__sz, __hash, __pred) {} - _LIBCPP_HIDE_FROM_ABI void insert(const key_type& __key, value_type __val) { - __table_[__key] = __val; - } + _LIBCPP_HIDE_FROM_ABI void insert(const key_type& __key, value_type __val) { __table_[__key] = __val; } _LIBCPP_HIDE_FROM_ABI value_type operator[](const key_type& __key) const { auto __it = __table_.find(__key); @@ -70,14 +60,11 @@ public: }; // Special case small numeric values; use an array -template +template class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> { private: using value_type = _Value; - using key_type = _Key; + using key_type = _Key; using unsigned_key_type = make_unsigned_t; std::array __table_; @@ -98,34 +85,33 @@ public: }; template ::value_type>, + class _Hash = hash::value_type>, class _BinaryPredicate = equal_to<>> class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher { private: using difference_type = typename std::iterator_traits<_RandomAccessIterator1>::difference_type; - using value_type = typename std::iterator_traits<_RandomAccessIterator1>::value_type; - using __skip_table_type = _BMSkipTable - && sizeof(value_type) == 1 - && is_same_v<_Hash, hash> - && is_same_v<_BinaryPredicate, equal_to<>>>; + using value_type = typename std::iterator_traits<_RandomAccessIterator1>::value_type; + using __skip_table_type = + _BMSkipTable && sizeof(value_type) == 1 && is_same_v<_Hash, hash> && + is_same_v<_BinaryPredicate, equal_to<>>>; public: - _LIBCPP_HIDE_FROM_ABI - boyer_moore_searcher(_RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, - _Hash __hash = _Hash(), - _BinaryPredicate __pred = _BinaryPredicate()) - : __first_(__first), - __last_(__last), - __pred_(__pred), - __pattern_length_(__last - __first), - __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, -1, __hash, __pred_)), - __suffix_(std::__allocate_shared_unbounded_array( - allocator(), __pattern_length_ + 1)) { + _LIBCPP_HIDE_FROM_ABI boyer_moore_searcher( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _Hash __hash = _Hash(), + _BinaryPredicate __pred = _BinaryPredicate()) + : __first_(__first), + __last_(__last), + __pred_(__pred), + __pattern_length_(__last - __first), + __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, -1, __hash, __pred_)), + __suffix_(std::__allocate_shared_unbounded_array( + allocator(), __pattern_length_ + 1)) { difference_type __i = 0; while (__first != __last) { __skip_table_->insert(*__first, __i); @@ -162,8 +148,8 @@ private: template _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2> __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { - _RandomAccessIterator2 __current = __f; - const _RandomAccessIterator2 __last = __l - __pattern_length_; + _RandomAccessIterator2 __current = __f; + const _RandomAccessIterator2 __last = __l - __pattern_length_; const __skip_table_type& __skip_table = *__skip_table_; while (__current <= __last) { @@ -190,7 +176,7 @@ private: const size_t __count = __last - __first; __prefix[0] = 0; - size_t __k = 0; + size_t __k = 0; for (size_t __i = 1; __i != __count; ++__i) { while (__k > 0 && !__pred(__first[__k], __first[__i])) @@ -219,7 +205,7 @@ private: __compute_bm_prefix(_ReverseIter(__last), _ReverseIter(__first), __pred, __scratch); for (size_t __i = 0; __i != __count; ++__i) { - const size_t __j = __count - __scratch[__i]; + const size_t __j = __count - __scratch[__i]; const difference_type __k = __i - __scratch[__i] + 1; if (__suffix_[__j] > __k) @@ -230,31 +216,31 @@ private: _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(boyer_moore_searcher); template ::value_type>, + class _Hash = hash::value_type>, class _BinaryPredicate = equal_to<>> class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher { private: using difference_type = typename iterator_traits<_RandomAccessIterator1>::difference_type; - using value_type = typename iterator_traits<_RandomAccessIterator1>::value_type; - using __skip_table_type = _BMSkipTable - && sizeof(value_type) == 1 - && is_same_v<_Hash, hash> - && is_same_v<_BinaryPredicate, equal_to<>>>; + using value_type = typename iterator_traits<_RandomAccessIterator1>::value_type; + using __skip_table_type = + _BMSkipTable && sizeof(value_type) == 1 && is_same_v<_Hash, hash> && + is_same_v<_BinaryPredicate, equal_to<>>>; + public: - _LIBCPP_HIDE_FROM_ABI - boyer_moore_horspool_searcher(_RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, - _Hash __hash = _Hash(), - _BinaryPredicate __pred = _BinaryPredicate()) - : __first_(__first), - __last_(__last), - __pred_(__pred), - __pattern_length_(__last - __first), - __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, __pattern_length_, __hash, __pred_)) { + _LIBCPP_HIDE_FROM_ABI boyer_moore_horspool_searcher( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _Hash __hash = _Hash(), + _BinaryPredicate __pred = _BinaryPredicate()) + : __first_(__first), + __last_(__last), + __pred_(__pred), + __pattern_length_(__last - __first), + __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, __pattern_length_, __hash, __pred_)) { if (__first == __last) return; --__last; @@ -293,8 +279,8 @@ private: template _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2> __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { - _RandomAccessIterator2 __current = __f; - const _RandomAccessIterator2 __last = __l - __pattern_length_; + _RandomAccessIterator2 __current = __f; + const _RandomAccessIterator2 __last = __l - __pattern_length_; const __skip_table_type& __skip_table = *__skip_table_; while (__current <= __last) { diff --git a/libcxx/include/__functional/compose.h b/libcxx/include/__functional/compose.h index af207e7cbafbf5a28a24c191b0d0f03bfa7f480a..4b86dd37cd48a4af6ee0aca37af85dcb1c655cb1 100644 --- a/libcxx/include/__functional/compose.h +++ b/libcxx/include/__functional/compose.h @@ -25,25 +25,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 struct __compose_op { - template - _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Fn1&& __f1, _Fn2&& __f2, _Args&&... __args) const - noexcept(noexcept(std::invoke(std::forward<_Fn1>(__f1), std::invoke(std::forward<_Fn2>(__f2), std::forward<_Args>(__args)...)))) - -> decltype( std::invoke(std::forward<_Fn1>(__f1), std::invoke(std::forward<_Fn2>(__f2), std::forward<_Args>(__args)...))) - { return std::invoke(std::forward<_Fn1>(__f1), std::invoke(std::forward<_Fn2>(__f2), std::forward<_Args>(__args)...)); } + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn1&& __f1, _Fn2&& __f2, _Args&&... __args) const noexcept(noexcept( + std::invoke(std::forward<_Fn1>(__f1), std::invoke(std::forward<_Fn2>(__f2), std::forward<_Args>(__args)...)))) + -> decltype(std::invoke(std::forward<_Fn1>(__f1), + std::invoke(std::forward<_Fn2>(__f2), std::forward<_Args>(__args)...))) { + return std::invoke(std::forward<_Fn1>(__f1), std::invoke(std::forward<_Fn2>(__f2), std::forward<_Args>(__args)...)); + } }; template struct __compose_t : __perfect_forward<__compose_op, _Fn1, _Fn2> { - using __perfect_forward<__compose_op, _Fn1, _Fn2>::__perfect_forward; + using __perfect_forward<__compose_op, _Fn1, _Fn2>::__perfect_forward; }; template -_LIBCPP_HIDE_FROM_ABI -constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2) - noexcept(noexcept(__compose_t, decay_t<_Fn2>>(std::forward<_Fn1>(__f1), std::forward<_Fn2>(__f2)))) - -> decltype( __compose_t, decay_t<_Fn2>>(std::forward<_Fn1>(__f1), std::forward<_Fn2>(__f2))) - { return __compose_t, decay_t<_Fn2>>(std::forward<_Fn1>(__f1), std::forward<_Fn2>(__f2)); } +_LIBCPP_HIDE_FROM_ABI constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2) noexcept( + noexcept(__compose_t, decay_t<_Fn2>>(std::forward<_Fn1>(__f1), std::forward<_Fn2>(__f2)))) + -> decltype(__compose_t, decay_t<_Fn2>>(std::forward<_Fn1>(__f1), std::forward<_Fn2>(__f2))) { + return __compose_t, decay_t<_Fn2>>(std::forward<_Fn1>(__f1), std::forward<_Fn2>(__f2)); +} #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__functional/default_searcher.h b/libcxx/include/__functional/default_searcher.h index 21b6de9c34c848d949cb5c981e75cb78db1c3be7..db89d10757c1b1fb10d3d67f6c28e1d878db4ead 100644 --- a/libcxx/include/__functional/default_searcher.h +++ b/libcxx/include/__functional/default_searcher.h @@ -26,27 +26,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 // default searcher -template> +template > class _LIBCPP_TEMPLATE_VIS default_searcher { public: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - default_searcher(_ForwardIterator __f, _ForwardIterator __l, - _BinaryPredicate __p = _BinaryPredicate()) - : __first_(__f), __last_(__l), __pred_(__p) {} - - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - pair<_ForwardIterator2, _ForwardIterator2> - operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const - { - auto __proj = __identity(); - return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj); - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + default_searcher(_ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate()) + : __first_(__f), __last_(__l), __pred_(__p) {} + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator2, _ForwardIterator2> + operator()(_ForwardIterator2 __f, _ForwardIterator2 __l) const { + auto __proj = __identity(); + return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj); + } private: - _ForwardIterator __first_; - _ForwardIterator __last_; - _BinaryPredicate __pred_; + _ForwardIterator __first_; + _ForwardIterator __last_; + _BinaryPredicate __pred_; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(default_searcher); diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h index 7cc4cccc26cdc634dcf6a61395eaf16fb380dd49..6505bb5871739d15c20cd1761955f054b6fc6369 100644 --- a/libcxx/include/__functional/function.h +++ b/libcxx/include/__functional/function.h @@ -53,86 +53,77 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") -class _LIBCPP_EXPORTED_FROM_ABI bad_function_call - : public exception -{ +class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception { public: - _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT = default; - _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT = default; - _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default; // Note that when a key function is not used, every translation unit that uses // bad_function_call will end up containing a weak definition of the vtable and // typeinfo. -#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION - ~bad_function_call() _NOEXCEPT override; -#else - _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {} -#endif - -#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE - const char* what() const _NOEXCEPT override; -#endif +# ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION + ~bad_function_call() _NOEXCEPT override; +# else + _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {} +# endif + +# ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE + const char* what() const _NOEXCEPT override; +# endif }; _LIBCPP_DIAGNOSTIC_POP -_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI -void __throw_bad_function_call() -{ -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - throw bad_function_call(); -#else - _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode"); -#endif +_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_function_call() { +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS + throw bad_function_call(); +# else + _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode"); +# endif } -template class _LIBCPP_TEMPLATE_VIS function; // undefined +template +class _LIBCPP_TEMPLATE_VIS function; // undefined -namespace __function -{ +namespace __function { -template -struct __maybe_derive_from_unary_function -{ -}; +template +struct __maybe_derive_from_unary_function {}; -template -struct __maybe_derive_from_unary_function<_Rp(_A1)> - : public __unary_function<_A1, _Rp> -{ -}; +template +struct __maybe_derive_from_unary_function<_Rp(_A1)> : public __unary_function<_A1, _Rp> {}; -template -struct __maybe_derive_from_binary_function -{ -}; +template +struct __maybe_derive_from_binary_function {}; -template -struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> - : public __binary_function<_A1, _A2, _Rp> -{ -}; +template +struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; template -_LIBCPP_HIDE_FROM_ABI -bool __not_null(_Fp const&) { return true; } +_LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp const&) { + return true; +} template -_LIBCPP_HIDE_FROM_ABI -bool __not_null(_Fp* __ptr) { return __ptr; } +_LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp* __ptr) { + return __ptr; +} template -_LIBCPP_HIDE_FROM_ABI -bool __not_null(_Ret _Class::*__ptr) { return __ptr; } +_LIBCPP_HIDE_FROM_ABI bool __not_null(_Ret _Class::*__ptr) { + return __ptr; +} template -_LIBCPP_HIDE_FROM_ABI -bool __not_null(function<_Fp> const& __f) { return !!__f; } +_LIBCPP_HIDE_FROM_ABI bool __not_null(function<_Fp> const& __f) { + return !!__f; +} -#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS -template -_LIBCPP_HIDE_FROM_ABI -bool __not_null(_Rp (^__p)(_Args...)) { return __p; } -#endif +# ifdef _LIBCPP_HAS_EXTENSION_BLOCKS +template +_LIBCPP_HIDE_FROM_ABI bool __not_null(_Rp (^__p)(_Args...)) { + return __p; +} +# endif } // namespace __function @@ -140,84 +131,60 @@ namespace __function { // __alloc_func holds a functor and an allocator. -template class __alloc_func; +template +class __alloc_func; template class __default_alloc_func; template -class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> -{ - __compressed_pair<_Fp, _Ap> __f_; - - public: - typedef _LIBCPP_NODEBUG _Fp _Target; - typedef _LIBCPP_NODEBUG _Ap _Alloc; - - _LIBCPP_HIDE_FROM_ABI - const _Target& __target() const { return __f_.first(); } - - // WIN32 APIs may define __allocator, so use __get_allocator instead. - _LIBCPP_HIDE_FROM_ABI - const _Alloc& __get_allocator() const { return __f_.second(); } - - _LIBCPP_HIDE_FROM_ABI - explicit __alloc_func(_Target&& __f) - : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), - std::forward_as_tuple()) - { - } +class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> { + __compressed_pair<_Fp, _Ap> __f_; - _LIBCPP_HIDE_FROM_ABI - explicit __alloc_func(const _Target& __f, const _Alloc& __a) - : __f_(piecewise_construct, std::forward_as_tuple(__f), - std::forward_as_tuple(__a)) - { - } +public: + typedef _LIBCPP_NODEBUG _Fp _Target; + typedef _LIBCPP_NODEBUG _Ap _Alloc; - _LIBCPP_HIDE_FROM_ABI - explicit __alloc_func(const _Target& __f, _Alloc&& __a) - : __f_(piecewise_construct, std::forward_as_tuple(__f), - std::forward_as_tuple(std::move(__a))) - { - } + _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_.first(); } - _LIBCPP_HIDE_FROM_ABI - explicit __alloc_func(_Target&& __f, _Alloc&& __a) - : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), - std::forward_as_tuple(std::move(__a))) - { - } + // WIN32 APIs may define __allocator, so use __get_allocator instead. + _LIBCPP_HIDE_FROM_ABI const _Alloc& __get_allocator() const { return __f_.second(); } - _LIBCPP_HIDE_FROM_ABI - _Rp operator()(_ArgTypes&&... __arg) - { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first(), - std::forward<_ArgTypes>(__arg)...); - } + _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f) + : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple()) {} - _LIBCPP_HIDE_FROM_ABI - __alloc_func* __clone() const - { - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA; - _AA __a(__f_.second()); - typedef __allocator_destructor<_AA> _Dp; - unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); - return __hold.release(); - } + _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, const _Alloc& __a) + : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(__a)) {} - _LIBCPP_HIDE_FROM_ABI - void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } + _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, _Alloc&& __a) + : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(std::move(__a))) {} - _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) { - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; - _FunAlloc __a(__f->__get_allocator()); - __f->destroy(); - __a.deallocate(__f, 1); - } + _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f, _Alloc&& __a) + : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple(std::move(__a))) {} + + _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), std::forward<_ArgTypes>(__arg)...); + } + + _LIBCPP_HIDE_FROM_ABI __alloc_func* __clone() const { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA; + _AA __a(__f_.second()); + typedef __allocator_destructor<_AA> _Dp; + unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); + return __hold.release(); + } + + _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } + + _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; + _FunAlloc __a(__f->__get_allocator()); + __f->destroy(); + __a.deallocate(__f, 1); + } }; template @@ -227,454 +194,377 @@ class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { public: typedef _LIBCPP_NODEBUG _Fp _Target; - _LIBCPP_HIDE_FROM_ABI - const _Target& __target() const { return __f_; } + _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_; } - _LIBCPP_HIDE_FROM_ABI - explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {} + _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {} - _LIBCPP_HIDE_FROM_ABI - explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} + _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} - _LIBCPP_HIDE_FROM_ABI - _Rp operator()(_ArgTypes&&... __arg) { + _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { typedef __invoke_void_return_wrapper<_Rp> _Invoker; return _Invoker::__call(__f_, std::forward<_ArgTypes>(__arg)...); } - _LIBCPP_HIDE_FROM_ABI - __default_alloc_func* __clone() const { - __builtin_new_allocator::__holder_t __hold = - __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); - __default_alloc_func* __res = - ::new ((void*)__hold.get()) __default_alloc_func(__f_); + _LIBCPP_HIDE_FROM_ABI __default_alloc_func* __clone() const { + __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); + __default_alloc_func* __res = ::new ((void*)__hold.get()) __default_alloc_func(__f_); (void)__hold.release(); return __res; } - _LIBCPP_HIDE_FROM_ABI - void destroy() _NOEXCEPT { __f_.~_Target(); } + _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~_Target(); } _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) { __f->destroy(); - __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); + __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); } }; // __base provides an abstract interface for copyable functors. -template class _LIBCPP_TEMPLATE_VIS __base; +template +class _LIBCPP_TEMPLATE_VIS __base; + +template +class __base<_Rp(_ArgTypes...)> { + __base(const __base&); + __base& operator=(const __base&); -template -class __base<_Rp(_ArgTypes...)> -{ - __base(const __base&); - __base& operator=(const __base&); public: - _LIBCPP_HIDE_FROM_ABI __base() {} - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {} - virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; - virtual void destroy() _NOEXCEPT = 0; - virtual void destroy_deallocate() _NOEXCEPT = 0; - virtual _Rp operator()(_ArgTypes&& ...) = 0; -#ifndef _LIBCPP_HAS_NO_RTTI - virtual const void* target(const type_info&) const _NOEXCEPT = 0; - virtual const std::type_info& target_type() const _NOEXCEPT = 0; -#endif // _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI __base() {} + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() _NOEXCEPT = 0; + virtual void destroy_deallocate() _NOEXCEPT = 0; + virtual _Rp operator()(_ArgTypes&&...) = 0; +# ifndef _LIBCPP_HAS_NO_RTTI + virtual const void* target(const type_info&) const _NOEXCEPT = 0; + virtual const std::type_info& target_type() const _NOEXCEPT = 0; +# endif // _LIBCPP_HAS_NO_RTTI }; // __func implements __base for a given functor type. -template class __func; +template +class __func; + +template +class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { + __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; -template -class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> - : public __base<_Rp(_ArgTypes...)> -{ - __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; public: - _LIBCPP_HIDE_FROM_ABI - explicit __func(_Fp&& __f) - : __f_(std::move(__f)) {} - - _LIBCPP_HIDE_FROM_ABI - explicit __func(const _Fp& __f, const _Alloc& __a) - : __f_(__f, __a) {} - - _LIBCPP_HIDE_FROM_ABI - explicit __func(const _Fp& __f, _Alloc&& __a) - : __f_(__f, std::move(__a)) {} - - _LIBCPP_HIDE_FROM_ABI - explicit __func(_Fp&& __f, _Alloc&& __a) - : __f_(std::move(__f), std::move(__a)) {} - - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg); -#ifndef _LIBCPP_HAS_NO_RTTI - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT; -#endif // _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f) : __f_(std::move(__f)) {} + + _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {} + + _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, _Alloc&& __a) : __f_(__f, std::move(__a)) {} + + _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f, _Alloc&& __a) : __f_(std::move(__f), std::move(__a)) {} + + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg); +# ifndef _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT; +# endif // _LIBCPP_HAS_NO_RTTI }; -template -__base<_Rp(_ArgTypes...)>* -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __rebind_alloc<__alloc_traits, __func> _Ap; - _Ap __a(__f_.__get_allocator()); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); - return __hold.release(); +template +__base<_Rp(_ArgTypes...)>* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __func> _Ap; + _Ap __a(__f_.__get_allocator()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); + return __hold.release(); } -template -void -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const -{ - ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); +template +void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const { + ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); } -template -void -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT -{ - __f_.destroy(); +template +void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT { + __f_.destroy(); } -template -void -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __rebind_alloc<__alloc_traits, __func> _Ap; - _Ap __a(__f_.__get_allocator()); - __f_.destroy(); - __a.deallocate(this, 1); +template +void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __func> _Ap; + _Ap __a(__f_.__get_allocator()); + __f_.destroy(); + __a.deallocate(this, 1); } -template -_Rp -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) -{ - return __f_(std::forward<_ArgTypes>(__arg)...); +template +_Rp __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) { + return __f_(std::forward<_ArgTypes>(__arg)...); } -#ifndef _LIBCPP_HAS_NO_RTTI +# ifndef _LIBCPP_HAS_NO_RTTI -template -const void* -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT -{ - if (__ti == typeid(_Fp)) - return std::addressof(__f_.__target()); - return nullptr; +template +const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { + if (__ti == typeid(_Fp)) + return std::addressof(__f_.__target()); + return nullptr; } -template -const std::type_info& -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT -{ - return typeid(_Fp); +template +const std::type_info& __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { + return typeid(_Fp); } -#endif // _LIBCPP_HAS_NO_RTTI +# endif // _LIBCPP_HAS_NO_RTTI // __value_func creates a value-type from a __func. -template class __value_func; +template +class __value_func; -template class __value_func<_Rp(_ArgTypes...)> -{ - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - typename aligned_storage<3 * sizeof(void*)>::type __buf_; - _LIBCPP_SUPPRESS_DEPRECATED_POP +template +class __value_func<_Rp(_ArgTypes...)> { + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + typename aligned_storage<3 * sizeof(void*)>::type __buf_; + _LIBCPP_SUPPRESS_DEPRECATED_POP - typedef __base<_Rp(_ArgTypes...)> __func; - __func* __f_; + typedef __base<_Rp(_ArgTypes...)> __func; + __func* __f_; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) - { - return reinterpret_cast<__func*>(__p); - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) { return reinterpret_cast<__func*>(__p); } - public: - _LIBCPP_HIDE_FROM_ABI - __value_func() _NOEXCEPT : __f_(nullptr) {} - - template - _LIBCPP_HIDE_FROM_ABI __value_func(_Fp&& __f, const _Alloc& __a) - : __f_(nullptr) - { - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; - typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; - - if (__function::__not_null(__f)) - { - _FunAlloc __af(__a); - if (sizeof(_Fun) <= sizeof(__buf_) && - is_nothrow_copy_constructible<_Fp>::value && - is_nothrow_copy_constructible<_FunAlloc>::value) - { - __f_ = - ::new ((void*)&__buf_) _Fun(std::move(__f), _Alloc(__af)); - } - else - { - typedef __allocator_destructor<_FunAlloc> _Dp; - unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); - ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__a)); - __f_ = __hold.release(); - } - } - } +public: + _LIBCPP_HIDE_FROM_ABI __value_func() _NOEXCEPT : __f_(nullptr) {} - template , __value_func>::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) - : __value_func(std::forward<_Fp>(__f), allocator<_Fp>()) {} - - _LIBCPP_HIDE_FROM_ABI - __value_func(const __value_func& __f) - { - if (__f.__f_ == nullptr) - __f_ = nullptr; - else if ((void*)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); + template + _LIBCPP_HIDE_FROM_ABI __value_func(_Fp&& __f, const _Alloc& __a) : __f_(nullptr) { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; + + if (__function::__not_null(__f)) { + _FunAlloc __af(__a); + if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value && + is_nothrow_copy_constructible<_FunAlloc>::value) { + __f_ = ::new ((void*)&__buf_) _Fun(std::move(__f), _Alloc(__af)); + } else { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__a)); + __f_ = __hold.release(); + } } + } - _LIBCPP_HIDE_FROM_ABI - __value_func(__value_func&& __f) _NOEXCEPT - { - if (__f.__f_ == nullptr) - __f_ = nullptr; - else if ((void*)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - { - __f_ = __f.__f_; - __f.__f_ = nullptr; - } - } + template , __value_func>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) : __value_func(std::forward<_Fp>(__f), allocator<_Fp>()) {} + + _LIBCPP_HIDE_FROM_ABI __value_func(const __value_func& __f) { + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } else + __f_ = __f.__f_->__clone(); + } - _LIBCPP_HIDE_FROM_ABI - ~__value_func() - { - if ((void*)__f_ == &__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); + _LIBCPP_HIDE_FROM_ABI __value_func(__value_func&& __f) _NOEXCEPT { + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } else { + __f_ = __f.__f_; + __f.__f_ = nullptr; } + } - _LIBCPP_HIDE_FROM_ABI - __value_func& operator=(__value_func&& __f) - { - *this = nullptr; - if (__f.__f_ == nullptr) - __f_ = nullptr; - else if ((void*)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - { - __f_ = __f.__f_; - __f.__f_ = nullptr; - } - return *this; - } + _LIBCPP_HIDE_FROM_ABI ~__value_func() { + if ((void*)__f_ == &__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + } - _LIBCPP_HIDE_FROM_ABI - __value_func& operator=(nullptr_t) - { - __func* __f = __f_; - __f_ = nullptr; - if ((void*)__f == &__buf_) - __f->destroy(); - else if (__f) - __f->destroy_deallocate(); - return *this; + _LIBCPP_HIDE_FROM_ABI __value_func& operator=(__value_func&& __f) { + *this = nullptr; + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } else { + __f_ = __f.__f_; + __f.__f_ = nullptr; } + return *this; + } - _LIBCPP_HIDE_FROM_ABI - _Rp operator()(_ArgTypes&&... __args) const - { - if (__f_ == nullptr) - __throw_bad_function_call(); - return (*__f_)(std::forward<_ArgTypes>(__args)...); - } + _LIBCPP_HIDE_FROM_ABI __value_func& operator=(nullptr_t) { + __func* __f = __f_; + __f_ = nullptr; + if ((void*)__f == &__buf_) + __f->destroy(); + else if (__f) + __f->destroy_deallocate(); + return *this; + } - _LIBCPP_HIDE_FROM_ABI - void swap(__value_func& __f) _NOEXCEPT - { - if (&__f == this) - return; - if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) - { - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - typename aligned_storage::type __tempbuf; - _LIBCPP_SUPPRESS_DEPRECATED_POP - __func* __t = __as_base(&__tempbuf); - __f_->__clone(__t); - __f_->destroy(); - __f_ = nullptr; - __f.__f_->__clone(__as_base(&__buf_)); - __f.__f_->destroy(); - __f.__f_ = nullptr; - __f_ = __as_base(&__buf_); - __t->__clone(__as_base(&__f.__buf_)); - __t->destroy(); - __f.__f_ = __as_base(&__f.__buf_); - } - else if ((void*)__f_ == &__buf_) - { - __f_->__clone(__as_base(&__f.__buf_)); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = __as_base(&__f.__buf_); - } - else if ((void*)__f.__f_ == &__f.__buf_) - { - __f.__f_->__clone(__as_base(&__buf_)); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = __as_base(&__buf_); - } - else - std::swap(__f_, __f.__f_); - } + _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { + if (__f_ == nullptr) + __throw_bad_function_call(); + return (*__f_)(std::forward<_ArgTypes>(__args)...); + } - _LIBCPP_HIDE_FROM_ABI - explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } + _LIBCPP_HIDE_FROM_ABI void swap(__value_func& __f) _NOEXCEPT { + if (&__f == this) + return; + if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) { + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + typename aligned_storage::type __tempbuf; + _LIBCPP_SUPPRESS_DEPRECATED_POP + __func* __t = __as_base(&__tempbuf); + __f_->__clone(__t); + __f_->destroy(); + __f_ = nullptr; + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = nullptr; + __f_ = __as_base(&__buf_); + __t->__clone(__as_base(&__f.__buf_)); + __t->destroy(); + __f.__f_ = __as_base(&__f.__buf_); + } else if ((void*)__f_ == &__buf_) { + __f_->__clone(__as_base(&__f.__buf_)); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = __as_base(&__f.__buf_); + } else if ((void*)__f.__f_ == &__f.__buf_) { + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = __as_base(&__buf_); + } else + std::swap(__f_, __f.__f_); + } -#ifndef _LIBCPP_HAS_NO_RTTI - _LIBCPP_HIDE_FROM_ABI - const std::type_info& target_type() const _NOEXCEPT - { - if (__f_ == nullptr) - return typeid(void); - return __f_->target_type(); - } + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } - template - _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT - { - if (__f_ == nullptr) - return nullptr; - return (const _Tp*)__f_->target(typeid(_Tp)); - } -#endif // _LIBCPP_HAS_NO_RTTI +# ifndef _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { + if (__f_ == nullptr) + return typeid(void); + return __f_->target_type(); + } + + template + _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT { + if (__f_ == nullptr) + return nullptr; + return (const _Tp*)__f_->target(typeid(_Tp)); + } +# endif // _LIBCPP_HAS_NO_RTTI }; // Storage for a functor object, to be used with __policy to manage copy and // destruction. -union __policy_storage -{ - mutable char __small[sizeof(void*) * 2]; - void* __large; +union __policy_storage { + mutable char __small[sizeof(void*) * 2]; + void* __large; }; // True if _Fun can safely be held in __policy_storage.__small. template struct __use_small_storage : public integral_constant< - bool, sizeof(_Fun) <= sizeof(__policy_storage) && - _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && - is_trivially_copy_constructible<_Fun>::value && - is_trivially_destructible<_Fun>::value> {}; + bool, + sizeof(_Fun) <= sizeof(__policy_storage)&& _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && + is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {}; // Policy contains information about how to copy, destroy, and move the // underlying functor. You can think of it as a vtable of sorts. -struct __policy -{ - // Used to copy or destroy __large values. null for trivial objects. - void* (*const __clone)(const void*); - void (*const __destroy)(void*); - - // True if this is the null policy (no value). - const bool __is_null; - - // The target type. May be null if RTTI is disabled. - const std::type_info* const __type_info; - - // Returns a pointer to a static policy object suitable for the functor - // type. - template - _LIBCPP_HIDE_FROM_ABI static const __policy* __create() - { - return __choose_policy<_Fun>(__use_small_storage<_Fun>()); - } +struct __policy { + // Used to copy or destroy __large values. null for trivial objects. + void* (*const __clone)(const void*); + void (*const __destroy)(void*); + + // True if this is the null policy (no value). + const bool __is_null; + + // The target type. May be null if RTTI is disabled. + const std::type_info* const __type_info; + + // Returns a pointer to a static policy object suitable for the functor + // type. + template + _LIBCPP_HIDE_FROM_ABI static const __policy* __create() { + return __choose_policy<_Fun>(__use_small_storage<_Fun>()); + } - _LIBCPP_HIDE_FROM_ABI - static const __policy* __create_empty() - { - static const _LIBCPP_CONSTEXPR __policy __policy = {nullptr, nullptr, - true, -#ifndef _LIBCPP_HAS_NO_RTTI - &typeid(void) -#else - nullptr -#endif - }; - return &__policy; - } + _LIBCPP_HIDE_FROM_ABI static const __policy* __create_empty() { + static const _LIBCPP_CONSTEXPR __policy __policy = { + nullptr, + nullptr, + true, +# ifndef _LIBCPP_HAS_NO_RTTI + &typeid(void) +# else + nullptr +# endif + }; + return &__policy; + } - private: - template - _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) - { - const _Fun* __f = static_cast(__s); - return __f->__clone(); - } +private: + template + _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) { + const _Fun* __f = static_cast(__s); + return __f->__clone(); + } - template - _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) { - _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); - } + template + _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) { + _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); + } - template - _LIBCPP_HIDE_FROM_ABI static const __policy* - __choose_policy(/* is_small = */ false_type) { - static const _LIBCPP_CONSTEXPR __policy __policy = { - &__large_clone<_Fun>, &__large_destroy<_Fun>, false, -#ifndef _LIBCPP_HAS_NO_RTTI - &typeid(typename _Fun::_Target) -#else - nullptr -#endif - }; - return &__policy; - } + template + _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ false_type) { + static const _LIBCPP_CONSTEXPR __policy __policy = { + &__large_clone<_Fun>, + &__large_destroy<_Fun>, + false, +# ifndef _LIBCPP_HAS_NO_RTTI + &typeid(typename _Fun::_Target) +# else + nullptr +# endif + }; + return &__policy; + } - template - _LIBCPP_HIDE_FROM_ABI static const __policy* - __choose_policy(/* is_small = */ true_type) - { - static const _LIBCPP_CONSTEXPR __policy __policy = { - nullptr, nullptr, false, -#ifndef _LIBCPP_HAS_NO_RTTI - &typeid(typename _Fun::_Target) -#else - nullptr -#endif - }; - return &__policy; - } + template + _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ true_type) { + static const _LIBCPP_CONSTEXPR __policy __policy = { + nullptr, + nullptr, + false, +# ifndef _LIBCPP_HAS_NO_RTTI + &typeid(typename _Fun::_Target) +# else + nullptr +# endif + }; + return &__policy; + } }; // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is @@ -684,548 +574,459 @@ using __fast_forward = __conditional_t::value, _Tp, _Tp&&>; // __policy_invoker calls an instance of __alloc_func held in __policy_storage. -template struct __policy_invoker; +template +struct __policy_invoker; template -struct __policy_invoker<_Rp(_ArgTypes...)> -{ - typedef _Rp (*__Call)(const __policy_storage*, - __fast_forward<_ArgTypes>...); - - __Call __call_; - - // Creates an invoker that throws bad_function_call. - _LIBCPP_HIDE_FROM_ABI - __policy_invoker() : __call_(&__call_empty) {} - - // Creates an invoker that calls the given instance of __func. - template - _LIBCPP_HIDE_FROM_ABI static __policy_invoker __create() - { - return __policy_invoker(&__call_impl<_Fun>); - } +struct __policy_invoker<_Rp(_ArgTypes...)> { + typedef _Rp (*__Call)(const __policy_storage*, __fast_forward<_ArgTypes>...); - private: - _LIBCPP_HIDE_FROM_ABI - explicit __policy_invoker(__Call __c) : __call_(__c) {} + __Call __call_; - _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, - __fast_forward<_ArgTypes>...) - { - __throw_bad_function_call(); - } + // Creates an invoker that throws bad_function_call. + _LIBCPP_HIDE_FROM_ABI __policy_invoker() : __call_(&__call_empty) {} - template - _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, - __fast_forward<_ArgTypes>... __args) - { - _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value - ? &__buf->__small - : __buf->__large); - return (*__f)(std::forward<_ArgTypes>(__args)...); - } + // Creates an invoker that calls the given instance of __func. + template + _LIBCPP_HIDE_FROM_ABI static __policy_invoker __create() { + return __policy_invoker(&__call_impl<_Fun>); + } + +private: + _LIBCPP_HIDE_FROM_ABI explicit __policy_invoker(__Call __c) : __call_(__c) {} + + _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, __fast_forward<_ArgTypes>...) { + __throw_bad_function_call(); + } + + template + _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) { + _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large); + return (*__f)(std::forward<_ArgTypes>(__args)...); + } }; // __policy_func uses a __policy and __policy_invoker to create a type-erased, // copyable functor. -template class __policy_func; - -template class __policy_func<_Rp(_ArgTypes...)> -{ - // Inline storage for small objects. - __policy_storage __buf_; - - // Calls the value stored in __buf_. This could technically be part of - // policy, but storing it here eliminates a level of indirection inside - // operator(). - typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; - __invoker __invoker_; - - // The policy that describes how to move / copy / destroy __buf_. Never - // null, even if the function is empty. - const __policy* __policy_; - - public: - _LIBCPP_HIDE_FROM_ABI - __policy_func() : __policy_(__policy::__create_empty()) {} - - template - _LIBCPP_HIDE_FROM_ABI __policy_func(_Fp&& __f, const _Alloc& __a) - : __policy_(__policy::__create_empty()) - { - typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; - - if (__function::__not_null(__f)) - { - __invoker_ = __invoker::template __create<_Fun>(); - __policy_ = __policy::__create<_Fun>(); - - _FunAlloc __af(__a); - if (__use_small_storage<_Fun>()) - { - ::new ((void*)&__buf_.__small) - _Fun(std::move(__f), _Alloc(__af)); - } - else - { - typedef __allocator_destructor<_FunAlloc> _Dp; - unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); - ::new ((void*)__hold.get()) - _Fun(std::move(__f), _Alloc(__af)); - __buf_.__large = __hold.release(); - } - } - } +template +class __policy_func; + +template +class __policy_func<_Rp(_ArgTypes...)> { + // Inline storage for small objects. + __policy_storage __buf_; + + // Calls the value stored in __buf_. This could technically be part of + // policy, but storing it here eliminates a level of indirection inside + // operator(). + typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; + __invoker __invoker_; - template , __policy_func>::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) - : __policy_(__policy::__create_empty()) { - typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; - - if (__function::__not_null(__f)) { - __invoker_ = __invoker::template __create<_Fun>(); - __policy_ = __policy::__create<_Fun>(); - if (__use_small_storage<_Fun>()) { - ::new ((void*)&__buf_.__small) _Fun(std::move(__f)); - } else { - __builtin_new_allocator::__holder_t __hold = - __builtin_new_allocator::__allocate_type<_Fun>(1); - __buf_.__large = ::new ((void*)__hold.get()) _Fun(std::move(__f)); - (void)__hold.release(); - } + // The policy that describes how to move / copy / destroy __buf_. Never + // null, even if the function is empty. + const __policy* __policy_; + +public: + _LIBCPP_HIDE_FROM_ABI __policy_func() : __policy_(__policy::__create_empty()) {} + + template + _LIBCPP_HIDE_FROM_ABI __policy_func(_Fp&& __f, const _Alloc& __a) : __policy_(__policy::__create_empty()) { + typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; + + if (__function::__not_null(__f)) { + __invoker_ = __invoker::template __create<_Fun>(); + __policy_ = __policy::__create<_Fun>(); + + _FunAlloc __af(__a); + if (__use_small_storage<_Fun>()) { + ::new ((void*)&__buf_.__small) _Fun(std::move(__f), _Alloc(__af)); + } else { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__af)); + __buf_.__large = __hold.release(); } } + } - _LIBCPP_HIDE_FROM_ABI - __policy_func(const __policy_func& __f) - : __buf_(__f.__buf_), __invoker_(__f.__invoker_), - __policy_(__f.__policy_) - { - if (__policy_->__clone) - __buf_.__large = __policy_->__clone(__f.__buf_.__large); + template , __policy_func>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) { + typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; + + if (__function::__not_null(__f)) { + __invoker_ = __invoker::template __create<_Fun>(); + __policy_ = __policy::__create<_Fun>(); + if (__use_small_storage<_Fun>()) { + ::new ((void*)&__buf_.__small) _Fun(std::move(__f)); + } else { + __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<_Fun>(1); + __buf_.__large = ::new ((void*)__hold.get()) _Fun(std::move(__f)); + (void)__hold.release(); + } } + } - _LIBCPP_HIDE_FROM_ABI - __policy_func(__policy_func&& __f) - : __buf_(__f.__buf_), __invoker_(__f.__invoker_), - __policy_(__f.__policy_) - { - if (__policy_->__destroy) - { - __f.__policy_ = __policy::__create_empty(); - __f.__invoker_ = __invoker(); - } - } + _LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { + if (__policy_->__clone) + __buf_.__large = __policy_->__clone(__f.__buf_.__large); + } - _LIBCPP_HIDE_FROM_ABI - ~__policy_func() - { - if (__policy_->__destroy) - __policy_->__destroy(__buf_.__large); + _LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { + if (__policy_->__destroy) { + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); } + } - _LIBCPP_HIDE_FROM_ABI - __policy_func& operator=(__policy_func&& __f) - { - *this = nullptr; - __buf_ = __f.__buf_; - __invoker_ = __f.__invoker_; - __policy_ = __f.__policy_; - __f.__policy_ = __policy::__create_empty(); - __f.__invoker_ = __invoker(); - return *this; - } + _LIBCPP_HIDE_FROM_ABI ~__policy_func() { + if (__policy_->__destroy) + __policy_->__destroy(__buf_.__large); + } - _LIBCPP_HIDE_FROM_ABI - __policy_func& operator=(nullptr_t) - { - const __policy* __p = __policy_; - __policy_ = __policy::__create_empty(); - __invoker_ = __invoker(); - if (__p->__destroy) - __p->__destroy(__buf_.__large); - return *this; - } + _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) { + *this = nullptr; + __buf_ = __f.__buf_; + __invoker_ = __f.__invoker_; + __policy_ = __f.__policy_; + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); + return *this; + } - _LIBCPP_HIDE_FROM_ABI - _Rp operator()(_ArgTypes&&... __args) const - { - return __invoker_.__call_(std::addressof(__buf_), - std::forward<_ArgTypes>(__args)...); - } + _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) { + const __policy* __p = __policy_; + __policy_ = __policy::__create_empty(); + __invoker_ = __invoker(); + if (__p->__destroy) + __p->__destroy(__buf_.__large); + return *this; + } - _LIBCPP_HIDE_FROM_ABI - void swap(__policy_func& __f) - { - std::swap(__invoker_, __f.__invoker_); - std::swap(__policy_, __f.__policy_); - std::swap(__buf_, __f.__buf_); - } + _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { + return __invoker_.__call_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...); + } - _LIBCPP_HIDE_FROM_ABI - explicit operator bool() const _NOEXCEPT - { - return !__policy_->__is_null; - } + _LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) { + std::swap(__invoker_, __f.__invoker_); + std::swap(__policy_, __f.__policy_); + std::swap(__buf_, __f.__buf_); + } -#ifndef _LIBCPP_HAS_NO_RTTI - _LIBCPP_HIDE_FROM_ABI - const std::type_info& target_type() const _NOEXCEPT - { - return *__policy_->__type_info; - } + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return !__policy_->__is_null; } - template - _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT - { - if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) - return nullptr; - if (__policy_->__clone) // Out of line storage. - return reinterpret_cast(__buf_.__large); - else - return reinterpret_cast(&__buf_.__small); - } -#endif // _LIBCPP_HAS_NO_RTTI +# ifndef _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { return *__policy_->__type_info; } + + template + _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT { + if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) + return nullptr; + if (__policy_->__clone) // Out of line storage. + return reinterpret_cast(__buf_.__large); + else + return reinterpret_cast(&__buf_.__small); + } +# endif // _LIBCPP_HAS_NO_RTTI }; -#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) +# if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) -extern "C" void *_Block_copy(const void *); -extern "C" void _Block_release(const void *); +extern "C" void* _Block_copy(const void*); +extern "C" void _Block_release(const void*); -template -class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> - : public __base<_Rp(_ArgTypes...)> -{ - typedef _Rp1(^__block_type)(_ArgTypes1...); - __block_type __f_; +template +class __func<_Rp1 (^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { + typedef _Rp1 (^__block_type)(_ArgTypes1...); + __block_type __f_; public: - _LIBCPP_HIDE_FROM_ABI - explicit __func(__block_type const& __f) -#ifdef _LIBCPP_HAS_OBJC_ARC - : __f_(__f) -#else - : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) -#endif - { } + _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type const& __f) +# ifdef _LIBCPP_HAS_OBJC_ARC + : __f_(__f) +# else + : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) +# endif + { + } - // [TODO] add && to save on a retain + // [TODO] add && to save on a retain - _LIBCPP_HIDE_FROM_ABI - explicit __func(__block_type __f, const _Alloc& /* unused */) -#ifdef _LIBCPP_HAS_OBJC_ARC - : __f_(__f) -#else - : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) -#endif - { } - - virtual __base<_Rp(_ArgTypes...)>* __clone() const { - _LIBCPP_ASSERT_INTERNAL(false, - "Block pointers are just pointers, so they should always fit into " - "std::function's small buffer optimization. This function should " - "never be invoked."); - return nullptr; - } + _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type __f, const _Alloc& /* unused */) +# ifdef _LIBCPP_HAS_OBJC_ARC + : __f_(__f) +# else + : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) +# endif + { + } - virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { - ::new ((void*)__p) __func(__f_); - } + virtual __base<_Rp(_ArgTypes...)>* __clone() const { + _LIBCPP_ASSERT_INTERNAL( + false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + return nullptr; + } - virtual void destroy() _NOEXCEPT { -#ifndef _LIBCPP_HAS_OBJC_ARC - if (__f_) - _Block_release(__f_); -#endif - __f_ = 0; - } + virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { ::new ((void*)__p) __func(__f_); } - virtual void destroy_deallocate() _NOEXCEPT { - _LIBCPP_ASSERT_INTERNAL(false, - "Block pointers are just pointers, so they should always fit into " - "std::function's small buffer optimization. This function should " - "never be invoked."); - } + virtual void destroy() _NOEXCEPT { +# ifndef _LIBCPP_HAS_OBJC_ARC + if (__f_) + _Block_release(__f_); +# endif + __f_ = 0; + } - virtual _Rp operator()(_ArgTypes&& ... __arg) { - return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...); - } + virtual void destroy_deallocate() _NOEXCEPT { + _LIBCPP_ASSERT_INTERNAL( + false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + } -#ifndef _LIBCPP_HAS_NO_RTTI - virtual const void* target(type_info const& __ti) const _NOEXCEPT { - if (__ti == typeid(__func::__block_type)) - return &__f_; - return (const void*)nullptr; - } + virtual _Rp operator()(_ArgTypes&&... __arg) { return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...); } - virtual const std::type_info& target_type() const _NOEXCEPT { - return typeid(__func::__block_type); - } -#endif // _LIBCPP_HAS_NO_RTTI +# ifndef _LIBCPP_HAS_NO_RTTI + virtual const void* target(type_info const& __ti) const _NOEXCEPT { + if (__ti == typeid(__func::__block_type)) + return &__f_; + return (const void*)nullptr; + } + + virtual const std::type_info& target_type() const _NOEXCEPT { return typeid(__func::__block_type); } +# endif // _LIBCPP_HAS_NO_RTTI }; -#endif // _LIBCPP_HAS_EXTENSION_BLOCKS +# endif // _LIBCPP_HAS_EXTENSION_BLOCKS } // namespace __function -template +template class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, - public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> -{ -#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION - typedef __function::__value_func<_Rp(_ArgTypes...)> __func; -#else - typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; -#endif - - __func __f_; - - template , function>, - __invokable<_Fp, _ArgTypes...> - >::value> - struct __callable; - template - struct __callable<_Fp, true> - { - static const bool value = is_void<_Rp>::value || - __is_core_convertible::type, - _Rp>::value; - }; - template - struct __callable<_Fp, false> - { - static const bool value = false; - }; + public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> { +# ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION + typedef __function::__value_func<_Rp(_ArgTypes...)> __func; +# else + typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; +# endif + + __func __f_; + + template , function>, __invokable<_Fp, _ArgTypes...> >::value> + struct __callable; + template + struct __callable<_Fp, true> { + static const bool value = + is_void<_Rp>::value || __is_core_convertible::type, _Rp>::value; + }; + template + struct __callable<_Fp, false> { + static const bool value = false; + }; template using _EnableIfLValueCallable = __enable_if_t<__callable<_Fp&>::value>; -public: - typedef _Rp result_type; - - // construct/copy/destroy: - _LIBCPP_HIDE_FROM_ABI - function() _NOEXCEPT { } - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {} - _LIBCPP_HIDE_FROM_ABI function(const function&); - _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT; - template> - _LIBCPP_HIDE_FROM_ABI function(_Fp); - -#if _LIBCPP_STD_VER <= 14 - template - _LIBCPP_HIDE_FROM_ABI - function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} - template - _LIBCPP_HIDE_FROM_ABI - function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} - template - _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&); - template - _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&); - template> - _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f); -#endif - _LIBCPP_HIDE_FROM_ABI function& operator=(const function&); - _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT; - template>> - _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&); - - _LIBCPP_HIDE_FROM_ABI ~function(); - - // function modifiers: - _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT; +public: + typedef _Rp result_type; + + // construct/copy/destroy: + _LIBCPP_HIDE_FROM_ABI function() _NOEXCEPT {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {} + _LIBCPP_HIDE_FROM_ABI function(const function&); + _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT; + template > + _LIBCPP_HIDE_FROM_ABI function(_Fp); + +# if _LIBCPP_STD_VER <= 14 + template + _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} + template + _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} + template + _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&); + template + _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&); + template > + _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f); +# endif + + _LIBCPP_HIDE_FROM_ABI function& operator=(const function&); + _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT; + template >> + _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&); + + _LIBCPP_HIDE_FROM_ABI ~function(); + + // function modifiers: + _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT; + +# if _LIBCPP_STD_VER <= 14 + template + _LIBCPP_HIDE_FROM_ABI void assign(_Fp&& __f, const _Alloc& __a) { + function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this); + } +# endif -#if _LIBCPP_STD_VER <= 14 - template - _LIBCPP_HIDE_FROM_ABI - void assign(_Fp&& __f, const _Alloc& __a) - {function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this);} -#endif + // function capacity: + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return static_cast(__f_); } - // function capacity: - _LIBCPP_HIDE_FROM_ABI - explicit operator bool() const _NOEXCEPT { - return static_cast(__f_); - } + // deleted overloads close possible hole in the type system + template + bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; +# if _LIBCPP_STD_VER <= 17 + template + bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; +# endif - // deleted overloads close possible hole in the type system - template - bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; -#if _LIBCPP_STD_VER <= 17 - template - bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; -#endif public: - // function invocation: - _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; - -#ifndef _LIBCPP_HAS_NO_RTTI - // function target access: - _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; - template - _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; - template - _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; -#endif // _LIBCPP_HAS_NO_RTTI + // function invocation: + _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; + +# ifndef _LIBCPP_HAS_NO_RTTI + // function target access: + _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; + template + _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; + template + _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; +# endif // _LIBCPP_HAS_NO_RTTI }; -#if _LIBCPP_STD_VER >= 17 -template -function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>; +# if _LIBCPP_STD_VER >= 17 +template +function(_Rp (*)(_Ap...)) -> function<_Rp(_Ap...)>; -template::type> +template ::type> function(_Fp) -> function<_Stripped>; -#endif // _LIBCPP_STD_VER >= 17 +# endif // _LIBCPP_STD_VER >= 17 -template +template function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} -#if _LIBCPP_STD_VER <= 14 -template +# if _LIBCPP_STD_VER <= 14 +template template -function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, - const function& __f) : __f_(__f.__f_) {} -#endif +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {} +# endif template -function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT - : __f_(std::move(__f.__f_)) {} +function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(std::move(__f.__f_)) {} -#if _LIBCPP_STD_VER <= 14 -template +# if _LIBCPP_STD_VER <= 14 +template template -function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, - function&& __f) - : __f_(std::move(__f.__f_)) {} -#endif +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {} +# endif template template function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {} -#if _LIBCPP_STD_VER <= 14 +# if _LIBCPP_STD_VER <= 14 template template -function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, - _Fp __f) - : __f_(std::move(__f), __a) {} -#endif +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, _Fp __f) : __f_(std::move(__f), __a) {} +# endif -template -function<_Rp(_ArgTypes...)>& -function<_Rp(_ArgTypes...)>::operator=(const function& __f) -{ - function(__f).swap(*this); - return *this; +template +function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) { + function(__f).swap(*this); + return *this; } -template -function<_Rp(_ArgTypes...)>& -function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT -{ - __f_ = std::move(__f.__f_); - return *this; +template +function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { + __f_ = std::move(__f.__f_); + return *this; } -template -function<_Rp(_ArgTypes...)>& -function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT -{ - __f_ = nullptr; - return *this; +template +function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { + __f_ = nullptr; + return *this; } -template +template template -function<_Rp(_ArgTypes...)>& -function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) -{ - function(std::forward<_Fp>(__f)).swap(*this); - return *this; +function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) { + function(std::forward<_Fp>(__f)).swap(*this); + return *this; } -template +template function<_Rp(_ArgTypes...)>::~function() {} -template -void -function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT -{ - __f_.swap(__f.__f_); +template +void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { + __f_.swap(__f.__f_); } -template -_Rp -function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const -{ - return __f_(std::forward<_ArgTypes>(__arg)...); +template +_Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { + return __f_(std::forward<_ArgTypes>(__arg)...); } -#ifndef _LIBCPP_HAS_NO_RTTI +# ifndef _LIBCPP_HAS_NO_RTTI -template -const std::type_info& -function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT -{ - return __f_.target_type(); +template +const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { + return __f_.target_type(); } -template +template template -_Tp* -function<_Rp(_ArgTypes...)>::target() _NOEXCEPT -{ - return (_Tp*)(__f_.template target<_Tp>()); +_Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT { + return (_Tp*)(__f_.template target<_Tp>()); } -template +template template -const _Tp* -function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT -{ - return __f_.template target<_Tp>(); +const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT { + return __f_.template target<_Tp>(); } -#endif // _LIBCPP_HAS_NO_RTTI +# endif // _LIBCPP_HAS_NO_RTTI template -inline _LIBCPP_HIDE_FROM_ABI -bool -operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;} +inline _LIBCPP_HIDE_FROM_ABI bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT { + return !__f; +} -#if _LIBCPP_STD_VER <= 17 +# if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_HIDE_FROM_ABI -bool -operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;} +inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT { + return !__f; +} template -inline _LIBCPP_HIDE_FROM_ABI -bool -operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;} +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT { + return (bool)__f; +} template -inline _LIBCPP_HIDE_FROM_ABI -bool -operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;} +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT { + return (bool)__f; +} -#endif // _LIBCPP_STD_VER <= 17 +# endif // _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_HIDE_FROM_ABI -void -swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT -{return __x.swap(__y);} +inline _LIBCPP_HIDE_FROM_ABI void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT { + return __x.swap(__y); +} _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h index c369e39ce003f35663ba90ca08212d334d672c09..ff22055d6915e452a7d12b6c1e13c558914c7c51 100644 --- a/libcxx/include/__functional/hash.h +++ b/libcxx/include/__functional/hash.h @@ -35,133 +35,117 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI -_Size -__loadword(const void* __p) -{ - _Size __r; - std::memcpy(&__r, __p, sizeof(__r)); - return __r; +inline _LIBCPP_HIDE_FROM_ABI _Size __loadword(const void* __p) { + _Size __r; + std::memcpy(&__r, __p, sizeof(__r)); + return __r; } // We use murmur2 when size_t is 32 bits, and cityhash64 when size_t // is 64 bits. This is because cityhash64 uses 64bit x 64bit // multiplication, which can be very slow on 32-bit systems. -template +template struct __murmur2_or_cityhash; template -struct __murmur2_or_cityhash<_Size, 32> -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - _Size operator()(const void* __key, _Size __len) const { - // murmur2 - const _Size __m = 0x5bd1e995; - const _Size __r = 24; - _Size __h = __len; - const unsigned char* __data = static_cast(__key); - for (; __len >= 4; __data += 4, __len -= 4) - { - _Size __k = std::__loadword<_Size>(__data); - __k *= __m; - __k ^= __k >> __r; - __k *= __m; - __h *= __m; - __h ^= __k; - } - switch (__len) - { - case 3: - __h ^= static_cast<_Size>(__data[2] << 16); - _LIBCPP_FALLTHROUGH(); - case 2: - __h ^= static_cast<_Size>(__data[1] << 8); - _LIBCPP_FALLTHROUGH(); - case 1: - __h ^= __data[0]; - __h *= __m; - } - __h ^= __h >> 13; +struct __murmur2_or_cityhash<_Size, 32> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK _Size + operator()(const void* __key, _Size __len) const { + // murmur2 + const _Size __m = 0x5bd1e995; + const _Size __r = 24; + _Size __h = __len; + const unsigned char* __data = static_cast(__key); + for (; __len >= 4; __data += 4, __len -= 4) { + _Size __k = std::__loadword<_Size>(__data); + __k *= __m; + __k ^= __k >> __r; + __k *= __m; __h *= __m; - __h ^= __h >> 15; - return __h; + __h ^= __k; } + switch (__len) { + case 3: + __h ^= static_cast<_Size>(__data[2] << 16); + _LIBCPP_FALLTHROUGH(); + case 2: + __h ^= static_cast<_Size>(__data[1] << 8); + _LIBCPP_FALLTHROUGH(); + case 1: + __h ^= __data[0]; + __h *= __m; + } + __h ^= __h >> 13; + __h *= __m; + __h ^= __h >> 15; + return __h; + } }; template -struct __murmur2_or_cityhash<_Size, 64> -{ +struct __murmur2_or_cityhash<_Size, 64> { // cityhash64 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - _Size operator()(const void* __key, _Size __len) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK _Size + operator()(const void* __key, _Size __len) const { const char* __s = static_cast(__key); if (__len <= 32) { - if (__len <= 16) { + if (__len <= 16) { return __hash_len_0_to_16(__s, __len); - } else { + } else { return __hash_len_17_to_32(__s, __len); - } + } } else if (__len <= 64) { - return __hash_len_33_to_64(__s, __len); + return __hash_len_33_to_64(__s, __len); } // For strings over 64 bytes we hash the end first, and then as we // loop we keep 56 bytes of state: v, w, x, y, and z. _Size __x = std::__loadword<_Size>(__s + __len - 40); - _Size __y = std::__loadword<_Size>(__s + __len - 16) + - std::__loadword<_Size>(__s + __len - 56); - _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len, - std::__loadword<_Size>(__s + __len - 24)); + _Size __y = std::__loadword<_Size>(__s + __len - 16) + std::__loadword<_Size>(__s + __len - 56); + _Size __z = + __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len, std::__loadword<_Size>(__s + __len - 24)); pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z); pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x); - __x = __x * __k1 + std::__loadword<_Size>(__s); + __x = __x * __k1 + std::__loadword<_Size>(__s); // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. __len = (__len - 1) & ~static_cast<_Size>(63); do { - __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1; - __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1; - __x ^= __w.second; - __y += __v.first + std::__loadword<_Size>(__s + 40); - __z = __rotate(__z + __w.first, 33) * __k1; - __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); - __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, - __y + std::__loadword<_Size>(__s + 16)); - std::swap(__z, __x); - __s += 64; - __len -= 64; + __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1; + __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1; + __x ^= __w.second; + __y += __v.first + std::__loadword<_Size>(__s + 40); + __z = __rotate(__z + __w.first, 33) * __k1; + __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); + __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, __y + std::__loadword<_Size>(__s + 16)); + std::swap(__z, __x); + __s += 64; + __len -= 64; } while (__len != 0); - return __hash_len_16( - __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z, - __hash_len_16(__v.second, __w.second) + __x); + return __hash_len_16(__hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z, + __hash_len_16(__v.second, __w.second) + __x); } - private: - // Some primes between 2^63 and 2^64. - static const _Size __k0 = 0xc3a5c85c97cb3127ULL; - static const _Size __k1 = 0xb492b66fbe98f273ULL; - static const _Size __k2 = 0x9ae16a3b2f90404fULL; - static const _Size __k3 = 0xc949d7c7509e6557ULL; +private: + // Some primes between 2^63 and 2^64. + static const _Size __k0 = 0xc3a5c85c97cb3127ULL; + static const _Size __k1 = 0xb492b66fbe98f273ULL; + static const _Size __k2 = 0x9ae16a3b2f90404fULL; + static const _Size __k3 = 0xc949d7c7509e6557ULL; - _LIBCPP_HIDE_FROM_ABI - static _Size __rotate(_Size __val, int __shift) { + _LIBCPP_HIDE_FROM_ABI static _Size __rotate(_Size __val, int __shift) { return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift))); } - _LIBCPP_HIDE_FROM_ABI - static _Size __rotate_by_at_least_1(_Size __val, int __shift) { + _LIBCPP_HIDE_FROM_ABI static _Size __rotate_by_at_least_1(_Size __val, int __shift) { return (__val >> __shift) | (__val << (64 - __shift)); } - _LIBCPP_HIDE_FROM_ABI - static _Size __shift_mix(_Size __val) { - return __val ^ (__val >> 47); - } + _LIBCPP_HIDE_FROM_ABI static _Size __shift_mix(_Size __val) { return __val ^ (__val >> 47); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static _Size __hash_len_16(_Size __u, _Size __v) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size __hash_len_16(_Size __u, _Size __v) { const _Size __mul = 0x9ddfea08eb382d69ULL; - _Size __a = (__u ^ __v) * __mul; + _Size __a = (__u ^ __v) * __mul; __a ^= (__a >> 47); _Size __b = (__v ^ __a) * __mul; __b ^= (__b >> 47); @@ -169,8 +153,8 @@ struct __murmur2_or_cityhash<_Size, 64> return __b; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static _Size __hash_len_0_to_16(const char* __s, _Size __len) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size + __hash_len_0_to_16(const char* __s, _Size __len) { if (__len > 8) { const _Size __a = std::__loadword<_Size>(__s); const _Size __b = std::__loadword<_Size>(__s + __len - 8); @@ -189,32 +173,29 @@ struct __murmur2_or_cityhash<_Size, 64> const unsigned char __a = static_cast(__s[0]); const unsigned char __b = static_cast(__s[__len >> 1]); const unsigned char __c = static_cast(__s[__len - 1]); - const uint32_t __y = static_cast(__a) + - (static_cast(__b) << 8); - const uint32_t __z = __len + (static_cast(__c) << 2); + const uint32_t __y = static_cast(__a) + (static_cast(__b) << 8); + const uint32_t __z = __len + (static_cast(__c) << 2); return __shift_mix(__y * __k2 ^ __z * __k3) * __k2; } return __k2; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static _Size __hash_len_17_to_32(const char *__s, _Size __len) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size + __hash_len_17_to_32(const char* __s, _Size __len) { const _Size __a = std::__loadword<_Size>(__s) * __k1; const _Size __b = std::__loadword<_Size>(__s + 8); const _Size __c = std::__loadword<_Size>(__s + __len - 8) * __k2; const _Size __d = std::__loadword<_Size>(__s + __len - 16) * __k0; - return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d, - __a + __rotate(__b ^ __k3, 20) - __c + __len); + return __hash_len_16( + __rotate(__a - __b, 43) + __rotate(__c, 30) + __d, __a + __rotate(__b ^ __k3, 20) - __c + __len); } // Return a 16-byte hash for 48 bytes. Quick and dirty. // Callers do best to use "random-looking" values for a and b. - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static pair<_Size, _Size> __weak_hash_len_32_with_seeds( - _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) - { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static pair<_Size, _Size> + __weak_hash_len_32_with_seeds(_Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) { __a += __w; - __b = __rotate(__b + __a + __z, 21); + __b = __rotate(__b + __a + __z, 21); const _Size __c = __a; __a += __x; __a += __y; @@ -223,24 +204,22 @@ struct __murmur2_or_cityhash<_Size, 64> } // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static pair<_Size, _Size> __weak_hash_len_32_with_seeds( - const char* __s, _Size __a, _Size __b) - { - return __weak_hash_len_32_with_seeds(std::__loadword<_Size>(__s), - std::__loadword<_Size>(__s + 8), - std::__loadword<_Size>(__s + 16), - std::__loadword<_Size>(__s + 24), - __a, - __b); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static pair<_Size, _Size> + __weak_hash_len_32_with_seeds(const char* __s, _Size __a, _Size __b) { + return __weak_hash_len_32_with_seeds( + std::__loadword<_Size>(__s), + std::__loadword<_Size>(__s + 8), + std::__loadword<_Size>(__s + 16), + std::__loadword<_Size>(__s + 24), + __a, + __b); } // Return an 8-byte hash for 33 to 64 bytes. - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static _Size __hash_len_33_to_64(const char *__s, size_t __len) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size + __hash_len_33_to_64(const char* __s, size_t __len) { _Size __z = std::__loadword<_Size>(__s + 24); - _Size __a = std::__loadword<_Size>(__s) + - (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0; + _Size __a = std::__loadword<_Size>(__s) + (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0; _Size __b = __rotate(__a + __z, 52); _Size __c = __rotate(__a, 37); __a += std::__loadword<_Size>(__s + 8); @@ -248,7 +227,7 @@ struct __murmur2_or_cityhash<_Size, 64> __a += std::__loadword<_Size>(__s + 16); _Size __vf = __a + __z; _Size __vs = __b + __rotate(__a, 31) + __c; - __a = std::__loadword<_Size>(__s + 16) + std::__loadword<_Size>(__s + __len - 32); + __a = std::__loadword<_Size>(__s + 16) + std::__loadword<_Size>(__s + __len - 32); __z += std::__loadword<_Size>(__s + __len - 8); __b = __rotate(__a + __z, 52); __c = __rotate(__a, 37); @@ -257,7 +236,7 @@ struct __murmur2_or_cityhash<_Size, 64> __a += std::__loadword<_Size>(__s + __len - 16); _Size __wf = __a + __z; _Size __ws = __b + __rotate(__a, 31) + __c; - _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0); + _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0); return __shift_mix(__r * __k0 + __vs) * __k2; } }; @@ -266,104 +245,76 @@ template struct __scalar_hash; template -struct __scalar_hash<_Tp, 0> - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - union - { - _Tp __t; - size_t __a; - } __u; - __u.__a = 0; - __u.__t = __v; - return __u.__a; - } +struct __scalar_hash<_Tp, 0> : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + union { + _Tp __t; + size_t __a; + } __u; + __u.__a = 0; + __u.__t = __v; + return __u.__a; + } }; template -struct __scalar_hash<_Tp, 1> - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - union - { - _Tp __t; - size_t __a; - } __u; - __u.__t = __v; - return __u.__a; - } +struct __scalar_hash<_Tp, 1> : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + union { + _Tp __t; + size_t __a; + } __u; + __u.__t = __v; + return __u.__a; + } }; template -struct __scalar_hash<_Tp, 2> - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - union - { - _Tp __t; - struct - { - size_t __a; - size_t __b; - } __s; - } __u; - __u.__t = __v; - return __murmur2_or_cityhash()(&__u, sizeof(__u)); - } +struct __scalar_hash<_Tp, 2> : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + union { + _Tp __t; + struct { + size_t __a; + size_t __b; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } }; template -struct __scalar_hash<_Tp, 3> - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - union - { - _Tp __t; - struct - { - size_t __a; - size_t __b; - size_t __c; - } __s; - } __u; - __u.__t = __v; - return __murmur2_or_cityhash()(&__u, sizeof(__u)); - } +struct __scalar_hash<_Tp, 3> : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + union { + _Tp __t; + struct { + size_t __a; + size_t __b; + size_t __c; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } }; template -struct __scalar_hash<_Tp, 4> - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - union - { - _Tp __t; - struct - { - size_t __a; - size_t __b; - size_t __c; - size_t __d; - } __s; - } __u; - __u.__t = __v; - return __murmur2_or_cityhash()(&__u, sizeof(__u)); - } +struct __scalar_hash<_Tp, 4> : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + union { + _Tp __t; + struct { + size_t __a; + size_t __b; + size_t __c; + size_t __d; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } }; struct _PairT { @@ -371,314 +322,223 @@ struct _PairT { size_t second; }; -_LIBCPP_HIDE_FROM_ABI -inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { - typedef __scalar_hash<_PairT> _HashT; - const _PairT __p = {__lhs, __rhs}; - return _HashT()(__p); +_LIBCPP_HIDE_FROM_ABI inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { + typedef __scalar_hash<_PairT> _HashT; + const _PairT __p = {__lhs, __rhs}; + return _HashT()(__p); } -template -struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> - : public __unary_function<_Tp*, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp* __v) const _NOEXCEPT - { - union - { - _Tp* __t; - size_t __a; - } __u; - __u.__t = __v; - return __murmur2_or_cityhash()(&__u, sizeof(__u)); - } +template +struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> : public __unary_function<_Tp*, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp* __v) const _NOEXCEPT { + union { + _Tp* __t; + size_t __a; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(bool __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(bool __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(char __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(char __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(signed char __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(signed char __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned char __v) const _NOEXCEPT { return static_cast(__v); } }; #ifndef _LIBCPP_HAS_NO_CHAR8_T template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(char8_t __v) const _NOEXCEPT { return static_cast(__v); } }; #endif // !_LIBCPP_HAS_NO_CHAR8_T template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(char16_t __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(char32_t __v) const _NOEXCEPT { return static_cast(__v); } }; #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(wchar_t __v) const _NOEXCEPT { return static_cast(__v); } }; #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(short __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(short __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned short __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(int __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(int __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned int __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(long __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(long __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned long __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __scalar_hash -{ -}; +struct _LIBCPP_TEMPLATE_VIS hash : public __scalar_hash {}; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __scalar_hash -{ -}; +struct _LIBCPP_TEMPLATE_VIS hash : public __scalar_hash {}; #ifndef _LIBCPP_HAS_NO_INT128 template <> -struct _LIBCPP_TEMPLATE_VIS hash<__int128_t> - : public __scalar_hash<__int128_t> -{ -}; +struct _LIBCPP_TEMPLATE_VIS hash<__int128_t> : public __scalar_hash<__int128_t> {}; template <> -struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t> - : public __scalar_hash<__uint128_t> -{ -}; +struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t> : public __scalar_hash<__uint128_t> {}; #endif template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __scalar_hash -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(float __v) const _NOEXCEPT - { - // -0.0 and 0.0 should return same hash - if (__v == 0.0f) - return 0; - return __scalar_hash::operator()(__v); - } +struct _LIBCPP_TEMPLATE_VIS hash : public __scalar_hash { + _LIBCPP_HIDE_FROM_ABI size_t operator()(float __v) const _NOEXCEPT { + // -0.0 and 0.0 should return same hash + if (__v == 0.0f) + return 0; + return __scalar_hash::operator()(__v); + } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __scalar_hash -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(double __v) const _NOEXCEPT - { - // -0.0 and 0.0 should return same hash - if (__v == 0.0) - return 0; - return __scalar_hash::operator()(__v); - } +struct _LIBCPP_TEMPLATE_VIS hash : public __scalar_hash { + _LIBCPP_HIDE_FROM_ABI size_t operator()(double __v) const _NOEXCEPT { + // -0.0 and 0.0 should return same hash + if (__v == 0.0) + return 0; + return __scalar_hash::operator()(__v); + } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __scalar_hash -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(long double __v) const _NOEXCEPT - { - // -0.0 and 0.0 should return same hash - if (__v == 0.0L) - return 0; +struct _LIBCPP_TEMPLATE_VIS hash : public __scalar_hash { + _LIBCPP_HIDE_FROM_ABI size_t operator()(long double __v) const _NOEXCEPT { + // -0.0 and 0.0 should return same hash + if (__v == 0.0L) + return 0; #if defined(__i386__) || (defined(__x86_64__) && defined(__ILP32__)) - // Zero out padding bits - union - { - long double __t; - struct - { - size_t __a; - size_t __b; - size_t __c; - size_t __d; - } __s; - } __u; - __u.__s.__a = 0; - __u.__s.__b = 0; - __u.__s.__c = 0; - __u.__s.__d = 0; - __u.__t = __v; - return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d; + // Zero out padding bits + union { + long double __t; + struct { + size_t __a; + size_t __b; + size_t __c; + size_t __d; + } __s; + } __u; + __u.__s.__a = 0; + __u.__s.__b = 0; + __u.__s.__c = 0; + __u.__s.__d = 0; + __u.__t = __v; + return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d; #elif defined(__x86_64__) - // Zero out padding bits - union - { - long double __t; - struct - { - size_t __a; - size_t __b; - } __s; - } __u; - __u.__s.__a = 0; - __u.__s.__b = 0; - __u.__t = __v; - return __u.__s.__a ^ __u.__s.__b; + // Zero out padding bits + union { + long double __t; + struct { + size_t __a; + size_t __b; + } __s; + } __u; + __u.__s.__a = 0; + __u.__s.__b = 0; + __u.__t = __v; + return __u.__s.__a ^ __u.__s.__b; #else - return __scalar_hash::operator()(__v); + return __scalar_hash::operator()(__v); #endif - } + } }; template ::value> -struct _LIBCPP_TEMPLATE_VIS __enum_hash - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - typedef typename underlying_type<_Tp>::type type; - return hash()(static_cast(__v)); - } +struct _LIBCPP_TEMPLATE_VIS __enum_hash : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + typedef typename underlying_type<_Tp>::type type; + return hash()(static_cast(__v)); + } }; template struct _LIBCPP_TEMPLATE_VIS __enum_hash<_Tp, false> { - __enum_hash() = delete; - __enum_hash(__enum_hash const&) = delete; - __enum_hash& operator=(__enum_hash const&) = delete; + __enum_hash() = delete; + __enum_hash(__enum_hash const&) = delete; + __enum_hash& operator=(__enum_hash const&) = delete; }; template -struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp> -{ -}; +struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp> {}; #if _LIBCPP_STD_VER >= 17 template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(nullptr_t) const _NOEXCEPT { - return 662607004ull; - } +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; } }; #endif #ifndef _LIBCPP_CXX03_LANG template -using __check_hash_requirements _LIBCPP_NODEBUG = integral_constant::value && - is_move_constructible<_Hash>::value && - __invokable_r::value ->; +using __check_hash_requirements _LIBCPP_NODEBUG = + integral_constant::value && is_move_constructible<_Hash>::value && + __invokable_r::value >; template > -using __has_enabled_hash _LIBCPP_NODEBUG = integral_constant::value && - is_default_constructible<_Hash>::value ->; +using __has_enabled_hash _LIBCPP_NODEBUG = + integral_constant::value && is_default_constructible<_Hash>::value >; -#if _LIBCPP_STD_VER >= 17 +# if _LIBCPP_STD_VER >= 17 template using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type; -template -using __enable_hash_helper _LIBCPP_NODEBUG = __enable_hash_helper_imp<_Type, - __enable_if_t<__all<__has_enabled_hash<_Keys>::value...>::value> ->; -#else -template +template +using __enable_hash_helper _LIBCPP_NODEBUG = + __enable_hash_helper_imp<_Type, __enable_if_t<__all<__has_enabled_hash<_Keys>::value...>::value> >; +# else +template using __enable_hash_helper _LIBCPP_NODEBUG = _Type; -#endif +# endif #endif // !_LIBCPP_CXX03_LANG diff --git a/libcxx/include/__functional/identity.h b/libcxx/include/__functional/identity.h index ee92c4130e716b7a1d7d2af513c5d4ea75ac410a..d0e7a7d0769a939c8b8191ad83768f9aa040371b 100644 --- a/libcxx/include/__functional/identity.h +++ b/libcxx/include/__functional/identity.h @@ -38,13 +38,12 @@ struct __is_identity<__identity> : true_type {}; #if _LIBCPP_STD_VER >= 20 struct identity { - template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept - { - return std::forward<_Tp>(__t); - } + template + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept { + return std::forward<_Tp>(__t); + } - using is_transparent = void; + using is_transparent = void; }; template <> diff --git a/libcxx/include/__functional/invoke.h b/libcxx/include/__functional/invoke.h index df2f99fe27d6f6b7cef7672819dffcf0672ce96f..ef4bf25f07759f790a19122e678b6fe5b56c19b7 100644 --- a/libcxx/include/__functional/invoke.h +++ b/libcxx/include/__functional/invoke.h @@ -22,12 +22,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 -template +template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 invoke_result_t<_Fn, _Args...> -invoke(_Fn&& __f, _Args&&... __args) - noexcept(is_nothrow_invocable_v<_Fn, _Args...>) -{ - return std::__invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); +invoke(_Fn&& __f, _Args&&... __args) noexcept(is_nothrow_invocable_v<_Fn, _Args...>) { + return std::__invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); } #endif // _LIBCPP_STD_VER >= 17 @@ -37,17 +35,17 @@ template requires is_invocable_r_v<_Result, _Fn, _Args...> _LIBCPP_HIDE_FROM_ABI constexpr _Result invoke_r(_Fn&& __f, _Args&&... __args) noexcept(is_nothrow_invocable_r_v<_Result, _Fn, _Args...>) { - if constexpr (is_void_v<_Result>) { - static_cast(std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...)); - } else { - // TODO: Use reference_converts_from_temporary_v once implemented - // using _ImplicitInvokeResult = invoke_result_t<_Fn, _Args...>; - // static_assert(!reference_converts_from_temporary_v<_Result, _ImplicitInvokeResult>, - static_assert(true, - "Returning from invoke_r would bind a temporary object to the reference return type, " - "which would result in a dangling reference."); - return std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); - } + if constexpr (is_void_v<_Result>) { + static_cast(std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...)); + } else { + // TODO: Use reference_converts_from_temporary_v once implemented + // using _ImplicitInvokeResult = invoke_result_t<_Fn, _Args...>; + // static_assert(!reference_converts_from_temporary_v<_Result, _ImplicitInvokeResult>, + static_assert(true, + "Returning from invoke_r would bind a temporary object to the reference return type, " + "which would result in a dangling reference."); + return std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); + } } #endif diff --git a/libcxx/include/__functional/is_transparent.h b/libcxx/include/__functional/is_transparent.h index c539a07d696dd12a6c56d1ec7cf963754feeda6e..13fc94f71c6ba1ea846f5bf54f2a0ba9ff9479dd 100644 --- a/libcxx/include/__functional/is_transparent.h +++ b/libcxx/include/__functional/is_transparent.h @@ -26,8 +26,7 @@ template struct __is_transparent : false_type {}; template -struct __is_transparent<_Tp, _Up, __void_t > - : true_type {}; +struct __is_transparent<_Tp, _Up, __void_t > : true_type {}; #endif diff --git a/libcxx/include/__functional/mem_fn.h b/libcxx/include/__functional/mem_fn.h index 77c8136d8785f980e2b55d54d5d1bd345f50b578..349a6ce3a75729ff95e746da767103c5911dde7a 100644 --- a/libcxx/include/__functional/mem_fn.h +++ b/libcxx/include/__functional/mem_fn.h @@ -23,34 +23,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -class __mem_fn : public __weak_result_type<_Tp> -{ +class __mem_fn : public __weak_result_type<_Tp> { public: - // types - typedef _Tp type; + // types + typedef _Tp type; + private: - type __f_; + type __f_; public: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - __mem_fn(type __f) _NOEXCEPT : __f_(__f) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn(type __f) _NOEXCEPT : __f_(__f) {} - // invoke - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + // invoke + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename __invoke_return::type - operator() (_ArgTypes&&... __args) const { - return std::__invoke(__f_, std::forward<_ArgTypes>(__args)...); - } + typename __invoke_return::type + operator()(_ArgTypes&&... __args) const { + return std::__invoke(__f_, std::forward<_ArgTypes>(__args)...); + } }; -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -__mem_fn<_Rp _Tp::*> -mem_fn(_Rp _Tp::* __pm) _NOEXCEPT -{ - return __mem_fn<_Rp _Tp::*>(__pm); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*> mem_fn(_Rp _Tp::*__pm) _NOEXCEPT { + return __mem_fn<_Rp _Tp::*>(__pm); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__functional/mem_fun_ref.h b/libcxx/include/__functional/mem_fun_ref.h index 620d479fdd61ae83f7ae0d3359d1c5dce4b71a62..fe43c46560924d84fdeb5d839435812579191554 100644 --- a/libcxx/include/__functional/mem_fun_ref.h +++ b/libcxx/include/__functional/mem_fun_ref.h @@ -22,149 +22,122 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) -template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t - : public __unary_function<_Tp*, _Sp> -{ - _Sp (_Tp::*__p_)(); +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t : public __unary_function<_Tp*, _Sp> { + _Sp (_Tp::*__p_)(); + public: - _LIBCPP_HIDE_FROM_ABI explicit mem_fun_t(_Sp (_Tp::*__p)()) - : __p_(__p) {} - _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp* __p) const - {return (__p->*__p_)();} + _LIBCPP_HIDE_FROM_ABI explicit mem_fun_t(_Sp (_Tp::*__p)()) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp* __p) const { return (__p->*__p_)(); } }; -template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t - : public __binary_function<_Tp*, _Ap, _Sp> -{ - _Sp (_Tp::*__p_)(_Ap); +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t : public __binary_function<_Tp*, _Ap, _Sp> { + _Sp (_Tp::*__p_)(_Ap); + public: - _LIBCPP_HIDE_FROM_ABI explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap)) - : __p_(__p) {} - _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp* __p, _Ap __x) const - {return (__p->*__p_)(__x);} + _LIBCPP_HIDE_FROM_ABI explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap)) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp* __p, _Ap __x) const { return (__p->*__p_)(__x); } }; -template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -mem_fun_t<_Sp,_Tp> -mem_fun(_Sp (_Tp::*__f)()) - {return mem_fun_t<_Sp,_Tp>(__f);} - -template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -mem_fun1_t<_Sp,_Tp,_Ap> -mem_fun(_Sp (_Tp::*__f)(_Ap)) - {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);} - -template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t - : public __unary_function<_Tp, _Sp> -{ - _Sp (_Tp::*__p_)(); +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI mem_fun_t<_Sp, _Tp> mem_fun(_Sp (_Tp::*__f)()) { + return mem_fun_t<_Sp, _Tp>(__f); +} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI mem_fun1_t<_Sp, _Tp, _Ap> mem_fun(_Sp (_Tp::*__f)(_Ap)) { + return mem_fun1_t<_Sp, _Tp, _Ap>(__f); +} + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t : public __unary_function<_Tp, _Sp> { + _Sp (_Tp::*__p_)(); + public: - _LIBCPP_HIDE_FROM_ABI explicit mem_fun_ref_t(_Sp (_Tp::*__p)()) - : __p_(__p) {} - _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp& __p) const - {return (__p.*__p_)();} + _LIBCPP_HIDE_FROM_ABI explicit mem_fun_ref_t(_Sp (_Tp::*__p)()) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp& __p) const { return (__p.*__p_)(); } }; -template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t - : public __binary_function<_Tp, _Ap, _Sp> -{ - _Sp (_Tp::*__p_)(_Ap); +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t : public __binary_function<_Tp, _Ap, _Sp> { + _Sp (_Tp::*__p_)(_Ap); + public: - _LIBCPP_HIDE_FROM_ABI explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap)) - : __p_(__p) {} - _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp& __p, _Ap __x) const - {return (__p.*__p_)(__x);} + _LIBCPP_HIDE_FROM_ABI explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap)) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp& __p, _Ap __x) const { return (__p.*__p_)(__x); } }; -template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -mem_fun_ref_t<_Sp,_Tp> -mem_fun_ref(_Sp (_Tp::*__f)()) - {return mem_fun_ref_t<_Sp,_Tp>(__f);} +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI mem_fun_ref_t<_Sp, _Tp> mem_fun_ref(_Sp (_Tp::*__f)()) { + return mem_fun_ref_t<_Sp, _Tp>(__f); +} -template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -mem_fun1_ref_t<_Sp,_Tp,_Ap> -mem_fun_ref(_Sp (_Tp::*__f)(_Ap)) - {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI mem_fun1_ref_t<_Sp, _Tp, _Ap> +mem_fun_ref(_Sp (_Tp::*__f)(_Ap)) { + return mem_fun1_ref_t<_Sp, _Tp, _Ap>(__f); +} template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t - : public __unary_function -{ - _Sp (_Tp::*__p_)() const; +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t : public __unary_function { + _Sp (_Tp::*__p_)() const; + public: - _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun_t(_Sp (_Tp::*__p)() const) - : __p_(__p) {} - _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp* __p) const - {return (__p->*__p_)();} + _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun_t(_Sp (_Tp::*__p)() const) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp* __p) const { return (__p->*__p_)(); } }; template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t - : public __binary_function -{ - _Sp (_Tp::*__p_)(_Ap) const; + : public __binary_function { + _Sp (_Tp::*__p_)(_Ap) const; + public: - _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const) - : __p_(__p) {} - _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp* __p, _Ap __x) const - {return (__p->*__p_)(__x);} + _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp* __p, _Ap __x) const { return (__p->*__p_)(__x); } }; template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -const_mem_fun_t<_Sp,_Tp> -mem_fun(_Sp (_Tp::*__f)() const) - {return const_mem_fun_t<_Sp,_Tp>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI const_mem_fun_t<_Sp, _Tp> mem_fun(_Sp (_Tp::*__f)() const) { + return const_mem_fun_t<_Sp, _Tp>(__f); +} template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -const_mem_fun1_t<_Sp,_Tp,_Ap> -mem_fun(_Sp (_Tp::*__f)(_Ap) const) - {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI const_mem_fun1_t<_Sp, _Tp, _Ap> +mem_fun(_Sp (_Tp::*__f)(_Ap) const) { + return const_mem_fun1_t<_Sp, _Tp, _Ap>(__f); +} template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t - : public __unary_function<_Tp, _Sp> -{ - _Sp (_Tp::*__p_)() const; +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t : public __unary_function<_Tp, _Sp> { + _Sp (_Tp::*__p_)() const; + public: - _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const) - : __p_(__p) {} - _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp& __p) const - {return (__p.*__p_)();} + _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp& __p) const { return (__p.*__p_)(); } }; template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t - : public __binary_function<_Tp, _Ap, _Sp> -{ - _Sp (_Tp::*__p_)(_Ap) const; +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t : public __binary_function<_Tp, _Ap, _Sp> { + _Sp (_Tp::*__p_)(_Ap) const; + public: - _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const) - : __p_(__p) {} - _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp& __p, _Ap __x) const - {return (__p.*__p_)(__x);} + _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp& __p, _Ap __x) const { return (__p.*__p_)(__x); } }; template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -const_mem_fun_ref_t<_Sp,_Tp> -mem_fun_ref(_Sp (_Tp::*__f)() const) - {return const_mem_fun_ref_t<_Sp,_Tp>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI const_mem_fun_ref_t<_Sp, _Tp> +mem_fun_ref(_Sp (_Tp::*__f)() const) { + return const_mem_fun_ref_t<_Sp, _Tp>(__f); +} template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -const_mem_fun1_ref_t<_Sp,_Tp,_Ap> -mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const) - {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI const_mem_fun1_ref_t<_Sp, _Tp, _Ap> +mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const) { + return const_mem_fun1_ref_t<_Sp, _Tp, _Ap>(__f); +} #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) diff --git a/libcxx/include/__functional/not_fn.h b/libcxx/include/__functional/not_fn.h index bbd1a8bc35af523af3bd0c47d7364ad39369a3e0..23a491c135d79d2d0d8b81250255a24d991b140c 100644 --- a/libcxx/include/__functional/not_fn.h +++ b/libcxx/include/__functional/not_fn.h @@ -28,26 +28,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 struct __not_fn_op { - template - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX20 auto operator()(_Args&&... __args) const - noexcept(noexcept(!std::invoke(std::forward<_Args>(__args)...))) - -> decltype( !std::invoke(std::forward<_Args>(__args)...)) - { return !std::invoke(std::forward<_Args>(__args)...); } + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto operator()(_Args&&... __args) const + noexcept(noexcept(!std::invoke(std::forward<_Args>(__args)...))) + -> decltype(!std::invoke(std::forward<_Args>(__args)...)) { + return !std::invoke(std::forward<_Args>(__args)...); + } }; template struct __not_fn_t : __perfect_forward<__not_fn_op, _Fn> { - using __perfect_forward<__not_fn_op, _Fn>::__perfect_forward; + using __perfect_forward<__not_fn_op, _Fn>::__perfect_forward; }; -template , _Fn> && - is_move_constructible_v> ->> -_LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX20 auto not_fn(_Fn&& __f) { - return __not_fn_t>(std::forward<_Fn>(__f)); +template , _Fn> && is_move_constructible_v> >> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto not_fn(_Fn&& __f) { + return __not_fn_t>(std::forward<_Fn>(__f)); } #endif // _LIBCPP_STD_VER >= 17 diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h index 23928e9fc22d1c67d79215b5d165d6e009c25b03..7ddc00650f162f11034ace6c86a6cbb93713c81e 100644 --- a/libcxx/include/__functional/operations.h +++ b/libcxx/include/__functional/operations.h @@ -30,13 +30,11 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS plus - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x + __y;} +struct _LIBCPP_TEMPLATE_VIS plus : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x + __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus); @@ -50,15 +48,14 @@ struct __desugars_to<__plus_tag, plus, _Tp, _Up> : true_type {}; #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS plus -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) + std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) + std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS plus { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) + std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) + std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -67,27 +64,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS minus - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x - __y;} +struct _LIBCPP_TEMPLATE_VIS minus : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x - __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS minus -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) - std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) - std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS minus { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) - std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) - std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -96,27 +90,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS multiplies - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x * __y;} +struct _LIBCPP_TEMPLATE_VIS multiplies : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x * __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS multiplies -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) * std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) * std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS multiplies { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) * std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) * std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -125,27 +116,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS divides - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x / __y;} +struct _LIBCPP_TEMPLATE_VIS divides : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x / __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS divides -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) / std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) / std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS divides { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) / std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) / std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -154,27 +142,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS modulus - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x % __y;} +struct _LIBCPP_TEMPLATE_VIS modulus : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x % __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS modulus -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) % std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) % std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS modulus { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) % std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) % std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -183,27 +168,21 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS negate - : __unary_function<_Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - _Tp operator()(const _Tp& __x) const - {return -__x;} +struct _LIBCPP_TEMPLATE_VIS negate : __unary_function<_Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return -__x; } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS negate -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_Tp&& __x) const - noexcept(noexcept(- std::forward<_Tp>(__x))) - -> decltype( - std::forward<_Tp>(__x)) - { return - std::forward<_Tp>(__x); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS negate { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const + noexcept(noexcept(-std::forward<_Tp>(__x))) -> decltype(-std::forward<_Tp>(__x)) { + return -std::forward<_Tp>(__x); + } + typedef void is_transparent; }; #endif @@ -214,51 +193,42 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS bit_and - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x & __y;} +struct _LIBCPP_TEMPLATE_VIS bit_and : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x & __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS bit_and -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) & std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) & std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) & std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS bit_and { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) & std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) & std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif #if _LIBCPP_STD_VER >= 14 template -struct _LIBCPP_TEMPLATE_VIS bit_not - : __unary_function<_Tp, _Tp> -{ - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - _Tp operator()(const _Tp& __x) const - {return ~__x;} +struct _LIBCPP_TEMPLATE_VIS bit_not : __unary_function<_Tp, _Tp> { + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return ~__x; } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_not); template <> -struct _LIBCPP_TEMPLATE_VIS bit_not -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_Tp&& __x) const - noexcept(noexcept(~std::forward<_Tp>(__x))) - -> decltype( ~std::forward<_Tp>(__x)) - { return ~std::forward<_Tp>(__x); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS bit_not { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const + noexcept(noexcept(~std::forward<_Tp>(__x))) -> decltype(~std::forward<_Tp>(__x)) { + return ~std::forward<_Tp>(__x); + } + typedef void is_transparent; }; #endif @@ -267,27 +237,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS bit_or - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x | __y;} +struct _LIBCPP_TEMPLATE_VIS bit_or : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x | __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS bit_or -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) | std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) | std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) | std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS bit_or { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) | std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) | std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) | std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -296,27 +263,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS bit_xor - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x ^ __y;} +struct _LIBCPP_TEMPLATE_VIS bit_xor : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x ^ __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS bit_xor -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) ^ std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) ^ std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) ^ std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS bit_xor { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) ^ std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) ^ std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) ^ std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -327,27 +291,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS equal_to - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x == __y;} +struct _LIBCPP_TEMPLATE_VIS equal_to : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x == __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS equal_to -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) == std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) == std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) == std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS equal_to { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) == std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) == std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) == std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -365,27 +326,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS not_equal_to - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x != __y;} +struct _LIBCPP_TEMPLATE_VIS not_equal_to : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x != __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS not_equal_to -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) != std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) != std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) != std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS not_equal_to { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) != std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) != std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) != std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -394,27 +352,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS less - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x < __y;} +struct _LIBCPP_TEMPLATE_VIS less : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x < __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS less -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) < std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) < std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS less { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) < std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -423,27 +378,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS less_equal - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x <= __y;} +struct _LIBCPP_TEMPLATE_VIS less_equal : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x <= __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS less_equal -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) <= std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) <= std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) <= std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS less_equal { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) <= std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) <= std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) <= std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -452,27 +404,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS greater_equal - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x >= __y;} +struct _LIBCPP_TEMPLATE_VIS greater_equal : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x >= __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS greater_equal -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) >= std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) >= std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) >= std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS greater_equal { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) >= std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) >= std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -481,27 +430,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS greater - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x > __y;} +struct _LIBCPP_TEMPLATE_VIS greater : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x > __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS greater -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) > std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) > std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) > std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS greater { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) > std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) > std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) > std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -512,27 +458,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS logical_and - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x && __y;} +struct _LIBCPP_TEMPLATE_VIS logical_and : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x && __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS logical_and -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) && std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) && std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) && std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS logical_and { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) && std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) && std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) && std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -541,27 +484,21 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS logical_not - : __unary_function<_Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x) const - {return !__x;} +struct _LIBCPP_TEMPLATE_VIS logical_not : __unary_function<_Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const { return !__x; } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS logical_not -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_Tp&& __x) const - noexcept(noexcept(!std::forward<_Tp>(__x))) - -> decltype( !std::forward<_Tp>(__x)) - { return !std::forward<_Tp>(__x); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS logical_not { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const + noexcept(noexcept(!std::forward<_Tp>(__x))) -> decltype(!std::forward<_Tp>(__x)) { + return !std::forward<_Tp>(__x); + } + typedef void is_transparent; }; #endif @@ -570,27 +507,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS logical_or - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x || __y;} +struct _LIBCPP_TEMPLATE_VIS logical_or : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x || __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS logical_or -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(std::forward<_T1>(__t) || std::forward<_T2>(__u))) - -> decltype( std::forward<_T1>(__t) || std::forward<_T2>(__u)) - { return std::forward<_T1>(__t) || std::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS logical_or { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) || std::forward<_T2>(__u))) + -> decltype(std::forward<_T1>(__t) || std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) || std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif diff --git a/libcxx/include/__functional/perfect_forward.h b/libcxx/include/__functional/perfect_forward.h index 2fbb623a7d892be297f29c8878a9b2c1179afa83..74177c789b4ad0fddabbd02d7b1c2b0c3f2bd9c5 100644 --- a/libcxx/include/__functional/perfect_forward.h +++ b/libcxx/include/__functional/perfect_forward.h @@ -40,57 +40,59 @@ private: tuple<_BoundArgs...> __bound_args_; public: - template , _Args&&...> - >> + template , _Args&&...> >> _LIBCPP_HIDE_FROM_ABI explicit constexpr __perfect_forward_impl(_Args&&... __bound_args) - : __bound_args_(std::forward<_Args>(__bound_args)...) {} + : __bound_args_(std::forward<_Args>(__bound_args)...) {} _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl const&) = default; - _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl&&) = default; + _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl&&) = default; _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default; - _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default; + _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default; template >> - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) & - noexcept(noexcept(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...))) - -> decltype( _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)) - { return _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...); } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) & noexcept( + noexcept(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...))) + -> decltype(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)) { + return _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...); + } template >> auto operator()(_Args&&...) & = delete; template >> - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const& - noexcept(noexcept(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...))) - -> decltype( _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)) - { return _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...); } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const& noexcept( + noexcept(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...))) + -> decltype(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)) { + return _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...); + } template >> auto operator()(_Args&&...) const& = delete; template >> - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) && - noexcept(noexcept(_Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...))) - -> decltype( _Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...)) - { return _Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...); } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) && noexcept( + noexcept(_Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...))) + -> decltype(_Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...)) { + return _Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...); + } template >> auto operator()(_Args&&...) && = delete; template >> - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const&& - noexcept(noexcept(_Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...))) - -> decltype( _Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...)) - { return _Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...); } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const&& noexcept( + noexcept(_Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...))) + -> decltype(_Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...)) { + return _Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...); + } template >> auto operator()(_Args&&...) const&& = delete; }; // __perfect_forward implements a perfect-forwarding call wrapper as explained in [func.require]. -template +template using __perfect_forward = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>; #endif // _LIBCPP_STD_VER >= 17 diff --git a/libcxx/include/__functional/pointer_to_binary_function.h b/libcxx/include/__functional/pointer_to_binary_function.h index 88e6db222e07054d1197070eb09b105238affaec..51a7c3fe0fc0fa825d4201cd40df659ecdc07ccb 100644 --- a/libcxx/include/__functional/pointer_to_binary_function.h +++ b/libcxx/include/__functional/pointer_to_binary_function.h @@ -23,21 +23,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function - : public __binary_function<_Arg1, _Arg2, _Result> -{ - _Result (*__f_)(_Arg1, _Arg2); + : public __binary_function<_Arg1, _Arg2, _Result> { + _Result (*__f_)(_Arg1, _Arg2); + public: - _LIBCPP_HIDE_FROM_ABI explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2)) - : __f_(__f) {} - _LIBCPP_HIDE_FROM_ABI _Result operator()(_Arg1 __x, _Arg2 __y) const - {return __f_(__x, __y);} + _LIBCPP_HIDE_FROM_ABI explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2)) : __f_(__f) {} + _LIBCPP_HIDE_FROM_ABI _Result operator()(_Arg1 __x, _Arg2 __y) const { return __f_(__x, __y); } }; template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -pointer_to_binary_function<_Arg1,_Arg2,_Result> -ptr_fun(_Result (*__f)(_Arg1,_Arg2)) - {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI pointer_to_binary_function<_Arg1, _Arg2, _Result> +ptr_fun(_Result (*__f)(_Arg1, _Arg2)) { + return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__f); +} #endif diff --git a/libcxx/include/__functional/pointer_to_unary_function.h b/libcxx/include/__functional/pointer_to_unary_function.h index ee13acfff757afc59a3b891a5fd99875328e9753..0338e76717894f6fc7c7d5a33a746cf73e9d59b4 100644 --- a/libcxx/include/__functional/pointer_to_unary_function.h +++ b/libcxx/include/__functional/pointer_to_unary_function.h @@ -23,21 +23,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function - : public __unary_function<_Arg, _Result> -{ - _Result (*__f_)(_Arg); + : public __unary_function<_Arg, _Result> { + _Result (*__f_)(_Arg); + public: - _LIBCPP_HIDE_FROM_ABI explicit pointer_to_unary_function(_Result (*__f)(_Arg)) - : __f_(__f) {} - _LIBCPP_HIDE_FROM_ABI _Result operator()(_Arg __x) const - {return __f_(__x);} + _LIBCPP_HIDE_FROM_ABI explicit pointer_to_unary_function(_Result (*__f)(_Arg)) : __f_(__f) {} + _LIBCPP_HIDE_FROM_ABI _Result operator()(_Arg __x) const { return __f_(__x); } }; template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI -pointer_to_unary_function<_Arg,_Result> -ptr_fun(_Result (*__f)(_Arg)) - {return pointer_to_unary_function<_Arg,_Result>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI pointer_to_unary_function<_Arg, _Result> +ptr_fun(_Result (*__f)(_Arg)) { + return pointer_to_unary_function<_Arg, _Result>(__f); +} #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) diff --git a/libcxx/include/__functional/ranges_operations.h b/libcxx/include/__functional/ranges_operations.h index 0ed631d8a74bdb9f8173bafa660e6fc8c4117bd7..38b28018049eb79cca7ac1d146eccd918ee662a7 100644 --- a/libcxx/include/__functional/ranges_operations.h +++ b/libcxx/include/__functional/ranges_operations.h @@ -29,8 +29,8 @@ namespace ranges { struct equal_to { template - requires equality_comparable_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const + requires equality_comparable_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(bool(std::forward<_Tp>(__t) == std::forward<_Up>(__u)))) { return std::forward<_Tp>(__t) == std::forward<_Up>(__u); } @@ -40,8 +40,8 @@ struct equal_to { struct not_equal_to { template - requires equality_comparable_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const + requires equality_comparable_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(bool(!(std::forward<_Tp>(__t) == std::forward<_Up>(__u))))) { return !(std::forward<_Tp>(__t) == std::forward<_Up>(__u)); } @@ -51,8 +51,8 @@ struct not_equal_to { struct less { template - requires totally_ordered_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(bool(std::forward<_Tp>(__t) < std::forward<_Up>(__u)))) { return std::forward<_Tp>(__t) < std::forward<_Up>(__u); } @@ -62,8 +62,8 @@ struct less { struct less_equal { template - requires totally_ordered_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(bool(!(std::forward<_Up>(__u) < std::forward<_Tp>(__t))))) { return !(std::forward<_Up>(__u) < std::forward<_Tp>(__t)); } @@ -73,8 +73,8 @@ struct less_equal { struct greater { template - requires totally_ordered_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(bool(std::forward<_Up>(__u) < std::forward<_Tp>(__t)))) { return std::forward<_Up>(__u) < std::forward<_Tp>(__t); } @@ -84,8 +84,8 @@ struct greater { struct greater_equal { template - requires totally_ordered_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(bool(!(std::forward<_Tp>(__t) < std::forward<_Up>(__u))))) { return !(std::forward<_Tp>(__t) < std::forward<_Up>(__u)); } diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h index 3688590d10d182b1a72aa46651a91e1d103c2334..54de06a8879c65f0431d848c85785f320e7b99f4 100644 --- a/libcxx/include/__functional/reference_wrapper.h +++ b/libcxx/include/__functional/reference_wrapper.h @@ -26,44 +26,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> -{ +class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> { public: - // types - typedef _Tp type; + // types + typedef _Tp type; + private: - type* __f_; + type* __f_; - static void __fun(_Tp&) _NOEXCEPT; - static void __fun(_Tp&&) = delete; + static void __fun(_Tp&) _NOEXCEPT; + static void __fun(_Tp&&) = delete; public: - template ::value, decltype(__fun(std::declval<_Up>())) > > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(std::declval<_Up>()))) { - type& __f = static_cast<_Up&&>(__u); - __f_ = std::addressof(__f); - } - - // access - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - operator type&() const _NOEXCEPT {return *__f_;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - type& get() const _NOEXCEPT {return *__f_;} - - // invoke - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename __invoke_of::type - operator() (_ArgTypes&&... __args) const + template < + class _Up, + class = __enable_if_t::value, decltype(__fun(std::declval<_Up>())) > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper(_Up&& __u) + _NOEXCEPT_(noexcept(__fun(std::declval<_Up>()))) { + type& __f = static_cast<_Up&&>(__u); + __f_ = std::addressof(__f); + } + + // access + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator type&() const _NOEXCEPT { return *__f_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; } + + // invoke + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of::type + operator()(_ArgTypes&&... __args) const #if _LIBCPP_STD_VER >= 17 - // Since is_nothrow_invocable requires C++17 LWG3764 is not backported - // to earlier versions. - noexcept(is_nothrow_invocable_v<_Tp&, _ArgTypes...>) + // Since is_nothrow_invocable requires C++17 LWG3764 is not backported + // to earlier versions. + noexcept(is_nothrow_invocable_v<_Tp&, _ArgTypes...>) #endif - { - return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); - } + { + return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); + } }; #if _LIBCPP_STD_VER >= 17 @@ -72,39 +71,31 @@ reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; #endif template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -reference_wrapper<_Tp> -ref(_Tp& __t) _NOEXCEPT -{ - return reference_wrapper<_Tp>(__t); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT { + return reference_wrapper<_Tp>(__t); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -reference_wrapper<_Tp> -ref(reference_wrapper<_Tp> __t) _NOEXCEPT -{ - return __t; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> +ref(reference_wrapper<_Tp> __t) _NOEXCEPT { + return __t; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -reference_wrapper -cref(const _Tp& __t) _NOEXCEPT -{ - return reference_wrapper(__t); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper cref(const _Tp& __t) _NOEXCEPT { + return reference_wrapper(__t); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -reference_wrapper -cref(reference_wrapper<_Tp> __t) _NOEXCEPT -{ - return __t; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper +cref(reference_wrapper<_Tp> __t) _NOEXCEPT { + return __t; } -template void ref(const _Tp&&) = delete; -template void cref(const _Tp&&) = delete; +template +void ref(const _Tp&&) = delete; +template +void cref(const _Tp&&) = delete; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__functional/unary_function.h b/libcxx/include/__functional/unary_function.h index f07cac175a99f0d9a0099014a0edbe5fd221dfc6..69b1bc94220ae6248e747cb7feaab2d8f8df6431 100644 --- a/libcxx/include/__functional/unary_function.h +++ b/libcxx/include/__functional/unary_function.h @@ -20,18 +20,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) template -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 unary_function -{ - typedef _Arg argument_type; - typedef _Result result_type; +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 unary_function { + typedef _Arg argument_type; + typedef _Result result_type; }; #endif // _LIBCPP_STD_VER <= 14 -template struct __unary_function_keep_layout_base { +template +struct __unary_function_keep_layout_base { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) using argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg; - using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; + using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; #endif }; diff --git a/libcxx/include/__functional/unary_negate.h b/libcxx/include/__functional/unary_negate.h index b2eed8e2db3573777a246d11f0ebe02a87fa2c73..d130b7d728a27e82fc0eda3f6c2eef5e2ce6e477 100644 --- a/libcxx/include/__functional/unary_negate.h +++ b/libcxx/include/__functional/unary_negate.h @@ -23,22 +23,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate - : public __unary_function -{ - _Predicate __pred_; + : public __unary_function { + _Predicate __pred_; + public: - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - explicit unary_negate(const _Predicate& __pred) - : __pred_(__pred) {} - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const typename _Predicate::argument_type& __x) const - {return !__pred_(__x);} + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI explicit unary_negate(const _Predicate& __pred) + : __pred_(__pred) {} + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool + operator()(const typename _Predicate::argument_type& __x) const { + return !__pred_(__x); + } }; template -_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI -unary_negate<_Predicate> -not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);} +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI unary_negate<_Predicate> +not1(const _Predicate& __pred) { + return unary_negate<_Predicate>(__pred); +} #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) diff --git a/libcxx/include/__functional/weak_result_type.h b/libcxx/include/__functional/weak_result_type.h index da6fe54bfae72874b962f15da858a3ac0d48c01c..ad7a8395186cd517f8f0a09afda143f96916b4a1 100644 --- a/libcxx/include/__functional/weak_result_type.h +++ b/libcxx/include/__functional/weak_result_type.h @@ -25,268 +25,205 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -struct __has_result_type -{ +struct __has_result_type { private: - template static false_type __test(...); - template static true_type __test(typename _Up::result_type* = 0); + template + static false_type __test(...); + template + static true_type __test(typename _Up::result_type* = 0); + public: - static const bool value = decltype(__test<_Tp>(0))::value; + static const bool value = decltype(__test<_Tp>(0))::value; }; // __weak_result_type template -struct __derives_from_unary_function -{ +struct __derives_from_unary_function { private: - struct __two {char __lx; char __lxx;}; - static __two __test(...); - template - static __unary_function<_Ap, _Rp> - __test(const volatile __unary_function<_Ap, _Rp>*); + struct __two { + char __lx; + char __lxx; + }; + static __two __test(...); + template + static __unary_function<_Ap, _Rp> __test(const volatile __unary_function<_Ap, _Rp>*); public: - static const bool value = !is_same::value; - typedef decltype(__test((_Tp*)0)) type; + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; }; template -struct __derives_from_binary_function -{ +struct __derives_from_binary_function { private: - struct __two {char __lx; char __lxx;}; - static __two __test(...); - template - static __binary_function<_A1, _A2, _Rp> - __test(const volatile __binary_function<_A1, _A2, _Rp>*); + struct __two { + char __lx; + char __lxx; + }; + static __two __test(...); + template + static __binary_function<_A1, _A2, _Rp> __test(const volatile __binary_function<_A1, _A2, _Rp>*); public: - static const bool value = !is_same::value; - typedef decltype(__test((_Tp*)0)) type; + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; }; template ::value> -struct __maybe_derive_from_unary_function // bool is true - : public __derives_from_unary_function<_Tp>::type -{ -}; +struct __maybe_derive_from_unary_function // bool is true + : public __derives_from_unary_function<_Tp>::type {}; template -struct __maybe_derive_from_unary_function<_Tp, false> -{ -}; +struct __maybe_derive_from_unary_function<_Tp, false> {}; template ::value> -struct __maybe_derive_from_binary_function // bool is true - : public __derives_from_binary_function<_Tp>::type -{ -}; +struct __maybe_derive_from_binary_function // bool is true + : public __derives_from_binary_function<_Tp>::type {}; template -struct __maybe_derive_from_binary_function<_Tp, false> -{ -}; +struct __maybe_derive_from_binary_function<_Tp, false> {}; template ::value> struct __weak_result_type_imp // bool is true : public __maybe_derive_from_unary_function<_Tp>, - public __maybe_derive_from_binary_function<_Tp> -{ + public __maybe_derive_from_binary_function<_Tp> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type; #endif }; template struct __weak_result_type_imp<_Tp, false> - : public __maybe_derive_from_unary_function<_Tp>, - public __maybe_derive_from_binary_function<_Tp> -{ -}; + : public __maybe_derive_from_unary_function<_Tp>, public __maybe_derive_from_binary_function<_Tp> {}; template -struct __weak_result_type - : public __weak_result_type_imp<_Tp> -{ -}; +struct __weak_result_type : public __weak_result_type_imp<_Tp> {}; // 0 argument case template -struct __weak_result_type<_Rp ()> -{ +struct __weak_result_type<_Rp()> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; template -struct __weak_result_type<_Rp (&)()> -{ +struct __weak_result_type<_Rp (&)()> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; template -struct __weak_result_type<_Rp (*)()> -{ +struct __weak_result_type<_Rp (*)()> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; // 1 argument case template -struct __weak_result_type<_Rp (_A1)> - : public __unary_function<_A1, _Rp> -{ -}; +struct __weak_result_type<_Rp(_A1)> : public __unary_function<_A1, _Rp> {}; template -struct __weak_result_type<_Rp (&)(_A1)> - : public __unary_function<_A1, _Rp> -{ -}; +struct __weak_result_type<_Rp (&)(_A1)> : public __unary_function<_A1, _Rp> {}; template -struct __weak_result_type<_Rp (*)(_A1)> - : public __unary_function<_A1, _Rp> -{ -}; +struct __weak_result_type<_Rp (*)(_A1)> : public __unary_function<_A1, _Rp> {}; template -struct __weak_result_type<_Rp (_Cp::*)()> - : public __unary_function<_Cp*, _Rp> -{ -}; +struct __weak_result_type<_Rp (_Cp::*)()> : public __unary_function<_Cp*, _Rp> {}; template -struct __weak_result_type<_Rp (_Cp::*)() const> - : public __unary_function -{ -}; +struct __weak_result_type<_Rp (_Cp::*)() const> : public __unary_function {}; template -struct __weak_result_type<_Rp (_Cp::*)() volatile> - : public __unary_function -{ -}; +struct __weak_result_type<_Rp (_Cp::*)() volatile> : public __unary_function {}; template -struct __weak_result_type<_Rp (_Cp::*)() const volatile> - : public __unary_function -{ -}; +struct __weak_result_type<_Rp (_Cp::*)() const volatile> : public __unary_function {}; // 2 argument case template -struct __weak_result_type<_Rp (_A1, _A2)> - : public __binary_function<_A1, _A2, _Rp> -{ -}; +struct __weak_result_type<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; template -struct __weak_result_type<_Rp (*)(_A1, _A2)> - : public __binary_function<_A1, _A2, _Rp> -{ -}; +struct __weak_result_type<_Rp (*)(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; template -struct __weak_result_type<_Rp (&)(_A1, _A2)> - : public __binary_function<_A1, _A2, _Rp> -{ -}; +struct __weak_result_type<_Rp (&)(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; template -struct __weak_result_type<_Rp (_Cp::*)(_A1)> - : public __binary_function<_Cp*, _A1, _Rp> -{ -}; +struct __weak_result_type<_Rp (_Cp::*)(_A1)> : public __binary_function<_Cp*, _A1, _Rp> {}; template -struct __weak_result_type<_Rp (_Cp::*)(_A1) const> - : public __binary_function -{ -}; +struct __weak_result_type<_Rp (_Cp::*)(_A1) const> : public __binary_function {}; template -struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> - : public __binary_function -{ -}; +struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> : public __binary_function {}; template -struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> - : public __binary_function -{ +struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> : public __binary_function { }; // 3 or more arguments -template -struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> -{ +template +struct __weak_result_type<_Rp(_A1, _A2, _A3, _A4...)> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> -{ +template +struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> -{ +template +struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> -{ +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> -{ +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> -{ +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> -{ +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __invoke_return -{ - typedef decltype(std::__invoke(std::declval<_Tp>(), std::declval<_Args>()...)) type; +template +struct __invoke_return { + typedef decltype(std::__invoke(std::declval<_Tp>(), std::declval<_Args>()...)) type; }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__fwd/get.h b/libcxx/include/__fwd/get.h index 1ca7148e3fa2eea8b45cedd7768db0d1c5fb1201..e7261b826953d7ad8d34818439884575e6384a68 100644 --- a/libcxx/include/__fwd/get.h +++ b/libcxx/include/__fwd/get.h @@ -26,70 +26,54 @@ _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_CXX03_LANG -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -typename tuple_element<_Ip, tuple<_Tp...> >::type& +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, tuple<_Tp...> >::type& get(tuple<_Tp...>&) _NOEXCEPT; -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -const typename tuple_element<_Ip, tuple<_Tp...> >::type& +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type& get(const tuple<_Tp...>&) _NOEXCEPT; -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -typename tuple_element<_Ip, tuple<_Tp...> >::type&& +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, tuple<_Tp...> >::type&& get(tuple<_Tp...>&&) _NOEXCEPT; -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -const typename tuple_element<_Ip, tuple<_Tp...> >::type&& +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&& get(const tuple<_Tp...>&&) _NOEXCEPT; #endif //_LIBCPP_CXX03_LANG template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -typename tuple_element<_Ip, pair<_T1, _T2> >::type& +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(pair<_T1, _T2>&) _NOEXCEPT; template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -const typename tuple_element<_Ip, pair<_T1, _T2> >::type& +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(const pair<_T1, _T2>&) _NOEXCEPT; #ifndef _LIBCPP_CXX03_LANG template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&& get(pair<_T1, _T2>&&) _NOEXCEPT; template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& get(const pair<_T1, _T2>&&) _NOEXCEPT; #endif template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp& -get(array<_Tp, _Size>&) _NOEXCEPT; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& get(array<_Tp, _Size>&) _NOEXCEPT; template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp& -get(const array<_Tp, _Size>&) _NOEXCEPT; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& get(const array<_Tp, _Size>&) _NOEXCEPT; #ifndef _LIBCPP_CXX03_LANG template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp&& -get(array<_Tp, _Size>&&) _NOEXCEPT; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& get(array<_Tp, _Size>&&) _NOEXCEPT; template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp&& -get(const array<_Tp, _Size>&&) _NOEXCEPT; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&& get(const array<_Tp, _Size>&&) _NOEXCEPT; #endif #if _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__fwd/span.h b/libcxx/include/__fwd/span.h index e9fa70382f59048e57d0018c3eb05414d1c19df2..8dafa742c19df5a877f73d991ec7afb65970c86b 100644 --- a/libcxx/include/__fwd/span.h +++ b/libcxx/include/__fwd/span.h @@ -26,7 +26,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 inline constexpr size_t dynamic_extent = numeric_limits::max(); -template class span; +template +class span; #endif diff --git a/libcxx/include/__fwd/string_view.h b/libcxx/include/__fwd/string_view.h index 786765ca6a2edfda475a87be060fc39fd1bff9e0..72a64be5b00b54bf02026d8cb708aa8b0a724ce1 100644 --- a/libcxx/include/__fwd/string_view.h +++ b/libcxx/include/__fwd/string_view.h @@ -19,17 +19,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template > +template > class _LIBCPP_TEMPLATE_VIS basic_string_view; -typedef basic_string_view string_view; +typedef basic_string_view string_view; #ifndef _LIBCPP_HAS_NO_CHAR8_T -typedef basic_string_view u8string_view; +typedef basic_string_view u8string_view; #endif typedef basic_string_view u16string_view; typedef basic_string_view u32string_view; #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -typedef basic_string_view wstring_view; +typedef basic_string_view wstring_view; #endif // clang-format off diff --git a/libcxx/include/__fwd/subrange.h b/libcxx/include/__fwd/subrange.h index 24db670575f4e08643df5652428b6121a9d6151a..d09b9b1c5b97bcb579450761dc296cd04159980e 100644 --- a/libcxx/include/__fwd/subrange.h +++ b/libcxx/include/__fwd/subrange.h @@ -17,7 +17,7 @@ #if _LIBCPP_STD_VER >= 20 -#include <__iterator/concepts.h> +# include <__iterator/concepts.h> _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index fa950ac7e9b786b12876b20feb4831b7752e6955..3cee48ef8538c662cc28cdb5ce3014a0a7b43dc9 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -55,7 +55,6 @@ _LIBCPP_PUSH_MACROS #include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template @@ -67,7 +66,7 @@ struct __is_hash_value_type_imp : false_type {}; template struct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {}; -template +template struct __is_hash_value_type : false_type {}; template @@ -76,110 +75,91 @@ struct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_O _LIBCPP_EXPORTED_FROM_ABI size_t __next_prime(size_t __n); template -struct __hash_node_base -{ - typedef typename pointer_traits<_NodePtr>::element_type __node_type; - typedef __hash_node_base __first_node; - typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer; - typedef _NodePtr __node_pointer; +struct __hash_node_base { + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef __hash_node_base __first_node; + typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer; + typedef _NodePtr __node_pointer; #if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB) typedef __node_base_pointer __next_pointer; #else - typedef __conditional_t::value, __node_base_pointer, __node_pointer> __next_pointer; + typedef __conditional_t::value, __node_base_pointer, __node_pointer> __next_pointer; #endif - __next_pointer __next_; + __next_pointer __next_; - _LIBCPP_HIDE_FROM_ABI - __next_pointer __ptr() _NOEXCEPT { - return static_cast<__next_pointer>( - pointer_traits<__node_base_pointer>::pointer_to(*this)); - } + _LIBCPP_HIDE_FROM_ABI __next_pointer __ptr() _NOEXCEPT { + return static_cast<__next_pointer>(pointer_traits<__node_base_pointer>::pointer_to(*this)); + } - _LIBCPP_HIDE_FROM_ABI - __node_pointer __upcast() _NOEXCEPT { - return static_cast<__node_pointer>( - pointer_traits<__node_base_pointer>::pointer_to(*this)); - } + _LIBCPP_HIDE_FROM_ABI __node_pointer __upcast() _NOEXCEPT { + return static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(*this)); + } - _LIBCPP_HIDE_FROM_ABI - size_t __hash() const _NOEXCEPT { - return static_cast<__node_type const&>(*this).__hash_; - } + _LIBCPP_HIDE_FROM_ABI size_t __hash() const _NOEXCEPT { return static_cast<__node_type const&>(*this).__hash_; } - _LIBCPP_HIDE_FROM_ABI __hash_node_base() _NOEXCEPT : __next_(nullptr) {} - _LIBCPP_HIDE_FROM_ABI explicit __hash_node_base(__next_pointer __next) _NOEXCEPT : __next_(__next) {} + _LIBCPP_HIDE_FROM_ABI __hash_node_base() _NOEXCEPT : __next_(nullptr) {} + _LIBCPP_HIDE_FROM_ABI explicit __hash_node_base(__next_pointer __next) _NOEXCEPT : __next_(__next) {} }; template -struct __hash_node - : public __hash_node_base - < - __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > - > -{ - typedef _Tp __node_value_type; - using _Base = __hash_node_base<__rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > >; - using __next_pointer = typename _Base::__next_pointer; +struct __hash_node : public __hash_node_base< __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > > { + typedef _Tp __node_value_type; + using _Base = __hash_node_base<__rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > >; + using __next_pointer = typename _Base::__next_pointer; - size_t __hash_; + size_t __hash_; - // We allow starting the lifetime of nodes without initializing the value held by the node, - // since that is handled by the hash table itself in order to be allocator-aware. + // We allow starting the lifetime of nodes without initializing the value held by the node, + // since that is handled by the hash table itself in order to be allocator-aware. #ifndef _LIBCPP_CXX03_LANG + private: - union { - _Tp __value_; - }; + union { + _Tp __value_; + }; public: - _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; } + _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; } #else + private: - _ALIGNAS_TYPE(_Tp) char __buffer_[sizeof(_Tp)]; + _ALIGNAS_TYPE(_Tp) char __buffer_[sizeof(_Tp)]; public: - _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { - return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); - } + _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); } #endif - _LIBCPP_HIDE_FROM_ABI explicit __hash_node(__next_pointer __next, size_t __hash) : _Base(__next), __hash_(__hash) {} - _LIBCPP_HIDE_FROM_ABI ~__hash_node() {} + _LIBCPP_HIDE_FROM_ABI explicit __hash_node(__next_pointer __next, size_t __hash) : _Base(__next), __hash_(__hash) {} + _LIBCPP_HIDE_FROM_ABI ~__hash_node() {} }; -inline _LIBCPP_HIDE_FROM_ABI -bool -__is_hash_power2(size_t __bc) -{ - return __bc > 2 && !(__bc & (__bc - 1)); -} +inline _LIBCPP_HIDE_FROM_ABI bool __is_hash_power2(size_t __bc) { return __bc > 2 && !(__bc & (__bc - 1)); } -inline _LIBCPP_HIDE_FROM_ABI -size_t -__constrain_hash(size_t __h, size_t __bc) -{ - return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : - (__h < __bc ? __h : __h % __bc); +inline _LIBCPP_HIDE_FROM_ABI size_t __constrain_hash(size_t __h, size_t __bc) { + return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : (__h < __bc ? __h : __h % __bc); } -inline _LIBCPP_HIDE_FROM_ABI -size_t -__next_hash_pow2(size_t __n) -{ - return __n < 2 ? __n : (size_t(1) << (numeric_limits::digits - __libcpp_clz(__n-1))); +inline _LIBCPP_HIDE_FROM_ABI size_t __next_hash_pow2(size_t __n) { + return __n < 2 ? __n : (size_t(1) << (numeric_limits::digits - __libcpp_clz(__n - 1))); } +template +class __hash_table; -template class __hash_table; - -template class _LIBCPP_TEMPLATE_VIS __hash_iterator; -template class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; -template class _LIBCPP_TEMPLATE_VIS __hash_local_iterator; -template class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; -template class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; -template class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_local_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; template struct __hash_key_value_types { @@ -189,73 +169,47 @@ struct __hash_key_value_types { typedef _Tp __container_value_type; static const bool __is_map = false; - _LIBCPP_HIDE_FROM_ABI - static key_type const& __get_key(_Tp const& __v) { - return __v; - } - _LIBCPP_HIDE_FROM_ABI - static __container_value_type const& __get_value(__node_value_type const& __v) { - return __v; - } - _LIBCPP_HIDE_FROM_ABI - static __container_value_type* __get_ptr(__node_value_type& __n) { - return std::addressof(__n); - } - _LIBCPP_HIDE_FROM_ABI - static __container_value_type&& __move(__node_value_type& __v) { - return std::move(__v); - } + _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(_Tp const& __v) { return __v; } + _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __v) { return __v; } + _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { return std::addressof(__n); } + _LIBCPP_HIDE_FROM_ABI static __container_value_type&& __move(__node_value_type& __v) { return std::move(__v); } }; template struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { - typedef _Key key_type; - typedef _Tp mapped_type; - typedef __hash_value_type<_Key, _Tp> __node_value_type; - typedef pair __container_value_type; - typedef __container_value_type __map_value_type; + typedef _Key key_type; + typedef _Tp mapped_type; + typedef __hash_value_type<_Key, _Tp> __node_value_type; + typedef pair __container_value_type; + typedef __container_value_type __map_value_type; static const bool __is_map = true; - _LIBCPP_HIDE_FROM_ABI - static key_type const& __get_key(__container_value_type const& __v) { - return __v.first; - } + _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(__container_value_type const& __v) { return __v.first; } template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI - static __container_value_type const& - __get_value(_Up& __t) { + _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) { return __t.__get_value(); } template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI - static __container_value_type const& - __get_value(_Up& __t) { + _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) { return __t; } - _LIBCPP_HIDE_FROM_ABI - static __container_value_type* __get_ptr(__node_value_type& __n) { + _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { return std::addressof(__n.__get_value()); } - _LIBCPP_HIDE_FROM_ABI - static pair __move(__node_value_type& __v) { - return __v.__move(); - } + _LIBCPP_HIDE_FROM_ABI static pair __move(__node_value_type& __v) { return __v.__move(); } }; -template , - bool = _KVTypes::__is_map> +template , bool = _KVTypes::__is_map> struct __hash_map_pointer_types {}; template struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { - typedef typename _KVTypes::__map_value_type _Mv; - typedef __rebind_pointer_t<_AllocPtr, _Mv> - __map_value_type_pointer; - typedef __rebind_pointer_t<_AllocPtr, const _Mv> - __const_map_value_type_pointer; + typedef typename _KVTypes::__map_value_type _Mv; + typedef __rebind_pointer_t<_AllocPtr, _Mv> __map_value_type_pointer; + typedef __rebind_pointer_t<_AllocPtr, const _Mv> __const_map_value_type_pointer; }; template ::element_type> @@ -263,39 +217,36 @@ struct __hash_node_types; template struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > - : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr> + : public __hash_key_value_types<_Tp>, + __hash_map_pointer_types<_Tp, _VoidPtr> { - typedef __hash_key_value_types<_Tp> __base; + typedef __hash_key_value_types<_Tp> __base; public: typedef ptrdiff_t difference_type; typedef size_t size_type; - typedef __rebind_pointer_t<_NodePtr, void> __void_pointer; + typedef __rebind_pointer_t<_NodePtr, void> __void_pointer; - typedef typename pointer_traits<_NodePtr>::element_type __node_type; - typedef _NodePtr __node_pointer; + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef _NodePtr __node_pointer; - typedef __hash_node_base<__node_pointer> __node_base_type; - typedef __rebind_pointer_t<_NodePtr, __node_base_type> - __node_base_pointer; + typedef __hash_node_base<__node_pointer> __node_base_type; + typedef __rebind_pointer_t<_NodePtr, __node_base_type> __node_base_pointer; - typedef typename __node_base_type::__next_pointer __next_pointer; + typedef typename __node_base_type::__next_pointer __next_pointer; - typedef _Tp __node_value_type; - typedef __rebind_pointer_t<_VoidPtr, __node_value_type> - __node_value_type_pointer; - typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> - __const_node_value_type_pointer; + typedef _Tp __node_value_type; + typedef __rebind_pointer_t<_VoidPtr, __node_value_type> __node_value_type_pointer; + typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> __const_node_value_type_pointer; private: - static_assert(!is_const<__node_type>::value, - "_NodePtr should never be a pointer to const"); - static_assert((is_same::element_type, void>::value), - "_VoidPtr does not point to unqualified void type"); - static_assert((is_same<__rebind_pointer_t<_VoidPtr, __node_type>, - _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); + static_assert(!is_const<__node_type>::value, "_NodePtr should never be a pointer to const"); + static_assert((is_same::element_type, void>::value), + "_VoidPtr does not point to unqualified void type"); + static_assert((is_same<__rebind_pointer_t<_VoidPtr, __node_type>, _NodePtr>::value), + "_VoidPtr does not rebind to _NodePtr."); }; template @@ -309,7 +260,6 @@ struct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __has template struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; - template struct __make_hash_node_types { typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; @@ -318,394 +268,327 @@ struct __make_hash_node_types { }; template -class _LIBCPP_TEMPLATE_VIS __hash_iterator -{ - typedef __hash_node_types<_NodePtr> _NodeTypes; - typedef _NodePtr __node_pointer; - typedef typename _NodeTypes::__next_pointer __next_pointer; +class _LIBCPP_TEMPLATE_VIS __hash_iterator { + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __next_pointer __node_; + __next_pointer __node_; public: - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__node_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef value_type& reference; - typedef typename _NodeTypes::__node_value_type_pointer pointer; + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; - _LIBCPP_HIDE_FROM_ABI __hash_iterator() _NOEXCEPT : __node_(nullptr) { - } + _LIBCPP_HIDE_FROM_ABI __hash_iterator() _NOEXCEPT : __node_(nullptr) {} - _LIBCPP_HIDE_FROM_ABI - reference operator*() const { - return __node_->__upcast()->__get_value(); - } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __node_->__upcast()->__get_value(); } - _LIBCPP_HIDE_FROM_ABI - pointer operator->() const { - return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); - } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { + return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); + } - _LIBCPP_HIDE_FROM_ABI - __hash_iterator& operator++() { - __node_ = __node_->__next_; - return *this; - } + _LIBCPP_HIDE_FROM_ABI __hash_iterator& operator++() { + __node_ = __node_->__next_; + return *this; + } - _LIBCPP_HIDE_FROM_ABI - __hash_iterator operator++(int) - { - __hash_iterator __t(*this); - ++(*this); - return __t; - } + _LIBCPP_HIDE_FROM_ABI __hash_iterator operator++(int) { + __hash_iterator __t(*this); + ++(*this); + return __t; + } - friend _LIBCPP_HIDE_FROM_ABI - bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) - { - return __x.__node_ == __y.__node_; - } - friend _LIBCPP_HIDE_FROM_ABI - bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) - {return !(__x == __y);} + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) { + return !(__x == __y); + } private: - _LIBCPP_HIDE_FROM_ABI - explicit __hash_iterator(__next_pointer __node) _NOEXCEPT - : __node_(__node) - { - } - - template friend class __hash_table; - template friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; - template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; - template friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; + _LIBCPP_HIDE_FROM_ABI explicit __hash_iterator(__next_pointer __node) _NOEXCEPT : __node_(__node) {} + + template + friend class __hash_table; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; }; template -class _LIBCPP_TEMPLATE_VIS __hash_const_iterator -{ - static_assert(!is_const::element_type>::value, ""); - typedef __hash_node_types<_NodePtr> _NodeTypes; - typedef _NodePtr __node_pointer; - typedef typename _NodeTypes::__next_pointer __next_pointer; +class _LIBCPP_TEMPLATE_VIS __hash_const_iterator { + static_assert(!is_const::element_type>::value, ""); + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __next_pointer __node_; + __next_pointer __node_; public: - typedef __hash_iterator<_NodePtr> __non_const_iterator; - - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__node_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef const value_type& reference; - typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + typedef __hash_iterator<_NodePtr> __non_const_iterator; + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; - _LIBCPP_HIDE_FROM_ABI __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { - } + _LIBCPP_HIDE_FROM_ABI __hash_const_iterator() _NOEXCEPT : __node_(nullptr) {} - _LIBCPP_HIDE_FROM_ABI - __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT - : __node_(__x.__node_) - { - } + _LIBCPP_HIDE_FROM_ABI __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_) {} - _LIBCPP_HIDE_FROM_ABI - reference operator*() const { - return __node_->__upcast()->__get_value(); - } - _LIBCPP_HIDE_FROM_ABI - pointer operator->() const { - return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); - } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __node_->__upcast()->__get_value(); } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { + return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); + } - _LIBCPP_HIDE_FROM_ABI - __hash_const_iterator& operator++() { - __node_ = __node_->__next_; - return *this; - } + _LIBCPP_HIDE_FROM_ABI __hash_const_iterator& operator++() { + __node_ = __node_->__next_; + return *this; + } - _LIBCPP_HIDE_FROM_ABI - __hash_const_iterator operator++(int) - { - __hash_const_iterator __t(*this); - ++(*this); - return __t; - } + _LIBCPP_HIDE_FROM_ABI __hash_const_iterator operator++(int) { + __hash_const_iterator __t(*this); + ++(*this); + return __t; + } - friend _LIBCPP_HIDE_FROM_ABI - bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) - { - return __x.__node_ == __y.__node_; - } - friend _LIBCPP_HIDE_FROM_ABI - bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) - {return !(__x == __y);} + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) { + return !(__x == __y); + } private: - _LIBCPP_HIDE_FROM_ABI - explicit __hash_const_iterator(__next_pointer __node) _NOEXCEPT - : __node_(__node) - { - } - - template friend class __hash_table; - template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; - template friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; + _LIBCPP_HIDE_FROM_ABI explicit __hash_const_iterator(__next_pointer __node) _NOEXCEPT : __node_(__node) {} + + template + friend class __hash_table; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; }; template -class _LIBCPP_TEMPLATE_VIS __hash_local_iterator -{ - typedef __hash_node_types<_NodePtr> _NodeTypes; - typedef _NodePtr __node_pointer; - typedef typename _NodeTypes::__next_pointer __next_pointer; +class _LIBCPP_TEMPLATE_VIS __hash_local_iterator { + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __next_pointer __node_; - size_t __bucket_; - size_t __bucket_count_; + __next_pointer __node_; + size_t __bucket_; + size_t __bucket_count_; public: - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__node_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef value_type& reference; - typedef typename _NodeTypes::__node_value_type_pointer pointer; + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; - _LIBCPP_HIDE_FROM_ABI __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { - } + _LIBCPP_HIDE_FROM_ABI __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {} - _LIBCPP_HIDE_FROM_ABI - reference operator*() const { - return __node_->__upcast()->__get_value(); - } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __node_->__upcast()->__get_value(); } - _LIBCPP_HIDE_FROM_ABI - pointer operator->() const { - return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); - } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { + return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); + } - _LIBCPP_HIDE_FROM_ABI - __hash_local_iterator& operator++() { - __node_ = __node_->__next_; - if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) - __node_ = nullptr; - return *this; - } + _LIBCPP_HIDE_FROM_ABI __hash_local_iterator& operator++() { + __node_ = __node_->__next_; + if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) + __node_ = nullptr; + return *this; + } - _LIBCPP_HIDE_FROM_ABI - __hash_local_iterator operator++(int) - { - __hash_local_iterator __t(*this); - ++(*this); - return __t; - } + _LIBCPP_HIDE_FROM_ABI __hash_local_iterator operator++(int) { + __hash_local_iterator __t(*this); + ++(*this); + return __t; + } - friend _LIBCPP_HIDE_FROM_ABI - bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) - { - return __x.__node_ == __y.__node_; - } - friend _LIBCPP_HIDE_FROM_ABI - bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) - {return !(__x == __y);} + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) { + return !(__x == __y); + } private: - _LIBCPP_HIDE_FROM_ABI - explicit __hash_local_iterator(__next_pointer __node, size_t __bucket, - size_t __bucket_count) _NOEXCEPT - : __node_(__node), - __bucket_(__bucket), - __bucket_count_(__bucket_count) - { - if (__node_ != nullptr) - __node_ = __node_->__next_; - } + _LIBCPP_HIDE_FROM_ABI explicit __hash_local_iterator( + __next_pointer __node, size_t __bucket, size_t __bucket_count) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) { + if (__node_ != nullptr) + __node_ = __node_->__next_; + } - template friend class __hash_table; - template friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; - template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; + template + friend class __hash_table; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; }; template -class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator -{ - typedef __hash_node_types<_ConstNodePtr> _NodeTypes; - typedef _ConstNodePtr __node_pointer; - typedef typename _NodeTypes::__next_pointer __next_pointer; - - __next_pointer __node_; - size_t __bucket_; - size_t __bucket_count_; - - typedef pointer_traits<__node_pointer> __pointer_traits; - typedef typename __pointer_traits::element_type __node; - typedef __remove_const_t<__node> __non_const_node; - typedef __rebind_pointer_t<__node_pointer, __non_const_node> - __non_const_node_pointer; -public: - typedef __hash_local_iterator<__non_const_node_pointer> - __non_const_iterator; +class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator { + typedef __hash_node_types<_ConstNodePtr> _NodeTypes; + typedef _ConstNodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__node_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef const value_type& reference; - typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + __next_pointer __node_; + size_t __bucket_; + size_t __bucket_count_; + typedef pointer_traits<__node_pointer> __pointer_traits; + typedef typename __pointer_traits::element_type __node; + typedef __remove_const_t<__node> __non_const_node; + typedef __rebind_pointer_t<__node_pointer, __non_const_node> __non_const_node_pointer; - _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { - } +public: + typedef __hash_local_iterator<__non_const_node_pointer> __non_const_iterator; - _LIBCPP_HIDE_FROM_ABI - __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT - : __node_(__x.__node_), - __bucket_(__x.__bucket_), - __bucket_count_(__x.__bucket_count_) - { - } + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; - _LIBCPP_HIDE_FROM_ABI - reference operator*() const { - return __node_->__upcast()->__get_value(); - } + _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) {} - _LIBCPP_HIDE_FROM_ABI - pointer operator->() const { - return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); - } + _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT + : __node_(__x.__node_), + __bucket_(__x.__bucket_), + __bucket_count_(__x.__bucket_count_) {} - _LIBCPP_HIDE_FROM_ABI - __hash_const_local_iterator& operator++() { - __node_ = __node_->__next_; - if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) - __node_ = nullptr; - return *this; - } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __node_->__upcast()->__get_value(); } - _LIBCPP_HIDE_FROM_ABI - __hash_const_local_iterator operator++(int) - { - __hash_const_local_iterator __t(*this); - ++(*this); - return __t; - } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { + return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); + } - friend _LIBCPP_HIDE_FROM_ABI - bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) - { - return __x.__node_ == __y.__node_; - } - friend _LIBCPP_HIDE_FROM_ABI - bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) - {return !(__x == __y);} + _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator& operator++() { + __node_ = __node_->__next_; + if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) + __node_ = nullptr; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator operator++(int) { + __hash_const_local_iterator __t(*this); + ++(*this); + return __t; + } + + friend _LIBCPP_HIDE_FROM_ABI bool + operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_HIDE_FROM_ABI bool + operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) { + return !(__x == __y); + } private: - _LIBCPP_HIDE_FROM_ABI - explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, - size_t __bucket_count) _NOEXCEPT - : __node_(__node_ptr), - __bucket_(__bucket), - __bucket_count_(__bucket_count) - { - if (__node_ != nullptr) - __node_ = __node_->__next_; - } + _LIBCPP_HIDE_FROM_ABI explicit __hash_const_local_iterator( + __next_pointer __node_ptr, size_t __bucket, size_t __bucket_count) _NOEXCEPT + : __node_(__node_ptr), + __bucket_(__bucket), + __bucket_count_(__bucket_count) { + if (__node_ != nullptr) + __node_ = __node_->__next_; + } - template friend class __hash_table; - template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; + template + friend class __hash_table; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; }; template -class __bucket_list_deallocator -{ - typedef _Alloc allocator_type; - typedef allocator_traits __alloc_traits; - typedef typename __alloc_traits::size_type size_type; +class __bucket_list_deallocator { + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::size_type size_type; + + __compressed_pair __data_; - __compressed_pair __data_; public: - typedef typename __alloc_traits::pointer pointer; - - _LIBCPP_HIDE_FROM_ABI - __bucket_list_deallocator() - _NOEXCEPT_(is_nothrow_default_constructible::value) - : __data_(0, __default_init_tag()) {} - - _LIBCPP_HIDE_FROM_ABI - __bucket_list_deallocator(const allocator_type& __a, size_type __size) - _NOEXCEPT_(is_nothrow_copy_constructible::value) - : __data_(__size, __a) {} - - _LIBCPP_HIDE_FROM_ABI - __bucket_list_deallocator(__bucket_list_deallocator&& __x) - _NOEXCEPT_(is_nothrow_move_constructible::value) - : __data_(std::move(__x.__data_)) - { - __x.size() = 0; - } + typedef typename __alloc_traits::pointer pointer; - _LIBCPP_HIDE_FROM_ABI - size_type& size() _NOEXCEPT {return __data_.first();} - _LIBCPP_HIDE_FROM_ABI - size_type size() const _NOEXCEPT {return __data_.first();} + _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator() _NOEXCEPT_(is_nothrow_default_constructible::value) + : __data_(0, __default_init_tag()) {} - _LIBCPP_HIDE_FROM_ABI - allocator_type& __alloc() _NOEXCEPT {return __data_.second();} - _LIBCPP_HIDE_FROM_ABI - const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();} + _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(const allocator_type& __a, size_type __size) + _NOEXCEPT_(is_nothrow_copy_constructible::value) + : __data_(__size, __a) {} - _LIBCPP_HIDE_FROM_ABI - void operator()(pointer __p) _NOEXCEPT - { - __alloc_traits::deallocate(__alloc(), __p, size()); - } + _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(__bucket_list_deallocator&& __x) + _NOEXCEPT_(is_nothrow_move_constructible::value) + : __data_(std::move(__x.__data_)) { + __x.size() = 0; + } + + _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __data_.first(); } + _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __data_.first(); } + + _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __data_.second(); } + _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __data_.second(); } + + _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT { __alloc_traits::deallocate(__alloc(), __p, size()); } }; -template class __hash_map_node_destructor; +template +class __hash_map_node_destructor; template -class __hash_node_destructor -{ - typedef _Alloc allocator_type; - typedef allocator_traits __alloc_traits; +class __hash_node_destructor { + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; public: - typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::pointer pointer; + private: - typedef __hash_node_types _NodeTypes; + typedef __hash_node_types _NodeTypes; - allocator_type& __na_; + allocator_type& __na_; public: - bool __value_constructed; - - _LIBCPP_HIDE_FROM_ABI __hash_node_destructor(__hash_node_destructor const&) = default; - _LIBCPP_HIDE_FROM_ABI __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; + bool __value_constructed; + _LIBCPP_HIDE_FROM_ABI __hash_node_destructor(__hash_node_destructor const&) = default; + _LIBCPP_HIDE_FROM_ABI __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; - _LIBCPP_HIDE_FROM_ABI - explicit __hash_node_destructor(allocator_type& __na, - bool __constructed = false) _NOEXCEPT - : __na_(__na), - __value_constructed(__constructed) - {} + _LIBCPP_HIDE_FROM_ABI explicit __hash_node_destructor(allocator_type& __na, bool __constructed = false) _NOEXCEPT + : __na_(__na), + __value_constructed(__constructed) {} - _LIBCPP_HIDE_FROM_ABI - void operator()(pointer __p) _NOEXCEPT - { - if (__value_constructed) { - __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__get_value())); - std::__destroy_at(std::addressof(*__p)); - } - if (__p) - __alloc_traits::deallocate(__na_, __p, 1); + _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT { + if (__value_constructed) { + __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__get_value())); + std::__destroy_at(std::addressof(*__p)); } + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } - template friend class __hash_map_node_destructor; + template + friend class __hash_map_node_destructor; }; #if _LIBCPP_STD_VER >= 17 @@ -713,33 +596,30 @@ template struct __generic_container_node_destructor; template -struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> - : __hash_node_destructor<_Alloc> -{ - using __hash_node_destructor<_Alloc>::__hash_node_destructor; +struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> : __hash_node_destructor<_Alloc> { + using __hash_node_destructor<_Alloc>::__hash_node_destructor; }; #endif template struct __enforce_unordered_container_requirements { #ifndef _LIBCPP_CXX03_LANG - static_assert(__check_hash_requirements<_Key, _Hash>::value, - "the specified hash does not meet the Hash requirements"); - static_assert(is_copy_constructible<_Equal>::value, - "the specified comparator is required to be copy constructible"); + static_assert(__check_hash_requirements<_Key, _Hash>::value, + "the specified hash does not meet the Hash requirements"); + static_assert(is_copy_constructible<_Equal>::value, "the specified comparator is required to be copy constructible"); #endif - typedef int type; + typedef int type; }; template #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, - "the specified comparator type does not provide a viable const call operator") - _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, - "the specified hash functor does not provide a viable const call operator") +_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, + "the specified comparator type does not provide a viable const call operator") +_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, + "the specified hash functor does not provide a viable const call operator") #endif -typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type -__diagnose_unordered_container_requirements(int); + typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type + __diagnose_unordered_container_requirements(int); // This dummy overload is used so that the compiler won't emit a spurious // "no matching function for call to __diagnose_unordered_xxx" diagnostic @@ -748,890 +628,668 @@ template int __diagnose_unordered_container_requirements(void*); template -class __hash_table -{ +class __hash_table { public: - typedef _Tp value_type; - typedef _Hash hasher; - typedef _Equal key_equal; - typedef _Alloc allocator_type; + typedef _Tp value_type; + typedef _Hash hasher; + typedef _Equal key_equal; + typedef _Alloc allocator_type; private: - typedef allocator_traits __alloc_traits; - typedef typename - __make_hash_node_types::type - _NodeTypes; -public: + typedef allocator_traits __alloc_traits; + typedef typename __make_hash_node_types::type _NodeTypes; - typedef typename _NodeTypes::__node_value_type __node_value_type; - typedef typename _NodeTypes::__container_value_type __container_value_type; - typedef typename _NodeTypes::key_type key_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; +public: + typedef typename _NodeTypes::__node_value_type __node_value_type; + typedef typename _NodeTypes::__container_value_type __container_value_type; + typedef typename _NodeTypes::key_type key_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; #ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE - typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::size_type size_type; #else - typedef typename _NodeTypes::size_type size_type; + typedef typename _NodeTypes::size_type size_type; #endif - typedef typename _NodeTypes::difference_type difference_type; + typedef typename _NodeTypes::difference_type difference_type; + public: - // Create __node - - typedef typename _NodeTypes::__node_type __node; - typedef __rebind_alloc<__alloc_traits, __node> __node_allocator; - typedef allocator_traits<__node_allocator> __node_traits; - typedef typename _NodeTypes::__void_pointer __void_pointer; - typedef typename _NodeTypes::__node_pointer __node_pointer; - typedef typename _NodeTypes::__node_pointer __node_const_pointer; - typedef typename _NodeTypes::__node_base_type __first_node; - typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; - typedef typename _NodeTypes::__next_pointer __next_pointer; + // Create __node + + typedef typename _NodeTypes::__node_type __node; + typedef __rebind_alloc<__alloc_traits, __node> __node_allocator; + typedef allocator_traits<__node_allocator> __node_traits; + typedef typename _NodeTypes::__void_pointer __void_pointer; + typedef typename _NodeTypes::__node_pointer __node_pointer; + typedef typename _NodeTypes::__node_pointer __node_const_pointer; + typedef typename _NodeTypes::__node_base_type __first_node; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; private: - // check for sane allocator pointer rebinding semantics. Rebinding the - // allocator for a new pointer type should be exactly the same as rebinding - // the pointer using 'pointer_traits'. - static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), - "Allocator does not rebind pointers in a sane manner."); - typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator; - typedef allocator_traits<__node_base_allocator> __node_base_traits; - static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), - "Allocator does not rebind pointers in a sane manner."); + // check for sane allocator pointer rebinding semantics. Rebinding the + // allocator for a new pointer type should be exactly the same as rebinding + // the pointer using 'pointer_traits'. + static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator; + typedef allocator_traits<__node_base_allocator> __node_base_traits; + static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); private: + typedef __rebind_alloc<__node_traits, __next_pointer> __pointer_allocator; + typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; + typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; + typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; + typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; + + // --- Member data begin --- + __bucket_list __bucket_list_; + __compressed_pair<__first_node, __node_allocator> __p1_; + __compressed_pair __p2_; + __compressed_pair __p3_; + // --- Member data end --- + + _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __p2_.first(); } - typedef __rebind_alloc<__node_traits, __next_pointer> __pointer_allocator; - typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; - typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; - typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; - typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; - - // --- Member data begin --- - __bucket_list __bucket_list_; - __compressed_pair<__first_node, __node_allocator> __p1_; - __compressed_pair __p2_; - __compressed_pair __p3_; - // --- Member data end --- - - _LIBCPP_HIDE_FROM_ABI - size_type& size() _NOEXCEPT {return __p2_.first();} public: - _LIBCPP_HIDE_FROM_ABI - size_type size() const _NOEXCEPT {return __p2_.first();} - - _LIBCPP_HIDE_FROM_ABI - hasher& hash_function() _NOEXCEPT {return __p2_.second();} - _LIBCPP_HIDE_FROM_ABI - const hasher& hash_function() const _NOEXCEPT {return __p2_.second();} - - _LIBCPP_HIDE_FROM_ABI - float& max_load_factor() _NOEXCEPT {return __p3_.first();} - _LIBCPP_HIDE_FROM_ABI - float max_load_factor() const _NOEXCEPT {return __p3_.first();} - - _LIBCPP_HIDE_FROM_ABI - key_equal& key_eq() _NOEXCEPT {return __p3_.second();} - _LIBCPP_HIDE_FROM_ABI - const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();} - - _LIBCPP_HIDE_FROM_ABI - __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();} - _LIBCPP_HIDE_FROM_ABI - const __node_allocator& __node_alloc() const _NOEXCEPT - {return __p1_.second();} + _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __p2_.first(); } + + _LIBCPP_HIDE_FROM_ABI hasher& hash_function() _NOEXCEPT { return __p2_.second(); } + _LIBCPP_HIDE_FROM_ABI const hasher& hash_function() const _NOEXCEPT { return __p2_.second(); } + + _LIBCPP_HIDE_FROM_ABI float& max_load_factor() _NOEXCEPT { return __p3_.first(); } + _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __p3_.first(); } + + _LIBCPP_HIDE_FROM_ABI key_equal& key_eq() _NOEXCEPT { return __p3_.second(); } + _LIBCPP_HIDE_FROM_ABI const key_equal& key_eq() const _NOEXCEPT { return __p3_.second(); } + + _LIBCPP_HIDE_FROM_ABI __node_allocator& __node_alloc() _NOEXCEPT { return __p1_.second(); } + _LIBCPP_HIDE_FROM_ABI const __node_allocator& __node_alloc() const _NOEXCEPT { return __p1_.second(); } public: - typedef __hash_iterator<__node_pointer> iterator; - typedef __hash_const_iterator<__node_pointer> const_iterator; - typedef __hash_local_iterator<__node_pointer> local_iterator; - typedef __hash_const_local_iterator<__node_pointer> const_local_iterator; - - _LIBCPP_HIDE_FROM_ABI - __hash_table() - _NOEXCEPT_( - is_nothrow_default_constructible<__bucket_list>::value && - is_nothrow_default_constructible<__first_node>::value && - is_nothrow_default_constructible<__node_allocator>::value && - is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value); - _LIBCPP_HIDE_FROM_ABI - __hash_table(const hasher& __hf, const key_equal& __eql); - _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql, - const allocator_type& __a); - _LIBCPP_HIDE_FROM_ABI explicit __hash_table(const allocator_type& __a); - _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u); - _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u, const allocator_type& __a); - _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u) - _NOEXCEPT_( - is_nothrow_move_constructible<__bucket_list>::value && - is_nothrow_move_constructible<__first_node>::value && - is_nothrow_move_constructible<__node_allocator>::value && - is_nothrow_move_constructible::value && - is_nothrow_move_constructible::value); - _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a); - _LIBCPP_HIDE_FROM_ABI ~__hash_table(); - - _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u); - _LIBCPP_HIDE_FROM_ABI - __hash_table& operator=(__hash_table&& __u) - _NOEXCEPT_( - __node_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<__node_allocator>::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value); - template - _LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last); - template - _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last); - - _LIBCPP_HIDE_FROM_ABI - size_type max_size() const _NOEXCEPT - { - return std::min( - __node_traits::max_size(__node_alloc()), - numeric_limits::max() - ); - } + typedef __hash_iterator<__node_pointer> iterator; + typedef __hash_const_iterator<__node_pointer> const_iterator; + typedef __hash_local_iterator<__node_pointer> local_iterator; + typedef __hash_const_local_iterator<__node_pointer> const_local_iterator; + + _LIBCPP_HIDE_FROM_ABI __hash_table() _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value&& is_nothrow_default_constructible<__first_node>::value&& + is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_default_constructible::value&& + is_nothrow_default_constructible::value); + _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql); + _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI explicit __hash_table(const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u); + _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u) _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value&& is_nothrow_move_constructible<__first_node>::value&& + is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible::value&& + is_nothrow_move_constructible::value); + _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI ~__hash_table(); + + _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u); + _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(__hash_table&& __u) + _NOEXCEPT_(__node_traits::propagate_on_container_move_assignment::value&& + is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable::value&& + is_nothrow_move_assignable::value); + template + _LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last); + template + _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last); + + _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + return std::min(__node_traits::max_size(__node_alloc()), numeric_limits::max()); + } private: - _LIBCPP_HIDE_FROM_ABI - __next_pointer __node_insert_multi_prepare(size_t __cp_hash, - value_type& __cp_val); - _LIBCPP_HIDE_FROM_ABI - void __node_insert_multi_perform(__node_pointer __cp, - __next_pointer __pn) _NOEXCEPT; - - _LIBCPP_HIDE_FROM_ABI - __next_pointer __node_insert_unique_prepare(size_t __nd_hash, - value_type& __nd_val); - _LIBCPP_HIDE_FROM_ABI - void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI __next_pointer __node_insert_multi_prepare(size_t __cp_hash, value_type& __cp_val); + _LIBCPP_HIDE_FROM_ABI void __node_insert_multi_perform(__node_pointer __cp, __next_pointer __pn) _NOEXCEPT; + + _LIBCPP_HIDE_FROM_ABI __next_pointer __node_insert_unique_prepare(size_t __nd_hash, value_type& __nd_val); + _LIBCPP_HIDE_FROM_ABI void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT; public: - _LIBCPP_HIDE_FROM_ABI - pair __node_insert_unique(__node_pointer __nd); - _LIBCPP_HIDE_FROM_ABI - iterator __node_insert_multi(__node_pointer __nd); - _LIBCPP_HIDE_FROM_ABI - iterator __node_insert_multi(const_iterator __p, - __node_pointer __nd); - - template - _LIBCPP_HIDE_FROM_ABI - pair __emplace_unique_key_args(_Key const& __k, _Args&&... __args); - - template - _LIBCPP_HIDE_FROM_ABI - pair __emplace_unique_impl(_Args&&... __args); - - template - _LIBCPP_HIDE_FROM_ABI - pair __emplace_unique(_Pp&& __x) { - return __emplace_unique_extract_key(std::forward<_Pp>(__x), - __can_extract_key<_Pp, key_type>()); - } + _LIBCPP_HIDE_FROM_ABI pair __node_insert_unique(__node_pointer __nd); + _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(__node_pointer __nd); + _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); - template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI - pair - __emplace_unique(_First&& __f, _Second&& __s) { - return __emplace_unique_key_args(__f, std::forward<_First>(__f), - std::forward<_Second>(__s)); - } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique_key_args(_Key const& __k, _Args&&... __args); - template - _LIBCPP_HIDE_FROM_ABI - pair __emplace_unique(_Args&&... __args) { - return __emplace_unique_impl(std::forward<_Args>(__args)...); - } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique_impl(_Args&&... __args); - template - _LIBCPP_HIDE_FROM_ABI - pair - __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { - return __emplace_unique_impl(std::forward<_Pp>(__x)); - } - template - _LIBCPP_HIDE_FROM_ABI - pair - __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { - return __emplace_unique_key_args(__x, std::forward<_Pp>(__x)); - } - template - _LIBCPP_HIDE_FROM_ABI - pair - __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { - return __emplace_unique_key_args(__x.first, std::forward<_Pp>(__x)); - } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(std::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>()); + } - template - _LIBCPP_HIDE_FROM_ABI - iterator __emplace_multi(_Args&&... __args); - template - _LIBCPP_HIDE_FROM_ABI - iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique(_First&& __f, _Second&& __s) { + return __emplace_unique_key_args(__f, std::forward<_First>(__f), std::forward<_Second>(__s)); + } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(std::forward<_Args>(__args)...); + } - _LIBCPP_HIDE_FROM_ABI - pair - __insert_unique(__container_value_type&& __x) { - return __emplace_unique_key_args(_NodeTypes::__get_key(__x), std::move(__x)); - } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(std::forward<_Pp>(__x)); + } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, std::forward<_Pp>(__x)); + } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, std::forward<_Pp>(__x)); + } - template ::value> > - _LIBCPP_HIDE_FROM_ABI - pair __insert_unique(_Pp&& __x) { - return __emplace_unique(std::forward<_Pp>(__x)); - } + template + _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args); + template + _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); - template - _LIBCPP_HIDE_FROM_ABI - iterator __insert_multi(_Pp&& __x) { - return __emplace_multi(std::forward<_Pp>(__x)); - } + _LIBCPP_HIDE_FROM_ABI pair __insert_unique(__container_value_type&& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), std::move(__x)); + } - template - _LIBCPP_HIDE_FROM_ABI - iterator __insert_multi(const_iterator __p, _Pp&& __x) { - return __emplace_hint_multi(__p, std::forward<_Pp>(__x)); - } + template ::value> > + _LIBCPP_HIDE_FROM_ABI pair __insert_unique(_Pp&& __x) { + return __emplace_unique(std::forward<_Pp>(__x)); + } - _LIBCPP_HIDE_FROM_ABI - pair __insert_unique(const __container_value_type& __x) { - return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); - } + template + _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(_Pp&& __x) { + return __emplace_multi(std::forward<_Pp>(__x)); + } + + template + _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(const_iterator __p, _Pp&& __x) { + return __emplace_hint_multi(__p, std::forward<_Pp>(__x)); + } + + _LIBCPP_HIDE_FROM_ABI pair __insert_unique(const __container_value_type& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); + } #if _LIBCPP_STD_VER >= 17 - template - _LIBCPP_HIDE_FROM_ABI - _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); - template - _LIBCPP_HIDE_FROM_ABI - iterator __node_handle_insert_unique(const_iterator __hint, - _NodeHandle&& __nh); - template - _LIBCPP_HIDE_FROM_ABI - void __node_handle_merge_unique(_Table& __source); - - template - _LIBCPP_HIDE_FROM_ABI - iterator __node_handle_insert_multi(_NodeHandle&& __nh); - template - _LIBCPP_HIDE_FROM_ABI - iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); - template - _LIBCPP_HIDE_FROM_ABI - void __node_handle_merge_multi(_Table& __source); - - template - _LIBCPP_HIDE_FROM_ABI - _NodeHandle __node_handle_extract(key_type const& __key); - template - _LIBCPP_HIDE_FROM_ABI - _NodeHandle __node_handle_extract(const_iterator __it); + template + _LIBCPP_HIDE_FROM_ABI _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); + template + _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_unique(const_iterator __hint, _NodeHandle&& __nh); + template + _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_unique(_Table& __source); + + template + _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(_NodeHandle&& __nh); + template + _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); + template + _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(_Table& __source); + + template + _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(key_type const& __key); + template + _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(const_iterator __it); #endif - _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI void __rehash_unique(size_type __n) { __rehash(__n); } - _LIBCPP_HIDE_FROM_ABI void __rehash_multi(size_type __n) { __rehash(__n); } - _LIBCPP_HIDE_FROM_ABI void __reserve_unique(size_type __n) - { - __rehash_unique(static_cast(std::ceil(__n / max_load_factor()))); - } - _LIBCPP_HIDE_FROM_ABI void __reserve_multi(size_type __n) - { - __rehash_multi(static_cast(std::ceil(__n / max_load_factor()))); - } + _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI void __rehash_unique(size_type __n) { __rehash(__n); } + _LIBCPP_HIDE_FROM_ABI void __rehash_multi(size_type __n) { __rehash(__n); } + _LIBCPP_HIDE_FROM_ABI void __reserve_unique(size_type __n) { + __rehash_unique(static_cast(std::ceil(__n / max_load_factor()))); + } + _LIBCPP_HIDE_FROM_ABI void __reserve_multi(size_type __n) { + __rehash_multi(static_cast(std::ceil(__n / max_load_factor()))); + } - _LIBCPP_HIDE_FROM_ABI - size_type bucket_count() const _NOEXCEPT - { - return __bucket_list_.get_deleter().size(); - } + _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __bucket_list_.get_deleter().size(); } - _LIBCPP_HIDE_FROM_ABI - iterator begin() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI - iterator end() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI - const_iterator begin() const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI - const_iterator end() const _NOEXCEPT; - - template - _LIBCPP_HIDE_FROM_ABI - size_type bucket(const _Key& __k) const - { - _LIBCPP_ASSERT_UNCATEGORIZED(bucket_count() > 0, - "unordered container::bucket(key) called when bucket_count() == 0"); - return std::__constrain_hash(hash_function()(__k), bucket_count()); - } + _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT; + + template + _LIBCPP_HIDE_FROM_ABI size_type bucket(const _Key& __k) const { + _LIBCPP_ASSERT_UNCATEGORIZED( + bucket_count() > 0, "unordered container::bucket(key) called when bucket_count() == 0"); + return std::__constrain_hash(hash_function()(__k), bucket_count()); + } - template - _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __x); - template - _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __x) const; - - typedef __hash_node_destructor<__node_allocator> _Dp; - typedef unique_ptr<__node, _Dp> __node_holder; - - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last); - template - _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k); - template - _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k); - _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT; - - template - _LIBCPP_HIDE_FROM_ABI - size_type __count_unique(const _Key& __k) const; - template - _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const; - - template - _LIBCPP_HIDE_FROM_ABI pair - __equal_range_unique(const _Key& __k); - template - _LIBCPP_HIDE_FROM_ABI pair - __equal_range_unique(const _Key& __k) const; - - template - _LIBCPP_HIDE_FROM_ABI pair - __equal_range_multi(const _Key& __k); - template - _LIBCPP_HIDE_FROM_ABI pair - __equal_range_multi(const _Key& __k) const; - - _LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u) + template + _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __x); + template + _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __x) const; + + typedef __hash_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + + _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); + _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last); + template + _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k); + template + _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k); + _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT; + + template + _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const; + template + _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const; + + template + _LIBCPP_HIDE_FROM_ABI pair __equal_range_unique(const _Key& __k); + template + _LIBCPP_HIDE_FROM_ABI pair __equal_range_unique(const _Key& __k) const; + + template + _LIBCPP_HIDE_FROM_ABI pair __equal_range_multi(const _Key& __k); + template + _LIBCPP_HIDE_FROM_ABI pair __equal_range_multi(const _Key& __k) const; + + _LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u) #if _LIBCPP_STD_VER <= 11 - _NOEXCEPT_( - __is_nothrow_swappable::value && __is_nothrow_swappable::value - && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value - || __is_nothrow_swappable<__pointer_allocator>::value) - && (!__node_traits::propagate_on_container_swap::value - || __is_nothrow_swappable<__node_allocator>::value) - ); + _NOEXCEPT_(__is_nothrow_swappable::value&& __is_nothrow_swappable::value && + (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value || + __is_nothrow_swappable<__pointer_allocator>::value) && + (!__node_traits::propagate_on_container_swap::value || + __is_nothrow_swappable<__node_allocator>::value)); #else - _NOEXCEPT_(__is_nothrow_swappable::value && __is_nothrow_swappable::value); + _NOEXCEPT_(__is_nothrow_swappable::value&& __is_nothrow_swappable::value); #endif - _LIBCPP_HIDE_FROM_ABI - size_type max_bucket_count() const _NOEXCEPT - {return max_size(); } - _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const; - _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT - { - size_type __bc = bucket_count(); - return __bc != 0 ? (float)size() / __bc : 0.f; - } - _LIBCPP_HIDE_FROM_ABI void max_load_factor(float __mlf) _NOEXCEPT - { - _LIBCPP_ASSERT_UNCATEGORIZED(__mlf > 0, - "unordered container::max_load_factor(lf) called with lf <= 0"); - max_load_factor() = std::max(__mlf, load_factor()); - } + _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return max_size(); } + _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const; + _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { + size_type __bc = bucket_count(); + return __bc != 0 ? (float)size() / __bc : 0.f; + } + _LIBCPP_HIDE_FROM_ABI void max_load_factor(float __mlf) _NOEXCEPT { + _LIBCPP_ASSERT_UNCATEGORIZED(__mlf > 0, "unordered container::max_load_factor(lf) called with lf <= 0"); + max_load_factor() = std::max(__mlf, load_factor()); + } - _LIBCPP_HIDE_FROM_ABI - local_iterator - begin(size_type __n) - { - _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(), - "unordered container::begin(n) called with n >= bucket_count()"); - return local_iterator(__bucket_list_[__n], __n, bucket_count()); - } + _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < bucket_count(), "unordered container::begin(n) called with n >= bucket_count()"); + return local_iterator(__bucket_list_[__n], __n, bucket_count()); + } - _LIBCPP_HIDE_FROM_ABI - local_iterator - end(size_type __n) - { - _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(), - "unordered container::end(n) called with n >= bucket_count()"); - return local_iterator(nullptr, __n, bucket_count()); - } + _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < bucket_count(), "unordered container::end(n) called with n >= bucket_count()"); + return local_iterator(nullptr, __n, bucket_count()); + } - _LIBCPP_HIDE_FROM_ABI - const_local_iterator - cbegin(size_type __n) const - { - _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(), - "unordered container::cbegin(n) called with n >= bucket_count()"); - return const_local_iterator(__bucket_list_[__n], __n, bucket_count()); - } + _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < bucket_count(), "unordered container::cbegin(n) called with n >= bucket_count()"); + return const_local_iterator(__bucket_list_[__n], __n, bucket_count()); + } - _LIBCPP_HIDE_FROM_ABI - const_local_iterator - cend(size_type __n) const - { - _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(), - "unordered container::cend(n) called with n >= bucket_count()"); - return const_local_iterator(nullptr, __n, bucket_count()); - } + _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < bucket_count(), "unordered container::cend(n) called with n >= bucket_count()"); + return const_local_iterator(nullptr, __n, bucket_count()); + } private: - template - _LIBCPP_HIDE_FROM_ABI void __rehash(size_type __n); - template - _LIBCPP_HIDE_FROM_ABI void __do_rehash(size_type __n); - - template - _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&& ...__args); - - template - _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); - - - _LIBCPP_HIDE_FROM_ABI - void __copy_assign_alloc(const __hash_table& __u) - {__copy_assign_alloc(__u, integral_constant());} - _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u, true_type); - _LIBCPP_HIDE_FROM_ABI - void __copy_assign_alloc(const __hash_table&, false_type) {} - - _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, false_type); - _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, true_type) - _NOEXCEPT_( - is_nothrow_move_assignable<__node_allocator>::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value); - _LIBCPP_HIDE_FROM_ABI - void __move_assign_alloc(__hash_table& __u) - _NOEXCEPT_( - !__node_traits::propagate_on_container_move_assignment::value || - (is_nothrow_move_assignable<__pointer_allocator>::value && - is_nothrow_move_assignable<__node_allocator>::value)) - {__move_assign_alloc(__u, integral_constant());} - _LIBCPP_HIDE_FROM_ABI - void __move_assign_alloc(__hash_table& __u, true_type) - _NOEXCEPT_( - is_nothrow_move_assignable<__pointer_allocator>::value && - is_nothrow_move_assignable<__node_allocator>::value) - { - __bucket_list_.get_deleter().__alloc() = - std::move(__u.__bucket_list_.get_deleter().__alloc()); - __node_alloc() = std::move(__u.__node_alloc()); - } - _LIBCPP_HIDE_FROM_ABI - void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} + template + _LIBCPP_HIDE_FROM_ABI void __rehash(size_type __n); + template + _LIBCPP_HIDE_FROM_ABI void __do_rehash(size_type __n); - _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT; + template + _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&&... __args); - template friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; + template + _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); + + _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u) { + __copy_assign_alloc(__u, integral_constant()); + } + _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u, true_type); + _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table&, false_type) {} + + _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, false_type); + _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable::value&& + is_nothrow_move_assignable::value); + _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u) _NOEXCEPT_( + !__node_traits::propagate_on_container_move_assignment::value || + (is_nothrow_move_assignable<__pointer_allocator>::value && is_nothrow_move_assignable<__node_allocator>::value)) { + __move_assign_alloc(__u, integral_constant()); + } + _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u, true_type) _NOEXCEPT_( + is_nothrow_move_assignable<__pointer_allocator>::value&& is_nothrow_move_assignable<__node_allocator>::value) { + __bucket_list_.get_deleter().__alloc() = std::move(__u.__bucket_list_.get_deleter().__alloc()); + __node_alloc() = std::move(__u.__node_alloc()); + } + _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} + + _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT; + + template + friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; }; template -inline -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() - _NOEXCEPT_( - is_nothrow_default_constructible<__bucket_list>::value && - is_nothrow_default_constructible<__first_node>::value && - is_nothrow_default_constructible<__node_allocator>::value && - is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value) - : __p2_(0, __default_init_tag()), - __p3_(1.0f, __default_init_tag()) -{ -} +inline __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value&& is_nothrow_default_constructible<__first_node>::value&& + is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_default_constructible::value&& + is_nothrow_default_constructible::value) + : __p2_(0, __default_init_tag()), __p3_(1.0f, __default_init_tag()) {} template -inline -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, - const key_equal& __eql) - : __bucket_list_(nullptr, __bucket_list_deleter()), - __p1_(), - __p2_(0, __hf), - __p3_(1.0f, __eql) -{ -} +inline __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, const key_equal& __eql) + : __bucket_list_(nullptr, __bucket_list_deleter()), __p1_(), __p2_(0, __hf), __p3_(1.0f, __eql) {} template -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, - const key_equal& __eql, - const allocator_type& __a) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table( + const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, __hf), - __p3_(1.0f, __eql) -{ -} + __p3_(1.0f, __eql) {} template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, __default_init_tag()), - __p3_(1.0f, __default_init_tag()) -{ -} + __p3_(1.0f, __default_init_tag()) {} template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u) : __bucket_list_(nullptr, - __bucket_list_deleter(allocator_traits<__pointer_allocator>:: - select_on_container_copy_construction( - __u.__bucket_list_.get_deleter().__alloc()), 0)), - __p1_(__default_init_tag(), allocator_traits<__node_allocator>:: - select_on_container_copy_construction(__u.__node_alloc())), + __bucket_list_deleter(allocator_traits<__pointer_allocator>::select_on_container_copy_construction( + __u.__bucket_list_.get_deleter().__alloc()), + 0)), + __p1_(__default_init_tag(), + allocator_traits<__node_allocator>::select_on_container_copy_construction(__u.__node_alloc())), __p2_(0, __u.hash_function()), - __p3_(__u.__p3_) -{ -} + __p3_(__u.__p3_) {} template -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, - const allocator_type& __a) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, __u.hash_function()), - __p3_(__u.__p3_) -{ -} + __p3_(__u.__p3_) {} template -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) - _NOEXCEPT_( - is_nothrow_move_constructible<__bucket_list>::value && - is_nothrow_move_constructible<__first_node>::value && - is_nothrow_move_constructible<__node_allocator>::value && - is_nothrow_move_constructible::value && +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value&& is_nothrow_move_constructible<__first_node>::value&& + is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible::value&& is_nothrow_move_constructible::value) : __bucket_list_(std::move(__u.__bucket_list_)), __p1_(std::move(__u.__p1_)), __p2_(std::move(__u.__p2_)), - __p3_(std::move(__u.__p3_)) -{ - if (size() > 0) - { - __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = - __p1_.first().__ptr(); - __u.__p1_.first().__next_ = nullptr; - __u.size() = 0; - } + __p3_(std::move(__u.__p3_)) { + if (size() > 0) { + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); + __u.__p1_.first().__next_ = nullptr; + __u.size() = 0; + } } template -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, - const allocator_type& __a) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, std::move(__u.hash_function())), - __p3_(std::move(__u.__p3_)) -{ - if (__a == allocator_type(__u.__node_alloc())) - { - __bucket_list_.reset(__u.__bucket_list_.release()); - __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); - __u.__bucket_list_.get_deleter().size() = 0; - if (__u.size() > 0) - { - __p1_.first().__next_ = __u.__p1_.first().__next_; - __u.__p1_.first().__next_ = nullptr; - __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = - __p1_.first().__ptr(); - size() = __u.size(); - __u.size() = 0; - } + __p3_(std::move(__u.__p3_)) { + if (__a == allocator_type(__u.__node_alloc())) { + __bucket_list_.reset(__u.__bucket_list_.release()); + __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); + __u.__bucket_list_.get_deleter().size() = 0; + if (__u.size() > 0) { + __p1_.first().__next_ = __u.__p1_.first().__next_; + __u.__p1_.first().__next_ = nullptr; + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); + size() = __u.size(); + __u.size() = 0; } + } } template -__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() -{ +__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() { #if defined(_LIBCPP_CXX03_LANG) - static_assert((is_copy_constructible::value), - "Predicate must be copy-constructible."); - static_assert((is_copy_constructible::value), - "Hasher must be copy-constructible."); + static_assert((is_copy_constructible::value), "Predicate must be copy-constructible."); + static_assert((is_copy_constructible::value), "Hasher must be copy-constructible."); #endif - __deallocate_node(__p1_.first().__next_); + __deallocate_node(__p1_.first().__next_); } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc( - const __hash_table& __u, true_type) -{ - if (__node_alloc() != __u.__node_alloc()) - { - clear(); - __bucket_list_.reset(); - __bucket_list_.get_deleter().size() = 0; - } - __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc(); - __node_alloc() = __u.__node_alloc(); +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(const __hash_table& __u, true_type) { + if (__node_alloc() != __u.__node_alloc()) { + clear(); + __bucket_list_.reset(); + __bucket_list_.get_deleter().size() = 0; + } + __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc(); + __node_alloc() = __u.__node_alloc(); } template -__hash_table<_Tp, _Hash, _Equal, _Alloc>& -__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) -{ - if (this != std::addressof(__u)) - { - __copy_assign_alloc(__u); - hash_function() = __u.hash_function(); - key_eq() = __u.key_eq(); - max_load_factor() = __u.max_load_factor(); - __assign_multi(__u.begin(), __u.end()); - } - return *this; +__hash_table<_Tp, _Hash, _Equal, _Alloc>& __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) { + if (this != std::addressof(__u)) { + __copy_assign_alloc(__u); + hash_function() = __u.hash_function(); + key_eq() = __u.key_eq(); + max_load_factor() = __u.max_load_factor(); + __assign_multi(__u.begin(), __u.end()); + } + return *this; } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) - _NOEXCEPT -{ - __node_allocator& __na = __node_alloc(); - while (__np != nullptr) - { - __next_pointer __next = __np->__next_; - __node_pointer __real_np = __np->__upcast(); - __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__get_value())); - std::__destroy_at(std::addressof(*__real_np)); - __node_traits::deallocate(__na, __real_np, 1); - __np = __next; - } +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) _NOEXCEPT { + __node_allocator& __na = __node_alloc(); + while (__np != nullptr) { + __next_pointer __next = __np->__next_; + __node_pointer __real_np = __np->__upcast(); + __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__get_value())); + std::__destroy_at(std::addressof(*__real_np)); + __node_traits::deallocate(__na, __real_np, 1); + __np = __next; + } } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT -{ - size_type __bc = bucket_count(); - for (size_type __i = 0; __i < __bc; ++__i) - __bucket_list_[__i] = nullptr; - size() = 0; - __next_pointer __cache = __p1_.first().__next_; - __p1_.first().__next_ = nullptr; - return __cache; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT { + size_type __bc = bucket_count(); + for (size_type __i = 0; __i < __bc; ++__i) + __bucket_list_[__i] = nullptr; + size() = 0; + __next_pointer __cache = __p1_.first().__next_; + __p1_.first().__next_ = nullptr; + return __cache; } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( - __hash_table& __u, true_type) - _NOEXCEPT_( - is_nothrow_move_assignable<__node_allocator>::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value) -{ - clear(); - __bucket_list_.reset(__u.__bucket_list_.release()); - __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); - __u.__bucket_list_.get_deleter().size() = 0; - __move_assign_alloc(__u); - size() = __u.size(); - hash_function() = std::move(__u.hash_function()); - max_load_factor() = __u.max_load_factor(); - key_eq() = std::move(__u.key_eq()); - __p1_.first().__next_ = __u.__p1_.first().__next_; - if (size() > 0) - { - __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = - __p1_.first().__ptr(); - __u.__p1_.first().__next_ = nullptr; - __u.size() = 0; - } +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable::value&& + is_nothrow_move_assignable::value) { + clear(); + __bucket_list_.reset(__u.__bucket_list_.release()); + __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); + __u.__bucket_list_.get_deleter().size() = 0; + __move_assign_alloc(__u); + size() = __u.size(); + hash_function() = std::move(__u.hash_function()); + max_load_factor() = __u.max_load_factor(); + key_eq() = std::move(__u.key_eq()); + __p1_.first().__next_ = __u.__p1_.first().__next_; + if (size() > 0) { + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); + __u.__p1_.first().__next_ = nullptr; + __u.size() = 0; + } } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( - __hash_table& __u, false_type) -{ - if (__node_alloc() == __u.__node_alloc()) - __move_assign(__u, true_type()); - else - { - hash_function() = std::move(__u.hash_function()); - key_eq() = std::move(__u.key_eq()); - max_load_factor() = __u.max_load_factor(); - if (bucket_count() != 0) - { - __next_pointer __cache = __detach(); -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_HAS_NO_EXCEPTIONS - const_iterator __i = __u.begin(); - while (__cache != nullptr && __u.size() != 0) - { - __cache->__upcast()->__get_value() = - std::move(__u.remove(__i++)->__get_value()); - __next_pointer __next = __cache->__next_; - __node_insert_multi(__cache->__upcast()); - __cache = __next; - } +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u, false_type) { + if (__node_alloc() == __u.__node_alloc()) + __move_assign(__u, true_type()); + else { + hash_function() = std::move(__u.hash_function()); + key_eq() = std::move(__u.key_eq()); + max_load_factor() = __u.max_load_factor(); + if (bucket_count() != 0) { + __next_pointer __cache = __detach(); #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (...) - { - __deallocate_node(__cache); - throw; - } + try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - __deallocate_node(__cache); - } const_iterator __i = __u.begin(); - while (__u.size() != 0) - { - __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__get_value())); - __node_insert_multi(__h.get()); - __h.release(); + while (__cache != nullptr && __u.size() != 0) { + __cache->__upcast()->__get_value() = std::move(__u.remove(__i++)->__get_value()); + __next_pointer __next = __cache->__next_; + __node_insert_multi(__cache->__upcast()); + __cache = __next; } +#ifndef _LIBCPP_HAS_NO_EXCEPTIONS + } catch (...) { + __deallocate_node(__cache); + throw; + } +#endif // _LIBCPP_HAS_NO_EXCEPTIONS + __deallocate_node(__cache); + } + const_iterator __i = __u.begin(); + while (__u.size() != 0) { + __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__get_value())); + __node_insert_multi(__h.get()); + __h.release(); } + } } template -inline -__hash_table<_Tp, _Hash, _Equal, _Alloc>& -__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) - _NOEXCEPT_( - __node_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<__node_allocator>::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value) -{ - __move_assign(__u, integral_constant()); - return *this; +inline __hash_table<_Tp, _Hash, _Equal, _Alloc>& +__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<__node_allocator>::value&& + is_nothrow_move_assignable::value&& is_nothrow_move_assignable::value) { + __move_assign(__u, integral_constant()); + return *this; } template template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, - _InputIterator __last) -{ - typedef iterator_traits<_InputIterator> _ITraits; - typedef typename _ITraits::value_type _ItValueType; - static_assert((is_same<_ItValueType, __container_value_type>::value), - "__assign_unique may only be called with the containers value type"); - - if (bucket_count() != 0) - { - __next_pointer __cache = __detach(); +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value), + "__assign_unique may only be called with the containers value type"); + + if (bucket_count() != 0) { + __next_pointer __cache = __detach(); #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { + try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - for (; __cache != nullptr && __first != __last; ++__first) - { - __cache->__upcast()->__get_value() = *__first; - __next_pointer __next = __cache->__next_; - __node_insert_unique(__cache->__upcast()); - __cache = __next; - } + for (; __cache != nullptr && __first != __last; ++__first) { + __cache->__upcast()->__get_value() = *__first; + __next_pointer __next = __cache->__next_; + __node_insert_unique(__cache->__upcast()); + __cache = __next; + } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (...) - { - __deallocate_node(__cache); - throw; - } -#endif // _LIBCPP_HAS_NO_EXCEPTIONS - __deallocate_node(__cache); + } catch (...) { + __deallocate_node(__cache); + throw; } - for (; __first != __last; ++__first) - __insert_unique(*__first); +#endif // _LIBCPP_HAS_NO_EXCEPTIONS + __deallocate_node(__cache); + } + for (; __first != __last; ++__first) + __insert_unique(*__first); } template template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, - _InputIterator __last) -{ - typedef iterator_traits<_InputIterator> _ITraits; - typedef typename _ITraits::value_type _ItValueType; - static_assert((is_same<_ItValueType, __container_value_type>::value || - is_same<_ItValueType, __node_value_type>::value), - "__assign_multi may only be called with the containers value type" - " or the nodes value type"); - if (bucket_count() != 0) - { - __next_pointer __cache = __detach(); +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert( + (is_same<_ItValueType, __container_value_type>::value || is_same<_ItValueType, __node_value_type>::value), + "__assign_multi may only be called with the containers value type" + " or the nodes value type"); + if (bucket_count() != 0) { + __next_pointer __cache = __detach(); #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { + try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - for (; __cache != nullptr && __first != __last; ++__first) - { - __cache->__upcast()->__get_value() = *__first; - __next_pointer __next = __cache->__next_; - __node_insert_multi(__cache->__upcast()); - __cache = __next; - } + for (; __cache != nullptr && __first != __last; ++__first) { + __cache->__upcast()->__get_value() = *__first; + __next_pointer __next = __cache->__next_; + __node_insert_multi(__cache->__upcast()); + __cache = __next; + } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (...) - { - __deallocate_node(__cache); - throw; - } -#endif // _LIBCPP_HAS_NO_EXCEPTIONS - __deallocate_node(__cache); + } catch (...) { + __deallocate_node(__cache); + throw; } - for (; __first != __last; ++__first) - __insert_multi(_NodeTypes::__get_value(*__first)); +#endif // _LIBCPP_HAS_NO_EXCEPTIONS + __deallocate_node(__cache); + } + for (; __first != __last; ++__first) + __insert_multi(_NodeTypes::__get_value(*__first)); } template -inline -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT -{ - return iterator(__p1_.first().__next_); +inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT { + return iterator(__p1_.first().__next_); } template -inline -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT -{ - return iterator(nullptr); +inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT { + return iterator(nullptr); } template -inline -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT -{ - return const_iterator(__p1_.first().__next_); +inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT { + return const_iterator(__p1_.first().__next_); } template -inline -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT -{ - return const_iterator(nullptr); +inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT { + return const_iterator(nullptr); } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT -{ - if (size() > 0) - { - __deallocate_node(__p1_.first().__next_); - __p1_.first().__next_ = nullptr; - size_type __bc = bucket_count(); - for (size_type __i = 0; __i < __bc; ++__i) - __bucket_list_[__i] = nullptr; - size() = 0; - } +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT { + if (size() > 0) { + __deallocate_node(__p1_.first().__next_); + __p1_.first().__next_ = nullptr; + size_type __bc = bucket_count(); + for (size_type __i = 0; __i < __bc; ++__i) + __bucket_list_[__i] = nullptr; + size() = 0; + } } - // Prepare the container for an insertion of the value __value with the hash // __hash. This does a lookup into the container to see if __value is already // present, and performs a rehash if necessary. Returns a pointer to the @@ -1640,36 +1298,28 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT // Note that this function does forward exceptions if key_eq() throws, and never // mutates __value or actually inserts into the map. template -_LIBCPP_HIDE_FROM_ABI -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( - size_t __hash, value_type& __value) -{ - size_type __bc = bucket_count(); - - if (__bc != 0) - { - size_t __chash = std::__constrain_hash(__hash, __bc); - __next_pointer __ndptr = __bucket_list_[__chash]; - if (__ndptr != nullptr) - { - for (__ndptr = __ndptr->__next_; __ndptr != nullptr && - (__ndptr->__hash() == __hash || - std::__constrain_hash(__ndptr->__hash(), __bc) == __chash); - __ndptr = __ndptr->__next_) - { - if ((__ndptr->__hash() == __hash) && - key_eq()(__ndptr->__upcast()->__get_value(), __value)) - return __ndptr; - } - } - } - if (size()+1 > __bc * max_load_factor() || __bc == 0) - { - __rehash_unique(std::max(2 * __bc + !std::__is_hash_power2(__bc), - size_type(std::ceil(float(size() + 1) / max_load_factor())))); +_LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(size_t __hash, value_type& __value) { + size_type __bc = bucket_count(); + + if (__bc != 0) { + size_t __chash = std::__constrain_hash(__hash, __bc); + __next_pointer __ndptr = __bucket_list_[__chash]; + if (__ndptr != nullptr) { + for (__ndptr = __ndptr->__next_; + __ndptr != nullptr && + (__ndptr->__hash() == __hash || std::__constrain_hash(__ndptr->__hash(), __bc) == __chash); + __ndptr = __ndptr->__next_) { + if ((__ndptr->__hash() == __hash) && key_eq()(__ndptr->__upcast()->__get_value(), __value)) + return __ndptr; + } } - return nullptr; + } + if (size() + 1 > __bc * max_load_factor() || __bc == 0) { + __rehash_unique(std::max( + 2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor())))); + } + return nullptr; } // Insert the node __nd into the container by pushing it into the right bucket, @@ -1677,50 +1327,41 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( // rehashing has already occurred and that no element with the same key exists // in the map. template -_LIBCPP_HIDE_FROM_ABI -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform( - __node_pointer __nd) _NOEXCEPT -{ - size_type __bc = bucket_count(); - size_t __chash = std::__constrain_hash(__nd->__hash(), __bc); - // insert_after __bucket_list_[__chash], or __first_node if bucket is null - __next_pointer __pn = __bucket_list_[__chash]; - if (__pn == nullptr) - { - __pn =__p1_.first().__ptr(); - __nd->__next_ = __pn->__next_; - __pn->__next_ = __nd->__ptr(); - // fix up __bucket_list_ - __bucket_list_[__chash] = __pn; - if (__nd->__next_ != nullptr) - __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); - } - else - { - __nd->__next_ = __pn->__next_; - __pn->__next_ = __nd->__ptr(); - } - ++size(); +_LIBCPP_HIDE_FROM_ABI void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(__node_pointer __nd) _NOEXCEPT { + size_type __bc = bucket_count(); + size_t __chash = std::__constrain_hash(__nd->__hash(), __bc); + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) { + __pn = __p1_.first().__ptr(); + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__nd->__next_ != nullptr) + __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); + } else { + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd->__ptr(); + } + ++size(); } template pair::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) -{ - __nd->__hash_ = hash_function()(__nd->__get_value()); - __next_pointer __existing_node = - __node_insert_unique_prepare(__nd->__hash(), __nd->__get_value()); - - // Insert the node, unless it already exists in the container. - bool __inserted = false; - if (__existing_node == nullptr) - { - __node_insert_unique_perform(__nd); - __existing_node = __nd->__ptr(); - __inserted = true; - } - return pair(iterator(__existing_node), __inserted); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) { + __nd->__hash_ = hash_function()(__nd->__get_value()); + __next_pointer __existing_node = __node_insert_unique_prepare(__nd->__hash(), __nd->__get_value()); + + // Insert the node, unless it already exists in the container. + bool __inserted = false; + if (__existing_node == nullptr) { + __node_insert_unique_perform(__nd); + __existing_node = __nd->__ptr(); + __inserted = true; + } + return pair(iterator(__existing_node), __inserted); } // Prepare the container for an insertion of the value __cp_val with the hash @@ -1732,40 +1373,34 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __ // mutates __value or actually inserts into the map. template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( - size_t __cp_hash, value_type& __cp_val) -{ - size_type __bc = bucket_count(); - if (size()+1 > __bc * max_load_factor() || __bc == 0) - { - __rehash_multi(std::max(2 * __bc + !std::__is_hash_power2(__bc), - size_type(std::ceil(float(size() + 1) / max_load_factor())))); - __bc = bucket_count(); - } - size_t __chash = std::__constrain_hash(__cp_hash, __bc); - __next_pointer __pn = __bucket_list_[__chash]; - if (__pn != nullptr) - { - for (bool __found = false; __pn->__next_ != nullptr && - std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash; - __pn = __pn->__next_) - { - // __found key_eq() action - // false false loop - // true true loop - // false true set __found to true - // true false break - if (__found != (__pn->__next_->__hash() == __cp_hash && - key_eq()(__pn->__next_->__upcast()->__get_value(), __cp_val))) - { - if (!__found) - __found = true; - else - break; - } - } +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(size_t __cp_hash, value_type& __cp_val) { + size_type __bc = bucket_count(); + if (size() + 1 > __bc * max_load_factor() || __bc == 0) { + __rehash_multi(std::max( + 2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + } + size_t __chash = std::__constrain_hash(__cp_hash, __bc); + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn != nullptr) { + for (bool __found = false; + __pn->__next_ != nullptr && std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash; + __pn = __pn->__next_) { + // __found key_eq() action + // false false loop + // true true loop + // false true set __found to true + // true false break + if (__found != + (__pn->__next_->__hash() == __cp_hash && key_eq()(__pn->__next_->__upcast()->__get_value(), __cp_val))) { + if (!__found) + __found = true; + else + break; + } } - return __pn; + } + return __pn; } // Insert the node __cp into the container after __pn (which is the last node in @@ -1774,746 +1409,601 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( // all we need to do is update the bucket and size(). Assumes that __cp->__hash // is up-to-date. template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( - __node_pointer __cp, __next_pointer __pn) _NOEXCEPT -{ - size_type __bc = bucket_count(); - size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); - if (__pn == nullptr) - { - __pn =__p1_.first().__ptr(); - __cp->__next_ = __pn->__next_; - __pn->__next_ = __cp->__ptr(); - // fix up __bucket_list_ - __bucket_list_[__chash] = __pn; - if (__cp->__next_ != nullptr) - __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)] - = __cp->__ptr(); - } - else - { - __cp->__next_ = __pn->__next_; - __pn->__next_ = __cp->__ptr(); - if (__cp->__next_ != nullptr) - { - size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc); - if (__nhash != __chash) - __bucket_list_[__nhash] = __cp->__ptr(); - } +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( + __node_pointer __cp, __next_pointer __pn) _NOEXCEPT { + size_type __bc = bucket_count(); + size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); + if (__pn == nullptr) { + __pn = __p1_.first().__ptr(); + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__cp->__next_ != nullptr) + __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)] = __cp->__ptr(); + } else { + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp->__ptr(); + if (__cp->__next_ != nullptr) { + size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc); + if (__nhash != __chash) + __bucket_list_[__nhash] = __cp->__ptr(); } - ++size(); + } + ++size(); } - template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) -{ - __cp->__hash_ = hash_function()(__cp->__get_value()); - __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__get_value()); - __node_insert_multi_perform(__cp, __pn); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) { + __cp->__hash_ = hash_function()(__cp->__get_value()); + __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__get_value()); + __node_insert_multi_perform(__cp, __pn); - return iterator(__cp->__ptr()); + return iterator(__cp->__ptr()); } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( - const_iterator __p, __node_pointer __cp) -{ - if (__p != end() && key_eq()(*__p, __cp->__get_value())) - { - __next_pointer __np = __p.__node_; - __cp->__hash_ = __np->__hash(); - size_type __bc = bucket_count(); - if (size()+1 > __bc * max_load_factor() || __bc == 0) - { - __rehash_multi(std::max(2 * __bc + !std::__is_hash_power2(__bc), - size_type(std::ceil(float(size() + 1) / max_load_factor())))); - __bc = bucket_count(); - } - size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); - __next_pointer __pp = __bucket_list_[__chash]; - while (__pp->__next_ != __np) - __pp = __pp->__next_; - __cp->__next_ = __np; - __pp->__next_ = static_cast<__next_pointer>(__cp); - ++size(); - return iterator(static_cast<__next_pointer>(__cp)); - } - return __node_insert_multi(__cp); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(const_iterator __p, __node_pointer __cp) { + if (__p != end() && key_eq()(*__p, __cp->__get_value())) { + __next_pointer __np = __p.__node_; + __cp->__hash_ = __np->__hash(); + size_type __bc = bucket_count(); + if (size() + 1 > __bc * max_load_factor() || __bc == 0) { + __rehash_multi(std::max( + 2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + } + size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); + __next_pointer __pp = __bucket_list_[__chash]; + while (__pp->__next_ != __np) + __pp = __pp->__next_; + __cp->__next_ = __np; + __pp->__next_ = static_cast<__next_pointer>(__cp); + ++size(); + return iterator(static_cast<__next_pointer>(__cp)); + } + return __node_insert_multi(__cp); } - - template -template +template pair::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) -{ - - size_t __hash = hash_function()(__k); - size_type __bc = bucket_count(); - bool __inserted = false; - __next_pointer __nd; - size_t __chash; - if (__bc != 0) - { - __chash = std::__constrain_hash(__hash, __bc); - __nd = __bucket_list_[__chash]; - if (__nd != nullptr) - { - for (__nd = __nd->__next_; __nd != nullptr && - (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash); - __nd = __nd->__next_) - { - if ((__nd->__hash() == __hash) && - key_eq()(__nd->__upcast()->__get_value(), __k)) - goto __done; - } - } +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) { + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + bool __inserted = false; + __next_pointer __nd; + size_t __chash; + if (__bc != 0) { + __chash = std::__constrain_hash(__hash, __bc); + __nd = __bucket_list_[__chash]; + if (__nd != nullptr) { + for (__nd = __nd->__next_; + __nd != nullptr && (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) { + if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __k)) + goto __done; + } } - { - __node_holder __h = __construct_node_hash(__hash, std::forward<_Args>(__args)...); - if (size()+1 > __bc * max_load_factor() || __bc == 0) - { - __rehash_unique(std::max(2 * __bc + !std::__is_hash_power2(__bc), - size_type(std::ceil(float(size() + 1) / max_load_factor())))); - __bc = bucket_count(); - __chash = std::__constrain_hash(__hash, __bc); - } - // insert_after __bucket_list_[__chash], or __first_node if bucket is null - __next_pointer __pn = __bucket_list_[__chash]; - if (__pn == nullptr) - { - __pn = __p1_.first().__ptr(); - __h->__next_ = __pn->__next_; - __pn->__next_ = __h.get()->__ptr(); - // fix up __bucket_list_ - __bucket_list_[__chash] = __pn; - if (__h->__next_ != nullptr) - __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] - = __h.get()->__ptr(); - } - else - { - __h->__next_ = __pn->__next_; - __pn->__next_ = static_cast<__next_pointer>(__h.get()); - } - __nd = static_cast<__next_pointer>(__h.release()); - // increment size - ++size(); - __inserted = true; + } + { + __node_holder __h = __construct_node_hash(__hash, std::forward<_Args>(__args)...); + if (size() + 1 > __bc * max_load_factor() || __bc == 0) { + __rehash_unique(std::max( + 2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + __chash = std::__constrain_hash(__hash, __bc); } + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) { + __pn = __p1_.first().__ptr(); + __h->__next_ = __pn->__next_; + __pn->__next_ = __h.get()->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__h->__next_ != nullptr) + __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] = __h.get()->__ptr(); + } else { + __h->__next_ = __pn->__next_; + __pn->__next_ = static_cast<__next_pointer>(__h.get()); + } + __nd = static_cast<__next_pointer>(__h.release()); + // increment size + ++size(); + __inserted = true; + } __done: - return pair(iterator(__nd), __inserted); + return pair(iterator(__nd), __inserted); } template template pair::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) -{ - __node_holder __h = __construct_node(std::forward<_Args>(__args)...); - pair __r = __node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) { + __node_holder __h = __construct_node(std::forward<_Args>(__args)...); + pair __r = __node_insert_unique(__h.get()); + if (__r.second) + __h.release(); + return __r; } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) -{ - __node_holder __h = __construct_node(std::forward<_Args>(__args)...); - iterator __r = __node_insert_multi(__h.get()); - __h.release(); - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) { + __node_holder __h = __construct_node(std::forward<_Args>(__args)...); + iterator __r = __node_insert_multi(__h.get()); + __h.release(); + return __r; } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( - const_iterator __p, _Args&&... __args) -{ - __node_holder __h = __construct_node(std::forward<_Args>(__args)...); - iterator __r = __node_insert_multi(__p, __h.get()); - __h.release(); - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) { + __node_holder __h = __construct_node(std::forward<_Args>(__args)...); + iterator __r = __node_insert_multi(__p, __h.get()); + __h.release(); + return __r; } #if _LIBCPP_STD_VER >= 17 template template -_LIBCPP_HIDE_FROM_ABI -_InsertReturnType -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( - _NodeHandle&& __nh) -{ - if (__nh.empty()) - return _InsertReturnType{end(), false, _NodeHandle()}; - pair __result = __node_insert_unique(__nh.__ptr_); - if (__result.second) - __nh.__release_ptr(); - return _InsertReturnType{__result.first, __result.second, std::move(__nh)}; +_LIBCPP_HIDE_FROM_ABI _InsertReturnType +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(_NodeHandle&& __nh) { + if (__nh.empty()) + return _InsertReturnType{end(), false, _NodeHandle()}; + pair __result = __node_insert_unique(__nh.__ptr_); + if (__result.second) + __nh.__release_ptr(); + return _InsertReturnType{__result.first, __result.second, std::move(__nh)}; } template template -_LIBCPP_HIDE_FROM_ABI -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( - const_iterator, _NodeHandle&& __nh) -{ - if (__nh.empty()) - return end(); - pair __result = __node_insert_unique(__nh.__ptr_); - if (__result.second) - __nh.__release_ptr(); - return __result.first; +_LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(const_iterator, _NodeHandle&& __nh) { + if (__nh.empty()) + return end(); + pair __result = __node_insert_unique(__nh.__ptr_); + if (__result.second) + __nh.__release_ptr(); + return __result.first; } template template -_LIBCPP_HIDE_FROM_ABI -_NodeHandle -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( - key_type const& __key) -{ - iterator __i = find(__key); - if (__i == end()) - return _NodeHandle(); - return __node_handle_extract<_NodeHandle>(__i); +_LIBCPP_HIDE_FROM_ABI _NodeHandle +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(key_type const& __key) { + iterator __i = find(__key); + if (__i == end()) + return _NodeHandle(); + return __node_handle_extract<_NodeHandle>(__i); } template template -_LIBCPP_HIDE_FROM_ABI -_NodeHandle -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( - const_iterator __p) -{ - allocator_type __alloc(__node_alloc()); - return _NodeHandle(remove(__p).release(), __alloc); +_LIBCPP_HIDE_FROM_ABI _NodeHandle __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(const_iterator __p) { + allocator_type __alloc(__node_alloc()); + return _NodeHandle(remove(__p).release(), __alloc); } template template -_LIBCPP_HIDE_FROM_ABI -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique( - _Table& __source) -{ - static_assert(is_same<__node, typename _Table::__node>::value, ""); - - for (typename _Table::iterator __it = __source.begin(); - __it != __source.end();) - { - __node_pointer __src_ptr = __it.__node_->__upcast(); - size_t __hash = hash_function()(__src_ptr->__get_value()); - __next_pointer __existing_node = - __node_insert_unique_prepare(__hash, __src_ptr->__get_value()); - auto __prev_iter = __it++; - if (__existing_node == nullptr) - { - (void)__source.remove(__prev_iter).release(); - __src_ptr->__hash_ = __hash; - __node_insert_unique_perform(__src_ptr); - } +_LIBCPP_HIDE_FROM_ABI void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(_Table& __source) { + static_assert(is_same<__node, typename _Table::__node>::value, ""); + + for (typename _Table::iterator __it = __source.begin(); __it != __source.end();) { + __node_pointer __src_ptr = __it.__node_->__upcast(); + size_t __hash = hash_function()(__src_ptr->__get_value()); + __next_pointer __existing_node = __node_insert_unique_prepare(__hash, __src_ptr->__get_value()); + auto __prev_iter = __it++; + if (__existing_node == nullptr) { + (void)__source.remove(__prev_iter).release(); + __src_ptr->__hash_ = __hash; + __node_insert_unique_perform(__src_ptr); } + } } template template -_LIBCPP_HIDE_FROM_ABI -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( - _NodeHandle&& __nh) -{ - if (__nh.empty()) - return end(); - iterator __result = __node_insert_multi(__nh.__ptr_); - __nh.__release_ptr(); - return __result; +_LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(_NodeHandle&& __nh) { + if (__nh.empty()) + return end(); + iterator __result = __node_insert_multi(__nh.__ptr_); + __nh.__release_ptr(); + return __result; } template template -_LIBCPP_HIDE_FROM_ABI -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( - const_iterator __hint, _NodeHandle&& __nh) -{ - if (__nh.empty()) - return end(); - iterator __result = __node_insert_multi(__hint, __nh.__ptr_); - __nh.__release_ptr(); - return __result; +_LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh) { + if (__nh.empty()) + return end(); + iterator __result = __node_insert_multi(__hint, __nh.__ptr_); + __nh.__release_ptr(); + return __result; } template template -_LIBCPP_HIDE_FROM_ABI -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( - _Table& __source) -{ - static_assert(is_same::value, ""); - - for (typename _Table::iterator __it = __source.begin(); - __it != __source.end();) - { - __node_pointer __src_ptr = __it.__node_->__upcast(); - size_t __src_hash = hash_function()(__src_ptr->__get_value()); - __next_pointer __pn = - __node_insert_multi_prepare(__src_hash, __src_ptr->__get_value()); - (void)__source.remove(__it++).release(); - __src_ptr->__hash_ = __src_hash; - __node_insert_multi_perform(__src_ptr, __pn); - } +_LIBCPP_HIDE_FROM_ABI void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(_Table& __source) { + static_assert(is_same::value, ""); + + for (typename _Table::iterator __it = __source.begin(); __it != __source.end();) { + __node_pointer __src_ptr = __it.__node_->__upcast(); + size_t __src_hash = hash_function()(__src_ptr->__get_value()); + __next_pointer __pn = __node_insert_multi_prepare(__src_hash, __src_ptr->__get_value()); + (void)__source.remove(__it++).release(); + __src_ptr->__hash_ = __src_hash; + __node_insert_multi_perform(__src_ptr, __pn); + } } #endif // _LIBCPP_STD_VER >= 17 template template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) -_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK -{ - if (__n == 1) - __n = 2; - else if (__n & (__n - 1)) - __n = std::__next_prime(__n); - size_type __bc = bucket_count(); - if (__n > __bc) - __do_rehash<_UniqueKeys>(__n); - else if (__n < __bc) - { - __n = std::max - ( - __n, - std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor()))) : - std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor()))) - ); - if (__n < __bc) - __do_rehash<_UniqueKeys>(__n); - } +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { + if (__n == 1) + __n = 2; + else if (__n & (__n - 1)) + __n = std::__next_prime(__n); + size_type __bc = bucket_count(); + if (__n > __bc) + __do_rehash<_UniqueKeys>(__n); + else if (__n < __bc) { + __n = std::max( + __n, + std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor()))) + : std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor())))); + if (__n < __bc) + __do_rehash<_UniqueKeys>(__n); + } } template template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) -{ - __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); - __bucket_list_.reset(__nbc > 0 ? - __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); - __bucket_list_.get_deleter().size() = __nbc; - if (__nbc > 0) - { - for (size_type __i = 0; __i < __nbc; ++__i) - __bucket_list_[__i] = nullptr; - __next_pointer __pp = __p1_.first().__ptr(); - __next_pointer __cp = __pp->__next_; - if (__cp != nullptr) - { - size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc); +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) { + __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); + __bucket_list_.reset(__nbc > 0 ? __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); + __bucket_list_.get_deleter().size() = __nbc; + if (__nbc > 0) { + for (size_type __i = 0; __i < __nbc; ++__i) + __bucket_list_[__i] = nullptr; + __next_pointer __pp = __p1_.first().__ptr(); + __next_pointer __cp = __pp->__next_; + if (__cp != nullptr) { + size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc); + __bucket_list_[__chash] = __pp; + size_type __phash = __chash; + for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; __cp = __pp->__next_) { + __chash = std::__constrain_hash(__cp->__hash(), __nbc); + if (__chash == __phash) + __pp = __cp; + else { + if (__bucket_list_[__chash] == nullptr) { __bucket_list_[__chash] = __pp; - size_type __phash = __chash; - for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; - __cp = __pp->__next_) - { - __chash = std::__constrain_hash(__cp->__hash(), __nbc); - if (__chash == __phash) - __pp = __cp; - else - { - if (__bucket_list_[__chash] == nullptr) - { - __bucket_list_[__chash] = __pp; - __pp = __cp; - __phash = __chash; - } - else - { - __next_pointer __np = __cp; - if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys) - { - for (; __np->__next_ != nullptr && - key_eq()(__cp->__upcast()->__get_value(), - __np->__next_->__upcast()->__get_value()); - __np = __np->__next_) - ; - } - __pp->__next_ = __np->__next_; - __np->__next_ = __bucket_list_[__chash]->__next_; - __bucket_list_[__chash]->__next_ = __cp; - - } - } + __pp = __cp; + __phash = __chash; + } else { + __next_pointer __np = __cp; + if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys) { + for (; __np->__next_ != nullptr && + key_eq()(__cp->__upcast()->__get_value(), __np->__next_->__upcast()->__get_value()); + __np = __np->__next_) + ; } + __pp->__next_ = __np->__next_; + __np->__next_ = __bucket_list_[__chash]->__next_; + __bucket_list_[__chash]->__next_ = __cp; + } } + } } + } } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) -{ - size_t __hash = hash_function()(__k); - size_type __bc = bucket_count(); - if (__bc != 0) - { - size_t __chash = std::__constrain_hash(__hash, __bc); - __next_pointer __nd = __bucket_list_[__chash]; - if (__nd != nullptr) - { - for (__nd = __nd->__next_; __nd != nullptr && - (__nd->__hash() == __hash - || std::__constrain_hash(__nd->__hash(), __bc) == __chash); - __nd = __nd->__next_) - { - if ((__nd->__hash() == __hash) - && key_eq()(__nd->__upcast()->__get_value(), __k)) - return iterator(__nd); - } - } +__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) { + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + if (__bc != 0) { + size_t __chash = std::__constrain_hash(__hash, __bc); + __next_pointer __nd = __bucket_list_[__chash]; + if (__nd != nullptr) { + for (__nd = __nd->__next_; + __nd != nullptr && (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) { + if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __k)) + return iterator(__nd); + } } - return end(); + } + return end(); } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const -{ - size_t __hash = hash_function()(__k); - size_type __bc = bucket_count(); - if (__bc != 0) - { - size_t __chash = std::__constrain_hash(__hash, __bc); - __next_pointer __nd = __bucket_list_[__chash]; - if (__nd != nullptr) - { - for (__nd = __nd->__next_; __nd != nullptr && - (__hash == __nd->__hash() - || std::__constrain_hash(__nd->__hash(), __bc) == __chash); - __nd = __nd->__next_) - { - if ((__nd->__hash() == __hash) - && key_eq()(__nd->__upcast()->__get_value(), __k)) - return const_iterator(__nd); - } - } - +__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const { + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + if (__bc != 0) { + size_t __chash = std::__constrain_hash(__hash, __bc); + __next_pointer __nd = __bucket_list_[__chash]; + if (__nd != nullptr) { + for (__nd = __nd->__next_; + __nd != nullptr && (__hash == __nd->__hash() || std::__constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) { + if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __k)) + return const_iterator(__nd); + } } - return end(); + } + return end(); } template -template +template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args) -{ - static_assert(!__is_hash_value_type<_Args...>::value, - "Construct cannot be called with a hash value type"); - __node_allocator& __na = __node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - - // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value - // held inside the node, since we need to use the allocator's construct() method for that. - // - // We don't use the allocator's construct() method to construct the node itself since the - // Cpp17FooInsertable named requirements don't require the allocator's construct() method - // to work on anything other than the value_type. - std::__construct_at(std::addressof(*__h), /* next = */nullptr, /* hash = */0); - - // Now construct the value_type using the allocator's construct() method. - __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_Args>(__args)...); - __h.get_deleter().__value_constructed = true; - - __h->__hash_ = hash_function()(__h->__get_value()); - return __h; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&&... __args) { + static_assert(!__is_hash_value_type<_Args...>::value, "Construct cannot be called with a hash value type"); + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + + // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value + // held inside the node, since we need to use the allocator's construct() method for that. + // + // We don't use the allocator's construct() method to construct the node itself since the + // Cpp17FooInsertable named requirements don't require the allocator's construct() method + // to work on anything other than the value_type. + std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ 0); + + // Now construct the value_type using the allocator's construct() method. + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_Args>(__args)...); + __h.get_deleter().__value_constructed = true; + + __h->__hash_ = hash_function()(__h->__get_value()); + return __h; } template -template +template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash( - size_t __hash, _First&& __f, _Rest&& ...__rest) -{ - static_assert(!__is_hash_value_type<_First, _Rest...>::value, - "Construct cannot be called with a hash value type"); - __node_allocator& __na = __node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - std::__construct_at(std::addressof(*__h), /* next = */nullptr, /* hash = */__hash); - __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__get_value()), - std::forward<_First>(__f), - std::forward<_Rest>(__rest)...); - __h.get_deleter().__value_constructed = true; - return __h; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest) { + static_assert(!__is_hash_value_type<_First, _Rest...>::value, "Construct cannot be called with a hash value type"); + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ __hash); + __node_traits::construct( + __na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_First>(__f), std::forward<_Rest>(__rest)...); + __h.get_deleter().__value_constructed = true; + return __h; } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) -{ - __next_pointer __np = __p.__node_; - _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(), - "unordered container::erase(iterator) called with a non-dereferenceable iterator"); - iterator __r(__np); - ++__r; - remove(__p); - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) { + __next_pointer __np = __p.__node_; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __p != end(), "unordered container::erase(iterator) called with a non-dereferenceable iterator"); + iterator __r(__np); + ++__r; + remove(__p); + return __r; } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, - const_iterator __last) -{ - for (const_iterator __p = __first; __first != __last; __p = __first) - { - ++__first; - erase(__p); - } - __next_pointer __np = __last.__node_; - return iterator (__np); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_iterator __last) { + for (const_iterator __p = __first; __first != __last; __p = __first) { + ++__first; + erase(__p); + } + __next_pointer __np = __last.__node_; + return iterator(__np); } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) -{ - iterator __i = find(__k); - if (__i == end()) - return 0; - erase(__i); - return 1; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) { + iterator __i = find(__k); + if (__i == end()) + return 0; + erase(__i); + return 1; } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) -{ - size_type __r = 0; - iterator __i = find(__k); - if (__i != end()) - { - iterator __e = end(); - do - { - erase(__i++); - ++__r; - } while (__i != __e && key_eq()(*__i, __k)); - } - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) { + size_type __r = 0; + iterator __i = find(__k); + if (__i != end()) { + iterator __e = end(); + do { + erase(__i++); + ++__r; + } while (__i != __e && key_eq()(*__i, __k)); + } + return __r; } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT -{ - // current node - __next_pointer __cn = __p.__node_; - size_type __bc = bucket_count(); - size_t __chash = std::__constrain_hash(__cn->__hash(), __bc); - // find previous node - __next_pointer __pn = __bucket_list_[__chash]; - for (; __pn->__next_ != __cn; __pn = __pn->__next_) - ; - // Fix up __bucket_list_ - // if __pn is not in same bucket (before begin is not in same bucket) && - // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) - if (__pn == __p1_.first().__ptr() - || std::__constrain_hash(__pn->__hash(), __bc) != __chash) - { - if (__cn->__next_ == nullptr - || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash) - __bucket_list_[__chash] = nullptr; - } - // if __cn->__next_ is not in same bucket (nullptr is in same bucket) - if (__cn->__next_ != nullptr) - { - size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc); - if (__nhash != __chash) - __bucket_list_[__nhash] = __pn; - } - // remove __cn - __pn->__next_ = __cn->__next_; - __cn->__next_ = nullptr; - --size(); - return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT { + // current node + __next_pointer __cn = __p.__node_; + size_type __bc = bucket_count(); + size_t __chash = std::__constrain_hash(__cn->__hash(), __bc); + // find previous node + __next_pointer __pn = __bucket_list_[__chash]; + for (; __pn->__next_ != __cn; __pn = __pn->__next_) + ; + // Fix up __bucket_list_ + // if __pn is not in same bucket (before begin is not in same bucket) && + // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) + if (__pn == __p1_.first().__ptr() || std::__constrain_hash(__pn->__hash(), __bc) != __chash) { + if (__cn->__next_ == nullptr || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash) + __bucket_list_[__chash] = nullptr; + } + // if __cn->__next_ is not in same bucket (nullptr is in same bucket) + if (__cn->__next_ != nullptr) { + size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc); + if (__nhash != __chash) + __bucket_list_[__nhash] = __pn; + } + // remove __cn + __pn->__next_ = __cn->__next_; + __cn->__next_ = nullptr; + --size(); + return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); } template template -inline -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const -{ - return static_cast(find(__k) != end()); +inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const { + return static_cast(find(__k) != end()); } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const -{ - size_type __r = 0; - const_iterator __i = find(__k); - if (__i != end()) - { - const_iterator __e = end(); - do - { - ++__i; - ++__r; - } while (__i != __e && key_eq()(*__i, __k)); - } - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const { + size_type __r = 0; + const_iterator __i = find(__k); + if (__i != end()) { + const_iterator __e = end(); + do { + ++__i; + ++__r; + } while (__i != __e && key_eq()(*__i, __k)); + } + return __r; } template template pair::iterator, typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( - const _Key& __k) -{ - iterator __i = find(__k); - iterator __j = __i; - if (__i != end()) - ++__j; - return pair(__i, __j); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(const _Key& __k) { + iterator __i = find(__k); + iterator __j = __i; + if (__i != end()) + ++__j; + return pair(__i, __j); } template template pair::const_iterator, typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( - const _Key& __k) const -{ - const_iterator __i = find(__k); - const_iterator __j = __i; - if (__i != end()) - ++__j; - return pair(__i, __j); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(const _Key& __k) const { + const_iterator __i = find(__k); + const_iterator __j = __i; + if (__i != end()) + ++__j; + return pair(__i, __j); } template template pair::iterator, typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( - const _Key& __k) -{ - iterator __i = find(__k); - iterator __j = __i; - if (__i != end()) - { - iterator __e = end(); - do - { - ++__j; - } while (__j != __e && key_eq()(*__j, __k)); - } - return pair(__i, __j); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(const _Key& __k) { + iterator __i = find(__k); + iterator __j = __i; + if (__i != end()) { + iterator __e = end(); + do { + ++__j; + } while (__j != __e && key_eq()(*__j, __k)); + } + return pair(__i, __j); } template template pair::const_iterator, typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( - const _Key& __k) const -{ - const_iterator __i = find(__k); - const_iterator __j = __i; - if (__i != end()) - { - const_iterator __e = end(); - do - { - ++__j; - } while (__j != __e && key_eq()(*__j, __k)); - } - return pair(__i, __j); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(const _Key& __k) const { + const_iterator __i = find(__k); + const_iterator __j = __i; + if (__i != end()) { + const_iterator __e = end(); + do { + ++__j; + } while (__j != __e && key_eq()(*__j, __k)); + } + return pair(__i, __j); } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) #if _LIBCPP_STD_VER <= 11 - _NOEXCEPT_( - __is_nothrow_swappable::value && __is_nothrow_swappable::value - && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value - || __is_nothrow_swappable<__pointer_allocator>::value) - && (!__node_traits::propagate_on_container_swap::value - || __is_nothrow_swappable<__node_allocator>::value) - ) + _NOEXCEPT_(__is_nothrow_swappable::value&& __is_nothrow_swappable::value && + (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value || + __is_nothrow_swappable<__pointer_allocator>::value) && + (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__node_allocator>::value)) #else - _NOEXCEPT_(__is_nothrow_swappable::value && __is_nothrow_swappable::value) + _NOEXCEPT_(__is_nothrow_swappable::value&& __is_nothrow_swappable::value) #endif { - _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__node_traits::propagate_on_container_swap::value || - this->__node_alloc() == __u.__node_alloc(), - "unordered container::swap: Either propagate_on_container_swap " - "must be true or the allocators must compare equal"); - { + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR( + __node_traits::propagate_on_container_swap::value || this->__node_alloc() == __u.__node_alloc(), + "unordered container::swap: Either propagate_on_container_swap " + "must be true or the allocators must compare equal"); + { __node_pointer_pointer __npp = __bucket_list_.release(); __bucket_list_.reset(__u.__bucket_list_.release()); __u.__bucket_list_.reset(__npp); - } - std::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); - std::__swap_allocator(__bucket_list_.get_deleter().__alloc(), - __u.__bucket_list_.get_deleter().__alloc()); - std::__swap_allocator(__node_alloc(), __u.__node_alloc()); - std::swap(__p1_.first().__next_, __u.__p1_.first().__next_); - __p2_.swap(__u.__p2_); - __p3_.swap(__u.__p3_); - if (size() > 0) - __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = - __p1_.first().__ptr(); - if (__u.size() > 0) - __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = - __u.__p1_.first().__ptr(); + } + std::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); + std::__swap_allocator(__bucket_list_.get_deleter().__alloc(), __u.__bucket_list_.get_deleter().__alloc()); + std::__swap_allocator(__node_alloc(), __u.__node_alloc()); + std::swap(__p1_.first().__next_, __u.__p1_.first().__next_); + __p2_.swap(__u.__p2_); + __p3_.swap(__u.__p3_); + if (size() > 0) + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); + if (__u.size() > 0) + __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = + __u.__p1_.first().__ptr(); } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type -__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const -{ - _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(), - "unordered container::bucket_size(n) called with n >= bucket_count()"); - __next_pointer __np = __bucket_list_[__n]; - size_type __bc = bucket_count(); - size_type __r = 0; - if (__np != nullptr) - { - for (__np = __np->__next_; __np != nullptr && - std::__constrain_hash(__np->__hash(), __bc) == __n; - __np = __np->__next_, (void) ++__r) - ; - } - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < bucket_count(), "unordered container::bucket_size(n) called with n >= bucket_count()"); + __next_pointer __np = __bucket_list_[__n]; + size_type __bc = bucket_count(); + size_type __r = 0; + if (__np != nullptr) { + for (__np = __np->__next_; __np != nullptr && std::__constrain_hash(__np->__hash(), __bc) == __n; + __np = __np->__next_, (void)++__r) + ; + } + return __r; } template -inline _LIBCPP_HIDE_FROM_ABI -void -swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, - __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); +inline _LIBCPP_HIDE_FROM_ABI void +swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { + __x.swap(__y); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__ios/fpos.h b/libcxx/include/__ios/fpos.h index ae578bdbb916c031e7c769a0c9dc5658f2039310..1af1e23ee50da1a3eb4ae7d7f57471fc49d6abb9 100644 --- a/libcxx/include/__ios/fpos.h +++ b/libcxx/include/__ios/fpos.h @@ -57,20 +57,17 @@ public: }; template -inline _LIBCPP_HIDE_FROM_ABI -streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { +inline _LIBCPP_HIDE_FROM_ABI streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { return streamoff(__x) - streamoff(__y); } template -inline _LIBCPP_HIDE_FROM_ABI -bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { +inline _LIBCPP_HIDE_FROM_ABI bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { return streamoff(__x) == streamoff(__y); } template -inline _LIBCPP_HIDE_FROM_ABI -bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { return streamoff(__x) != streamoff(__y); } diff --git a/libcxx/include/__iterator/access.h b/libcxx/include/__iterator/access.h index 3ab3955e12a5bdfc0b3c58d70c70f6af8bc8a715..5c6090eeb40c59fcfc08cfa035020442c8864894 100644 --- a/libcxx/include/__iterator/access.h +++ b/libcxx/include/__iterator/access.h @@ -32,85 +32,60 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* end(_Tp (&__array)[_Np]) _NOEXCEPT #if !defined(_LIBCPP_CXX03_LANG) template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto -begin(_Cp& __c) -> decltype(__c.begin()) -{ - return __c.begin(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto begin(_Cp& __c) -> decltype(__c.begin()) { + return __c.begin(); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto -begin(const _Cp& __c) -> decltype(__c.begin()) -{ - return __c.begin(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto begin(const _Cp& __c) -> decltype(__c.begin()) { + return __c.begin(); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto -end(_Cp& __c) -> decltype(__c.end()) -{ - return __c.end(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto end(_Cp& __c) -> decltype(__c.end()) { + return __c.end(); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto -end(const _Cp& __c) -> decltype(__c.end()) -{ - return __c.end(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto end(const _Cp& __c) -> decltype(__c.end()) { + return __c.end(); } -#if _LIBCPP_STD_VER >= 14 +# if _LIBCPP_STD_VER >= 14 template _LIBCPP_HIDE_FROM_ABI constexpr auto cbegin(const _Cp& __c) noexcept(noexcept(std::begin(__c))) -> decltype(std::begin(__c)) { - return std::begin(__c); + return std::begin(__c); } template _LIBCPP_HIDE_FROM_ABI constexpr auto cend(const _Cp& __c) noexcept(noexcept(std::end(__c))) -> decltype(std::end(__c)) { - return std::end(__c); + return std::end(__c); } -#endif - +# endif -#else // defined(_LIBCPP_CXX03_LANG) +#else // defined(_LIBCPP_CXX03_LANG) template -_LIBCPP_HIDE_FROM_ABI -typename _Cp::iterator -begin(_Cp& __c) -{ - return __c.begin(); +_LIBCPP_HIDE_FROM_ABI typename _Cp::iterator begin(_Cp& __c) { + return __c.begin(); } template -_LIBCPP_HIDE_FROM_ABI -typename _Cp::const_iterator -begin(const _Cp& __c) -{ - return __c.begin(); +_LIBCPP_HIDE_FROM_ABI typename _Cp::const_iterator begin(const _Cp& __c) { + return __c.begin(); } template -_LIBCPP_HIDE_FROM_ABI -typename _Cp::iterator -end(_Cp& __c) -{ - return __c.end(); +_LIBCPP_HIDE_FROM_ABI typename _Cp::iterator end(_Cp& __c) { + return __c.end(); } template -_LIBCPP_HIDE_FROM_ABI -typename _Cp::const_iterator -end(const _Cp& __c) -{ - return __c.end(); +_LIBCPP_HIDE_FROM_ABI typename _Cp::const_iterator end(const _Cp& __c) { + return __c.end(); } #endif // !defined(_LIBCPP_CXX03_LANG) diff --git a/libcxx/include/__iterator/advance.h b/libcxx/include/__iterator/advance.h index 76938970b0c348f705a186bd2b4e84efb0dbba60..64c8d249f78f3ecb839feff28582d3ef799bf032 100644 --- a/libcxx/include/__iterator/advance.h +++ b/libcxx/include/__iterator/advance.h @@ -35,15 +35,15 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -void __advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void +__advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) { for (; __n > 0; --__n) ++__i; } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void +__advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) { if (__n >= 0) for (; __n > 0; --__n) ++__i; @@ -53,17 +53,16 @@ void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -void __advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void +__advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) { __i += __n; } -template < - class _InputIter, class _Distance, - class _IntegralDistance = decltype(std::__convert_to_integral(std::declval<_Distance>())), - class = __enable_if_t::value> > -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -void advance(_InputIter& __i, _Distance __orig_n) { +template < class _InputIter, + class _Distance, + class _IntegralDistance = decltype(std::__convert_to_integral(std::declval<_Distance>())), + class = __enable_if_t::value> > +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void advance(_InputIter& __i, _Distance __orig_n) { typedef typename iterator_traits<_InputIter>::difference_type _Difference; _Difference __n = static_cast<_Difference>(std::__convert_to_integral(__orig_n)); _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value, @@ -81,8 +80,7 @@ namespace __advance { struct __fn { private: template - _LIBCPP_HIDE_FROM_ABI - static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) { + _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) { while (__n > 0) { --__n; ++__i; @@ -90,8 +88,7 @@ private: } template - _LIBCPP_HIDE_FROM_ABI - static constexpr void __advance_backward(_Ip& __i, iter_difference_t<_Ip> __n) { + _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_backward(_Ip& __i, iter_difference_t<_Ip> __n) { while (__n < 0) { ++__n; --__i; @@ -101,10 +98,9 @@ private: public: // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative. template - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const { - _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || bidirectional_iterator<_Ip>, - "If `n < 0`, then `bidirectional_iterator` must be true."); + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const { + _LIBCPP_ASSERT_UNCATEGORIZED( + __n >= 0 || bidirectional_iterator<_Ip>, "If `n < 0`, then `bidirectional_iterator` must be true."); // If `I` models `random_access_iterator`, equivalent to `i += n`. if constexpr (random_access_iterator<_Ip>) { @@ -123,14 +119,16 @@ public: } } - // Preconditions: Either `assignable_from || sized_sentinel_for` is modeled, or [i, bound_sentinel) denotes a range. + // Preconditions: Either `assignable_from || sized_sentinel_for` is modeled, or [i, bound_sentinel) + // denotes a range. template _Sp> _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, _Sp __bound_sentinel) const { // If `I` and `S` model `assignable_from`, equivalent to `i = std::move(bound_sentinel)`. if constexpr (assignable_from<_Ip&, _Sp>) { __i = std::move(__bound_sentinel); } - // Otherwise, if `S` and `I` model `sized_sentinel_for`, equivalent to `ranges::advance(i, bound_sentinel - i)`. + // Otherwise, if `S` and `I` model `sized_sentinel_for`, equivalent to `ranges::advance(i, bound_sentinel - + // i)`. else if constexpr (sized_sentinel_for<_Sp, _Ip>) { (*this)(__i, __bound_sentinel - __i); } @@ -145,22 +143,19 @@ public: // Preconditions: // * If `n > 0`, [i, bound_sentinel) denotes a range. // * If `n == 0`, [i, bound_sentinel) or [bound_sentinel, i) denotes a range. - // * If `n < 0`, [bound_sentinel, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as`. + // * If `n < 0`, [bound_sentinel, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model + // `same_as`. // Returns: `n - M`, where `M` is the difference between the ending and starting position. template _Sp> - _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, - _Sp __bound_sentinel) const { + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> + operator()(_Ip& __i, iter_difference_t<_Ip> __n, _Sp __bound_sentinel) const { _LIBCPP_ASSERT_UNCATEGORIZED((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>), "If `n < 0`, then `bidirectional_iterator && same_as` must be true."); // If `S` and `I` model `sized_sentinel_for`: if constexpr (sized_sentinel_for<_Sp, _Ip>) { // If |n| >= |bound_sentinel - i|, equivalent to `ranges::advance(i, bound_sentinel)`. // __magnitude_geq(a, b) returns |a| >= |b|, assuming they have the same sign. - auto __magnitude_geq = [](auto __a, auto __b) { - return __a == 0 ? __b == 0 : - __a > 0 ? __a >= __b : - __a <= __b; - }; + auto __magnitude_geq = [](auto __a, auto __b) { return __a == 0 ? __b == 0 : __a > 0 ? __a >= __b : __a <= __b; }; if (const auto __m = __bound_sentinel - __i; __magnitude_geq(__n, __m)) { (*this)(__i, __bound_sentinel); return __n - __m; @@ -194,7 +189,7 @@ public: } // namespace __advance inline namespace __cpo { - inline constexpr auto advance = __advance::__fn{}; +inline constexpr auto advance = __advance::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/libcxx/include/__iterator/back_insert_iterator.h b/libcxx/include/__iterator/back_insert_iterator.h index f022d3bdf8dd100627c484ceb39e1ca3221d693f..6d3dd4b12966fe7547fcbfd73173b60c6569a20b 100644 --- a/libcxx/include/__iterator/back_insert_iterator.h +++ b/libcxx/include/__iterator/back_insert_iterator.h @@ -33,42 +33,49 @@ class _LIBCPP_TEMPLATE_VIS back_insert_iterator : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + protected: - _Container* container; + _Container* container; + public: - typedef output_iterator_tag iterator_category; - typedef void value_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; #if _LIBCPP_STD_VER >= 20 - typedef ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; #else - typedef void difference_type; + typedef void difference_type; #endif - typedef void pointer; - typedef void reference; - typedef _Container container_type; + typedef void pointer; + typedef void reference; + typedef _Container container_type; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit back_insert_iterator(_Container& __x) : container(std::addressof(__x)) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator=(const typename _Container::value_type& __value) - {container->push_back(__value); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit back_insert_iterator(_Container& __x) + : container(std::addressof(__x)) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& + operator=(const typename _Container::value_type& __value) { + container->push_back(__value); + return *this; + } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator=(typename _Container::value_type&& __value) - {container->push_back(std::move(__value)); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& + operator=(typename _Container::value_type&& __value) { + container->push_back(std::move(__value)); + return *this; + } #endif // _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator*() {return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator++() {return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator operator++(int) {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator operator++(int) { return *this; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Container* __get_container() const { return container; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Container* __get_container() const { return container; } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(back_insert_iterator); template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -back_insert_iterator<_Container> -back_inserter(_Container& __x) -{ - return back_insert_iterator<_Container>(__x); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator<_Container> +back_inserter(_Container& __x) { + return back_insert_iterator<_Container>(__x); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/common_iterator.h b/libcxx/include/__iterator/common_iterator.h index d7c308d8da00e6fe1f38108eef7baa5cb3feb05a..cc49d62cd04dd49089a498d579aa12f8c705d52f 100644 --- a/libcxx/include/__iterator/common_iterator.h +++ b/libcxx/include/__iterator/common_iterator.h @@ -41,13 +41,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template +template concept __can_use_postfix_proxy = - constructible_from, iter_reference_t<_Iter>> && - move_constructible>; + constructible_from, iter_reference_t<_Iter>> && move_constructible>; -template _Sent> - requires (!same_as<_Iter, _Sent> && copyable<_Iter>) +template _Sent> + requires(!same_as<_Iter, _Sent> && copyable<_Iter>) class common_iterator { struct __proxy { _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>* operator->() const noexcept { @@ -57,42 +56,42 @@ class common_iterator { }; struct __postfix_proxy { - _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>& operator*() const noexcept { - return __value_; - } + _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>& operator*() const noexcept { return __value_; } iter_value_t<_Iter> __value_; }; variant<_Iter, _Sent> __hold_; - template _OtherSent> - requires (!same_as<_OtherIter, _OtherSent> && copyable<_OtherIter>) + template _OtherSent> + requires(!same_as<_OtherIter, _OtherSent> && copyable<_OtherIter>) friend class common_iterator; public: - _LIBCPP_HIDE_FROM_ABI common_iterator() requires default_initializable<_Iter> = default; + _LIBCPP_HIDE_FROM_ABI common_iterator() + requires default_initializable<_Iter> + = default; _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, std::move(__i)) {} _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, std::move(__s)) {} - template + template requires convertible_to && convertible_to _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(const common_iterator<_I2, _S2>& __other) - : __hold_([&]() -> variant<_Iter, _Sent> { - _LIBCPP_ASSERT_UNCATEGORIZED(!__other.__hold_.valueless_by_exception(), - "Attempted to construct from a valueless common_iterator"); - if (__other.__hold_.index() == 0) - return variant<_Iter, _Sent>{in_place_index<0>, std::__unchecked_get<0>(__other.__hold_)}; - return variant<_Iter, _Sent>{in_place_index<1>, std::__unchecked_get<1>(__other.__hold_)}; - }()) {} - - template + : __hold_([&]() -> variant<_Iter, _Sent> { + _LIBCPP_ASSERT_UNCATEGORIZED( + !__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator"); + if (__other.__hold_.index() == 0) + return variant<_Iter, _Sent>{in_place_index<0>, std::__unchecked_get<0>(__other.__hold_)}; + return variant<_Iter, _Sent>{in_place_index<1>, std::__unchecked_get<1>(__other.__hold_)}; + }()) {} + + template requires convertible_to && convertible_to && assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&> _LIBCPP_HIDE_FROM_ABI common_iterator& operator=(const common_iterator<_I2, _S2>& __other) { - _LIBCPP_ASSERT_UNCATEGORIZED(!__other.__hold_.valueless_by_exception(), - "Attempted to assign from a valueless common_iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED( + !__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator"); - auto __idx = __hold_.index(); + auto __idx = __hold_.index(); auto __other_idx = __other.__hold_.index(); // If they're the same index, just assign. @@ -110,31 +109,29 @@ public: return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() - { - _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_), - "Attempted to dereference a non-dereferenceable common_iterator"); + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() { + _LIBCPP_ASSERT_UNCATEGORIZED( + std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); return *std::__unchecked_get<_Iter>(__hold_); } _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const requires __dereferenceable { - _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_), - "Attempted to dereference a non-dereferenceable common_iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED( + std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); return *std::__unchecked_get<_Iter>(__hold_); } - template + template _LIBCPP_HIDE_FROM_ABI decltype(auto) operator->() const - requires indirectly_readable && - (requires(const _I2& __i) { __i.operator->(); } || - is_reference_v> || - constructible_from, iter_reference_t<_I2>>) + requires indirectly_readable && (requires(const _I2& __i) { + __i.operator->(); + } || is_reference_v> || constructible_from, iter_reference_t<_I2>>) { - _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_), - "Attempted to dereference a non-dereferenceable common_iterator"); - if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { + _LIBCPP_ASSERT_UNCATEGORIZED( + std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); + if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { return std::__unchecked_get<_Iter>(__hold_); } else if constexpr (is_reference_v>) { auto&& __tmp = *std::__unchecked_get<_Iter>(__hold_); @@ -145,20 +142,22 @@ public: } _LIBCPP_HIDE_FROM_ABI common_iterator& operator++() { - _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_), - "Attempted to increment a non-dereferenceable common_iterator"); - ++std::__unchecked_get<_Iter>(__hold_); return *this; + _LIBCPP_ASSERT_UNCATEGORIZED( + std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); + ++std::__unchecked_get<_Iter>(__hold_); + return *this; } _LIBCPP_HIDE_FROM_ABI decltype(auto) operator++(int) { - _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_), - "Attempted to increment a non-dereferenceable common_iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED( + std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); if constexpr (forward_iterator<_Iter>) { auto __tmp = *this; ++*this; return __tmp; - } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __can_reference; } || - !__can_use_postfix_proxy<_Iter>) { + } else if constexpr (requires(_Iter& __i) { + { *__i++ } -> __can_reference; + } || !__can_use_postfix_proxy<_Iter>) { return std::__unchecked_get<_Iter>(__hold_)++; } else { auto __p = __postfix_proxy{**this}; @@ -167,14 +166,14 @@ public: } } - template _S2> + template _S2> requires sentinel_for<_Sent, _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(), - "Attempted to compare a valueless common_iterator"); - _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(), - "Attempted to compare a valueless common_iterator"); + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT_UNCATEGORIZED( + !__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED( + !__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -188,14 +187,14 @@ public: return std::__unchecked_get<_Sent>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); } - template _S2> + template _S2> requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(), - "Attempted to compare a valueless common_iterator"); - _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(), - "Attempted to compare a valueless common_iterator"); + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT_UNCATEGORIZED( + !__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED( + !__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -204,22 +203,22 @@ public: return true; if (__x_index == 0 && __y_index == 0) - return std::__unchecked_get<_Iter>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); + return std::__unchecked_get<_Iter>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); if (__x_index == 0) - return std::__unchecked_get<_Iter>(__x.__hold_) == std::__unchecked_get<_S2>(__y.__hold_); + return std::__unchecked_get<_Iter>(__x.__hold_) == std::__unchecked_get<_S2>(__y.__hold_); - return std::__unchecked_get<_Sent>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); + return std::__unchecked_get<_Sent>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); } - template _I2, sized_sentinel_for<_Iter> _S2> + template _I2, sized_sentinel_for<_Iter> _S2> requires sized_sentinel_for<_Sent, _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(), - "Attempted to subtract from a valueless common_iterator"); - _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(), - "Attempted to subtract a valueless common_iterator"); + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_I2> + operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT_UNCATEGORIZED( + !__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED( + !__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -228,73 +227,67 @@ public: return 0; if (__x_index == 0 && __y_index == 0) - return std::__unchecked_get<_Iter>(__x.__hold_) - std::__unchecked_get<_I2>(__y.__hold_); + return std::__unchecked_get<_Iter>(__x.__hold_) - std::__unchecked_get<_I2>(__y.__hold_); if (__x_index == 0) - return std::__unchecked_get<_Iter>(__x.__hold_) - std::__unchecked_get<_S2>(__y.__hold_); + return std::__unchecked_get<_Iter>(__x.__hold_) - std::__unchecked_get<_S2>(__y.__hold_); return std::__unchecked_get<_Sent>(__x.__hold_) - std::__unchecked_get<_I2>(__y.__hold_); } - _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i) - noexcept(noexcept(ranges::iter_move(std::declval()))) - requires input_iterator<_Iter> + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> + iter_move(const common_iterator& __i) noexcept(noexcept(ranges::iter_move(std::declval()))) + requires input_iterator<_Iter> { - _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__i.__hold_), - "Attempted to iter_move a non-dereferenceable common_iterator"); - return ranges::iter_move( std::__unchecked_get<_Iter>(__i.__hold_)); + _LIBCPP_ASSERT_UNCATEGORIZED( + std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator"); + return ranges::iter_move(std::__unchecked_get<_Iter>(__i.__hold_)); } - template _I2, class _S2> - _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) - noexcept(noexcept(ranges::iter_swap(std::declval(), std::declval()))) - { - _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__x.__hold_), - "Attempted to iter_swap a non-dereferenceable common_iterator"); - _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_I2>(__y.__hold_), - "Attempted to iter_swap a non-dereferenceable common_iterator"); + template _I2, class _S2> + _LIBCPP_HIDE_FROM_ABI friend constexpr void + iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) noexcept( + noexcept(ranges::iter_swap(std::declval(), std::declval()))) { + _LIBCPP_ASSERT_UNCATEGORIZED( + std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED( + std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); return ranges::iter_swap(std::__unchecked_get<_Iter>(__x.__hold_), std::__unchecked_get<_I2>(__y.__hold_)); } }; -template +template struct incrementable_traits> { using difference_type = iter_difference_t<_Iter>; }; -template -concept __denotes_forward_iter = - requires { typename iterator_traits<_Iter>::iterator_category; } && - derived_from::iterator_category, forward_iterator_tag>; +template +concept __denotes_forward_iter = requires { + typename iterator_traits<_Iter>::iterator_category; +} && derived_from::iterator_category, forward_iterator_tag>; -template -concept __common_iter_has_ptr_op = requires(const common_iterator<_Iter, _Sent>& __a) { - __a.operator->(); -}; +template +concept __common_iter_has_ptr_op = requires(const common_iterator<_Iter, _Sent>& __a) { __a.operator->(); }; -template +template struct __arrow_type_or_void { - using type = void; + using type = void; }; -template +template requires __common_iter_has_ptr_op<_Iter, _Sent> struct __arrow_type_or_void<_Iter, _Sent> { - using type = decltype(std::declval&>().operator->()); + using type = decltype(std::declval&>().operator->()); }; -template +template struct iterator_traits> { - using iterator_concept = _If, - forward_iterator_tag, - input_iterator_tag>; - using iterator_category = _If<__denotes_forward_iter<_Iter>, - forward_iterator_tag, - input_iterator_tag>; - using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type; - using value_type = iter_value_t<_Iter>; - using difference_type = iter_difference_t<_Iter>; - using reference = iter_reference_t<_Iter>; + using iterator_concept = _If, forward_iterator_tag, input_iterator_tag>; + using iterator_category = _If<__denotes_forward_iter<_Iter>, forward_iterator_tag, input_iterator_tag>; + using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; }; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h index 614de85847a09031a459881f2016ccca64b62841..afb7b821a99ce6dc88cc109c11e27c2f3104f0b9 100644 --- a/libcxx/include/__iterator/concepts.h +++ b/libcxx/include/__iterator/concepts.h @@ -49,246 +49,198 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 // [iterator.concept.readable] -template +template concept __indirectly_readable_impl = - requires(const _In __i) { - typename iter_value_t<_In>; - typename iter_reference_t<_In>; - typename iter_rvalue_reference_t<_In>; - { *__i } -> same_as>; - { ranges::iter_move(__i) } -> same_as>; - } && - common_reference_with&&, iter_value_t<_In>&> && - common_reference_with&&, iter_rvalue_reference_t<_In>&&> && - common_reference_with&&, const iter_value_t<_In>&>; - -template + requires(const _In __i) { + typename iter_value_t<_In>; + typename iter_reference_t<_In>; + typename iter_rvalue_reference_t<_In>; + { *__i } -> same_as>; + { ranges::iter_move(__i) } -> same_as>; + } && common_reference_with&&, iter_value_t<_In>&> && + common_reference_with&&, iter_rvalue_reference_t<_In>&&> && + common_reference_with&&, const iter_value_t<_In>&>; + +template concept indirectly_readable = __indirectly_readable_impl>; -template +template using iter_common_reference_t = common_reference_t, iter_value_t<_Tp>&>; // [iterator.concept.writable] -template -concept indirectly_writable = - requires(_Out&& __o, _Tp&& __t) { - *__o = std::forward<_Tp>(__t); // not required to be equality-preserving - *std::forward<_Out>(__o) = std::forward<_Tp>(__t); // not required to be equality-preserving - const_cast&&>(*__o) = std::forward<_Tp>(__t); // not required to be equality-preserving - const_cast&&>(*std::forward<_Out>(__o)) = std::forward<_Tp>(__t); // not required to be equality-preserving - }; +template +concept indirectly_writable = requires(_Out&& __o, _Tp&& __t) { + *__o = std::forward<_Tp>(__t); // not required to be equality-preserving + *std::forward<_Out>(__o) = std::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*__o) = std::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*std::forward<_Out>(__o)) = + std::forward<_Tp>(__t); // not required to be equality-preserving +}; // [iterator.concept.winc] -template +template concept __integer_like = integral<_Tp> && !same_as<_Tp, bool>; -template +template concept __signed_integer_like = signed_integral<_Tp>; -template +template concept weakly_incrementable = - // TODO: remove this once the clang bug is fixed (bugs.llvm.org/PR48173). - !same_as<_Ip, bool> && // Currently, clang does not handle bool correctly. - movable<_Ip> && - requires(_Ip __i) { - typename iter_difference_t<_Ip>; - requires __signed_integer_like>; - { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving - __i++; // not required to be equality-preserving - }; + // TODO: remove this once the clang bug is fixed (bugs.llvm.org/PR48173). + !same_as<_Ip, bool> && // Currently, clang does not handle bool correctly. + movable<_Ip> && requires(_Ip __i) { + typename iter_difference_t<_Ip>; + requires __signed_integer_like>; + { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving + __i++; // not required to be equality-preserving + }; // [iterator.concept.inc] -template -concept incrementable = - regular<_Ip> && - weakly_incrementable<_Ip> && - requires(_Ip __i) { - { __i++ } -> same_as<_Ip>; - }; +template +concept incrementable = regular<_Ip> && weakly_incrementable<_Ip> && requires(_Ip __i) { + { __i++ } -> same_as<_Ip>; +}; // [iterator.concept.iterator] -template -concept input_or_output_iterator = - requires(_Ip __i) { - { *__i } -> __can_reference; - } && - weakly_incrementable<_Ip>; +template +concept input_or_output_iterator = requires(_Ip __i) { + { *__i } -> __can_reference; +} && weakly_incrementable<_Ip>; // [iterator.concept.sentinel] -template -concept sentinel_for = - semiregular<_Sp> && - input_or_output_iterator<_Ip> && - __weakly_equality_comparable_with<_Sp, _Ip>; +template +concept sentinel_for = semiregular<_Sp> && input_or_output_iterator<_Ip> && __weakly_equality_comparable_with<_Sp, _Ip>; -template +template inline constexpr bool disable_sized_sentinel_for = false; -template +template concept sized_sentinel_for = - sentinel_for<_Sp, _Ip> && - !disable_sized_sentinel_for, remove_cv_t<_Ip>> && - requires(const _Ip& __i, const _Sp& __s) { - { __s - __i } -> same_as>; - { __i - __s } -> same_as>; - }; + sentinel_for<_Sp, _Ip> && !disable_sized_sentinel_for, remove_cv_t<_Ip>> && + requires(const _Ip& __i, const _Sp& __s) { + { __s - __i } -> same_as>; + { __i - __s } -> same_as>; + }; // [iterator.concept.input] -template -concept input_iterator = - input_or_output_iterator<_Ip> && - indirectly_readable<_Ip> && - requires { typename _ITER_CONCEPT<_Ip>; } && - derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>; +template +concept input_iterator = input_or_output_iterator<_Ip> && indirectly_readable<_Ip> && requires { + typename _ITER_CONCEPT<_Ip>; +} && derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>; // [iterator.concept.output] -template +template concept output_iterator = - input_or_output_iterator<_Ip> && - indirectly_writable<_Ip, _Tp> && - requires (_Ip __it, _Tp&& __t) { - *__it++ = std::forward<_Tp>(__t); // not required to be equality-preserving - }; + input_or_output_iterator<_Ip> && indirectly_writable<_Ip, _Tp> && requires(_Ip __it, _Tp&& __t) { + *__it++ = std::forward<_Tp>(__t); // not required to be equality-preserving + }; // [iterator.concept.forward] -template +template concept forward_iterator = - input_iterator<_Ip> && - derived_from<_ITER_CONCEPT<_Ip>, forward_iterator_tag> && - incrementable<_Ip> && - sentinel_for<_Ip, _Ip>; + input_iterator<_Ip> && derived_from<_ITER_CONCEPT<_Ip>, forward_iterator_tag> && incrementable<_Ip> && + sentinel_for<_Ip, _Ip>; // [iterator.concept.bidir] -template +template concept bidirectional_iterator = - forward_iterator<_Ip> && - derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> && - requires(_Ip __i) { - { --__i } -> same_as<_Ip&>; - { __i-- } -> same_as<_Ip>; - }; - -template + forward_iterator<_Ip> && derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> && requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> same_as<_Ip>; + }; + +template concept random_access_iterator = - bidirectional_iterator<_Ip> && - derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> && - totally_ordered<_Ip> && - sized_sentinel_for<_Ip, _Ip> && - requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) { - { __i += __n } -> same_as<_Ip&>; - { __j + __n } -> same_as<_Ip>; - { __n + __j } -> same_as<_Ip>; - { __i -= __n } -> same_as<_Ip&>; - { __j - __n } -> same_as<_Ip>; - { __j[__n] } -> same_as>; - }; - -template + bidirectional_iterator<_Ip> && derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> && + totally_ordered<_Ip> && sized_sentinel_for<_Ip, _Ip> && + requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) { + { __i += __n } -> same_as<_Ip&>; + { __j + __n } -> same_as<_Ip>; + { __n + __j } -> same_as<_Ip>; + { __i -= __n } -> same_as<_Ip&>; + { __j - __n } -> same_as<_Ip>; + { __j[__n] } -> same_as>; + }; + +template concept contiguous_iterator = - random_access_iterator<_Ip> && - derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> && - is_lvalue_reference_v> && - same_as, remove_cvref_t>> && - requires(const _Ip& __i) { - { std::to_address(__i) } -> same_as>>; - }; - -template + random_access_iterator<_Ip> && derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> && + is_lvalue_reference_v> && same_as, remove_cvref_t>> && + requires(const _Ip& __i) { + { std::to_address(__i) } -> same_as>>; + }; + +template concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip __i) { __i.operator->(); }); // [indirectcallable.indirectinvocable] -template +template concept indirectly_unary_invocable = - indirectly_readable<_It> && - copy_constructible<_Fp> && - invocable<_Fp&, iter_value_t<_It>&> && - invocable<_Fp&, iter_reference_t<_It>> && - invocable<_Fp&, iter_common_reference_t<_It>> && - common_reference_with< - invoke_result_t<_Fp&, iter_value_t<_It>&>, - invoke_result_t<_Fp&, iter_reference_t<_It>>>; - -template + indirectly_readable<_It> && copy_constructible<_Fp> && invocable<_Fp&, iter_value_t<_It>&> && + invocable<_Fp&, iter_reference_t<_It>> && invocable<_Fp&, iter_common_reference_t<_It>> && + common_reference_with< invoke_result_t<_Fp&, iter_value_t<_It>&>, invoke_result_t<_Fp&, iter_reference_t<_It>>>; + +template concept indirectly_regular_unary_invocable = - indirectly_readable<_It> && - copy_constructible<_Fp> && - regular_invocable<_Fp&, iter_value_t<_It>&> && - regular_invocable<_Fp&, iter_reference_t<_It>> && - regular_invocable<_Fp&, iter_common_reference_t<_It>> && - common_reference_with< - invoke_result_t<_Fp&, iter_value_t<_It>&>, - invoke_result_t<_Fp&, iter_reference_t<_It>>>; - -template + indirectly_readable<_It> && copy_constructible<_Fp> && regular_invocable<_Fp&, iter_value_t<_It>&> && + regular_invocable<_Fp&, iter_reference_t<_It>> && regular_invocable<_Fp&, iter_common_reference_t<_It>> && + common_reference_with< invoke_result_t<_Fp&, iter_value_t<_It>&>, invoke_result_t<_Fp&, iter_reference_t<_It>>>; + +template concept indirect_unary_predicate = - indirectly_readable<_It> && - copy_constructible<_Fp> && - predicate<_Fp&, iter_value_t<_It>&> && - predicate<_Fp&, iter_reference_t<_It>> && - predicate<_Fp&, iter_common_reference_t<_It>>; + indirectly_readable<_It> && copy_constructible<_Fp> && predicate<_Fp&, iter_value_t<_It>&> && + predicate<_Fp&, iter_reference_t<_It>> && predicate<_Fp&, iter_common_reference_t<_It>>; -template +template concept indirect_binary_predicate = - indirectly_readable<_It1> && indirectly_readable<_It2> && - copy_constructible<_Fp> && - predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && - predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && - predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && - predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && - predicate<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; - -template + indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fp> && + predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && + predicate<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + +template concept indirect_equivalence_relation = - indirectly_readable<_It1> && indirectly_readable<_It2> && - copy_constructible<_Fp> && - equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && - equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && - equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && - equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && - equivalence_relation<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; - -template + indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fp> && + equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && + equivalence_relation<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + +template concept indirect_strict_weak_order = - indirectly_readable<_It1> && indirectly_readable<_It2> && - copy_constructible<_Fp> && - strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && - strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && - strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && - strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && - strict_weak_order<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; - -template - requires (indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...> + indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fp> && + strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && + strict_weak_order<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + +template + requires(indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...> using indirect_result_t = invoke_result_t<_Fp, iter_reference_t<_Its>...>; -template -concept indirectly_movable = - indirectly_readable<_In> && - indirectly_writable<_Out, iter_rvalue_reference_t<_In>>; +template +concept indirectly_movable = indirectly_readable<_In> && indirectly_writable<_Out, iter_rvalue_reference_t<_In>>; -template +template concept indirectly_movable_storable = - indirectly_movable<_In, _Out> && - indirectly_writable<_Out, iter_value_t<_In>> && - movable> && - constructible_from, iter_rvalue_reference_t<_In>> && - assignable_from&, iter_rvalue_reference_t<_In>>; - -template -concept indirectly_copyable = - indirectly_readable<_In> && - indirectly_writable<_Out, iter_reference_t<_In>>; - -template + indirectly_movable<_In, _Out> && indirectly_writable<_Out, iter_value_t<_In>> && movable> && + constructible_from, iter_rvalue_reference_t<_In>> && + assignable_from&, iter_rvalue_reference_t<_In>>; + +template +concept indirectly_copyable = indirectly_readable<_In> && indirectly_writable<_Out, iter_reference_t<_In>>; + +template concept indirectly_copyable_storable = - indirectly_copyable<_In, _Out> && - indirectly_writable<_Out, iter_value_t<_In>&> && - indirectly_writable<_Out, const iter_value_t<_In>&> && - indirectly_writable<_Out, iter_value_t<_In>&&> && - indirectly_writable<_Out, const iter_value_t<_In>&&> && - copyable> && - constructible_from, iter_reference_t<_In>> && - assignable_from&, iter_reference_t<_In>>; + indirectly_copyable<_In, _Out> && indirectly_writable<_Out, iter_value_t<_In>&> && + indirectly_writable<_Out, const iter_value_t<_In>&> && indirectly_writable<_Out, iter_value_t<_In>&&> && + indirectly_writable<_Out, const iter_value_t<_In>&&> && copyable> && + constructible_from, iter_reference_t<_In>> && + assignable_from&, iter_reference_t<_In>>; // Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle // (both iter_swap and indirectly_swappable require indirectly_readable). @@ -298,10 +250,10 @@ concept indirectly_copyable_storable = template using __has_random_access_iterator_category_or_concept #if _LIBCPP_STD_VER >= 20 - = integral_constant>; -#else // _LIBCPP_STD_VER < 20 - = __has_random_access_iterator_category<_Tp>; -#endif // _LIBCPP_STD_VER + = integral_constant>; +#else // _LIBCPP_STD_VER < 20 + = __has_random_access_iterator_category<_Tp>; +#endif // _LIBCPP_STD_VER _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/counted_iterator.h b/libcxx/include/__iterator/counted_iterator.h index 171c0d7f0e77262bb380a7c4a9c91dfae3918498..c72ac677ff2f892b2df58f79d1f7ee8ea597fe4b 100644 --- a/libcxx/include/__iterator/counted_iterator.h +++ b/libcxx/include/__iterator/counted_iterator.h @@ -41,118 +41,110 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template +template struct __counted_iterator_concept {}; -template +template requires requires { typename _Iter::iterator_concept; } struct __counted_iterator_concept<_Iter> { using iterator_concept = typename _Iter::iterator_concept; }; -template +template struct __counted_iterator_category {}; -template +template requires requires { typename _Iter::iterator_category; } struct __counted_iterator_category<_Iter> { using iterator_category = typename _Iter::iterator_category; }; -template +template struct __counted_iterator_value_type {}; -template +template struct __counted_iterator_value_type<_Iter> { using value_type = iter_value_t<_Iter>; }; -template +template class counted_iterator - : public __counted_iterator_concept<_Iter> - , public __counted_iterator_category<_Iter> - , public __counted_iterator_value_type<_Iter> -{ + : public __counted_iterator_concept<_Iter>, + public __counted_iterator_category<_Iter>, + public __counted_iterator_value_type<_Iter> { public: - using iterator_type = _Iter; + using iterator_type = _Iter; using difference_type = iter_difference_t<_Iter>; - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator() requires default_initializable<_Iter> = default; + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator() + requires default_initializable<_Iter> + = default; - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n) - : __current_(std::move(__iter)), __count_(__n) { + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n) + : __current_(std::move(__iter)), __count_(__n) { _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "__n must not be negative."); } - template + template requires convertible_to - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator(const counted_iterator<_I2>& __other) - : __current_(__other.__current_), __count_(__other.__count_) {} + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator(const counted_iterator<_I2>& __other) + : __current_(__other.__current_), __count_(__other.__count_) {} - template + template requires assignable_from<_Iter&, const _I2&> - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator& operator=(const counted_iterator<_I2>& __other) { + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator& operator=(const counted_iterator<_I2>& __other) { __current_ = __other.__current_; - __count_ = __other.__count_; + __count_ = __other.__count_; return *this; } - _LIBCPP_HIDE_FROM_ABI - constexpr const _Iter& base() const& noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const& noexcept { return __current_; } - _LIBCPP_HIDE_FROM_ABI - constexpr _Iter base() && { return std::move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } - _LIBCPP_HIDE_FROM_ABI - constexpr iter_difference_t<_Iter> count() const noexcept { return __count_; } + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> count() const noexcept { return __count_; } - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator*() { + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() { _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator is equal to or past end."); return *__current_; } - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator*() const + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const requires __dereferenceable { _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator is equal to or past end."); return *__current_; } - _LIBCPP_HIDE_FROM_ABI - constexpr auto operator->() const noexcept + _LIBCPP_HIDE_FROM_ABI constexpr auto operator->() const noexcept requires contiguous_iterator<_Iter> { return std::to_address(__current_); } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator& operator++() { + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator& operator++() { _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end."); ++__current_; --__count_; return *this; } - _LIBCPP_HIDE_FROM_ABI - decltype(auto) operator++(int) { + _LIBCPP_HIDE_FROM_ABI decltype(auto) operator++(int) { _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end."); --__count_; -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try { return __current_++; } - catch(...) { ++__count_; throw; } -#else +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS + try { + return __current_++; + } catch (...) { + ++__count_; + throw; + } +# else return __current_++; -#endif // _LIBCPP_HAS_NO_EXCEPTIONS +# endif // _LIBCPP_HAS_NO_EXCEPTIONS } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator operator++(int) + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator operator++(int) requires forward_iterator<_Iter> { _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end."); @@ -161,8 +153,7 @@ public: return __tmp; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator& operator--() + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator& operator--() requires bidirectional_iterator<_Iter> { --__current_; @@ -170,8 +161,7 @@ public: return *this; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator operator--(int) + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator operator--(int) requires bidirectional_iterator<_Iter> { counted_iterator __tmp = *this; @@ -179,23 +169,20 @@ public: return __tmp; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator operator+(iter_difference_t<_Iter> __n) const + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator operator+(iter_difference_t<_Iter> __n) const requires random_access_iterator<_Iter> { return counted_iterator(__current_ + __n, __count_ - __n); } - _LIBCPP_HIDE_FROM_ABI - friend constexpr counted_iterator operator+( - iter_difference_t<_Iter> __n, const counted_iterator& __x) + _LIBCPP_HIDE_FROM_ABI friend constexpr counted_iterator + operator+(iter_difference_t<_Iter> __n, const counted_iterator& __x) requires random_access_iterator<_Iter> { return __x + __n; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n) + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n) requires random_access_iterator<_Iter> { _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __count_, "Cannot advance iterator past end."); @@ -204,110 +191,92 @@ public: return *this; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator operator-(iter_difference_t<_Iter> __n) const + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator operator-(iter_difference_t<_Iter> __n) const requires random_access_iterator<_Iter> { return counted_iterator(__current_ - __n, __count_ + __n); } - template _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_I2> operator-( - const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) - { + template _I2> + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_I2> + operator-(const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) { return __rhs.__count_ - __lhs.__count_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_Iter> operator-( - const counted_iterator& __lhs, default_sentinel_t) - { + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Iter> + operator-(const counted_iterator& __lhs, default_sentinel_t) { return -__lhs.__count_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_Iter> operator-( - default_sentinel_t, const counted_iterator& __rhs) - { + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Iter> + operator-(default_sentinel_t, const counted_iterator& __rhs) { return __rhs.__count_; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n) + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n) requires random_access_iterator<_Iter> { - _LIBCPP_ASSERT_UNCATEGORIZED(-__n <= __count_, - "Attempt to subtract too large of a size: " - "counted_iterator would be decremented before the " - "first element of its range."); + _LIBCPP_ASSERT_UNCATEGORIZED( + -__n <= __count_, + "Attempt to subtract too large of a size: " + "counted_iterator would be decremented before the " + "first element of its range."); __current_ -= __n; __count_ += __n; return *this; } - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const requires random_access_iterator<_Iter> { _LIBCPP_ASSERT_UNCATEGORIZED(__n < __count_, "Subscript argument must be less than size."); return __current_[__n]; } - template _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==( - const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) - { + template _I2> + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) { return __lhs.__count_ == __rhs.__count_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==( - const counted_iterator& __lhs, default_sentinel_t) - { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const counted_iterator& __lhs, default_sentinel_t) { return __lhs.__count_ == 0; } - template _I2> - _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering operator<=>( - const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) - { + template _I2> + _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering + operator<=>(const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) { return __rhs.__count_ <=> __lhs.__count_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const counted_iterator& __i) - noexcept(noexcept(ranges::iter_move(__i.__current_))) - requires input_iterator<_Iter> + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> + iter_move(const counted_iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__current_))) + requires input_iterator<_Iter> { _LIBCPP_ASSERT_UNCATEGORIZED(__i.__count_ > 0, "Iterator must not be past end of range."); return ranges::iter_move(__i.__current_); } - template _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr void iter_swap(const counted_iterator& __x, const counted_iterator<_I2>& __y) - noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) - { - _LIBCPP_ASSERT_UNCATEGORIZED(__x.__count_ > 0 && __y.__count_ > 0, - "Iterators must not be past end of range."); + template _I2> + _LIBCPP_HIDE_FROM_ABI friend constexpr void + iter_swap(const counted_iterator& __x, + const counted_iterator<_I2>& __y) noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) { + _LIBCPP_ASSERT_UNCATEGORIZED(__x.__count_ > 0 && __y.__count_ > 0, "Iterators must not be past end of range."); return ranges::iter_swap(__x.__current_, __y.__current_); } private: _LIBCPP_NO_UNIQUE_ADDRESS _Iter __current_ = _Iter(); - iter_difference_t<_Iter> __count_ = 0; - template + iter_difference_t<_Iter> __count_ = 0; + template friend class counted_iterator; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(counted_iterator); -template +template requires same_as<_ITER_TRAITS<_Iter>, iterator_traits<_Iter>> struct iterator_traits> : iterator_traits<_Iter> { - using pointer = conditional_t, - add_pointer_t>, void>; + using pointer = conditional_t, add_pointer_t>, void>; }; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/data.h b/libcxx/include/__iterator/data.h index 894de49991d6e605ea82b43a4da442fb380e5c75..398673906101723c71a2b89ee1ad0216e832770d 100644 --- a/libcxx/include/__iterator/data.h +++ b/libcxx/include/__iterator/data.h @@ -22,27 +22,25 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 -template constexpr -_LIBCPP_HIDE_FROM_ABI -auto data(_Cont& __c) -_NOEXCEPT_(noexcept(__c.data())) --> decltype (__c.data()) -{ return __c.data(); } - -template constexpr -_LIBCPP_HIDE_FROM_ABI -auto data(const _Cont& __c) -_NOEXCEPT_(noexcept(__c.data())) --> decltype (__c.data()) -{ return __c.data(); } +template +constexpr _LIBCPP_HIDE_FROM_ABI auto data(_Cont& __c) _NOEXCEPT_(noexcept(__c.data())) -> decltype(__c.data()) { + return __c.data(); +} + +template +constexpr _LIBCPP_HIDE_FROM_ABI auto data(const _Cont& __c) _NOEXCEPT_(noexcept(__c.data())) -> decltype(__c.data()) { + return __c.data(); +} template -_LIBCPP_HIDE_FROM_ABI -constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; } +_LIBCPP_HIDE_FROM_ABI constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { + return __array; +} template -_LIBCPP_HIDE_FROM_ABI -constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); } +_LIBCPP_HIDE_FROM_ABI constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { + return __il.begin(); +} #endif diff --git a/libcxx/include/__iterator/default_sentinel.h b/libcxx/include/__iterator/default_sentinel.h index d5fb2b699ad442a5bfe661613083213868a500de..3b65f442f1a85ba5f8b68402ff8a694aa1ca797a 100644 --- a/libcxx/include/__iterator/default_sentinel.h +++ b/libcxx/include/__iterator/default_sentinel.h @@ -20,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -struct default_sentinel_t { }; +struct default_sentinel_t {}; inline constexpr default_sentinel_t default_sentinel{}; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/distance.h b/libcxx/include/__iterator/distance.h index 83a92653909564f8f86f59bc60567c43ffae7313..75bd49c9ae732b1008bbdab6e69d4d4160803ffd 100644 --- a/libcxx/include/__iterator/distance.h +++ b/libcxx/include/__iterator/distance.h @@ -27,30 +27,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -typename iterator_traits<_InputIter>::difference_type -__distance(_InputIter __first, _InputIter __last, input_iterator_tag) -{ - typename iterator_traits<_InputIter>::difference_type __r(0); - for (; __first != __last; ++__first) - ++__r; - return __r; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type +__distance(_InputIter __first, _InputIter __last, input_iterator_tag) { + typename iterator_traits<_InputIter>::difference_type __r(0); + for (; __first != __last; ++__first) + ++__r; + return __r; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -typename iterator_traits<_RandIter>::difference_type -__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) -{ - return __last - __first; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_RandIter>::difference_type +__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) { + return __last - __first; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -typename iterator_traits<_InputIter>::difference_type -distance(_InputIter __first, _InputIter __last) -{ - return std::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type +distance(_InputIter __first, _InputIter __last) { + return std::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); } #if _LIBCPP_STD_VER >= 20 @@ -61,10 +55,9 @@ namespace ranges { namespace __distance { struct __fn { - template _Sp> - requires (!sized_sentinel_for<_Sp, _Ip>) - _LIBCPP_HIDE_FROM_ABI - constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const { + template _Sp> + requires(!sized_sentinel_for<_Sp, _Ip>) + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const { iter_difference_t<_Ip> __n = 0; while (__first != __last) { ++__first; @@ -73,9 +66,8 @@ struct __fn { return __n; } - template> _Sp> - _LIBCPP_HIDE_FROM_ABI - constexpr iter_difference_t<_Ip> operator()(_Ip&& __first, _Sp __last) const { + template > _Sp> + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip&& __first, _Sp __last) const { if constexpr (sized_sentinel_for<_Sp, __remove_cvref_t<_Ip>>) { return __last - __first; } else { @@ -83,9 +75,8 @@ struct __fn { } } - template - _LIBCPP_HIDE_FROM_ABI - constexpr range_difference_t<_Rp> operator()(_Rp&& __r) const { + template + _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Rp> operator()(_Rp&& __r) const { if constexpr (sized_range<_Rp>) { return static_cast>(ranges::size(__r)); } else { @@ -97,7 +88,7 @@ struct __fn { } // namespace __distance inline namespace __cpo { - inline constexpr auto distance = __distance::__fn{}; +inline constexpr auto distance = __distance::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/libcxx/include/__iterator/empty.h b/libcxx/include/__iterator/empty.h index 6c7b0dcb1ebca020806120e994915356997e35cb..3ca0aff6be46efb2ea7c19a241ec1cf55a4f9312 100644 --- a/libcxx/include/__iterator/empty.h +++ b/libcxx/include/__iterator/empty.h @@ -23,19 +23,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI -constexpr auto empty(const _Cont& __c) -_NOEXCEPT_(noexcept(__c.empty())) --> decltype (__c.empty()) -{ return __c.empty(); } +_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI constexpr auto empty(const _Cont& __c) + _NOEXCEPT_(noexcept(__c.empty())) -> decltype(__c.empty()) { + return __c.empty(); +} template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI -constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; } +_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI constexpr bool empty(const _Tp (&)[_Sz]) noexcept { + return false; +} template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI -constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; } +_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI constexpr bool empty(initializer_list<_Ep> __il) noexcept { + return __il.size() == 0; +} #endif // _LIBCPP_STD_VER >= 17 diff --git a/libcxx/include/__iterator/erase_if_container.h b/libcxx/include/__iterator/erase_if_container.h index 532ec9c1de0be3d617db78e6c5553260a8e6196d..0f87f50cd1c160486adeff4c2a6085a90e84a650 100644 --- a/libcxx/include/__iterator/erase_if_container.h +++ b/libcxx/include/__iterator/erase_if_container.h @@ -22,9 +22,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI -typename _Container::size_type -__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) { +_LIBCPP_HIDE_FROM_ABI typename _Container::size_type __libcpp_erase_if_container(_Container& __c, _Predicate& __pred) { typename _Container::size_type __old_size = __c.size(); const typename _Container::iterator __last = __c.end(); diff --git a/libcxx/include/__iterator/front_insert_iterator.h b/libcxx/include/__iterator/front_insert_iterator.h index f9aa442177b2c9c049a2b861d294b9894914fc57..7f2c54ec87442e20004b4d9e2f2066e81dd3aa9b 100644 --- a/libcxx/include/__iterator/front_insert_iterator.h +++ b/libcxx/include/__iterator/front_insert_iterator.h @@ -33,40 +33,47 @@ class _LIBCPP_TEMPLATE_VIS front_insert_iterator : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + protected: - _Container* container; + _Container* container; + public: - typedef output_iterator_tag iterator_category; - typedef void value_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; #if _LIBCPP_STD_VER >= 20 - typedef ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; #else - typedef void difference_type; + typedef void difference_type; #endif - typedef void pointer; - typedef void reference; - typedef _Container container_type; + typedef void pointer; + typedef void reference; + typedef _Container container_type; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit front_insert_iterator(_Container& __x) : container(std::addressof(__x)) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator=(const typename _Container::value_type& __value) - {container->push_front(__value); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit front_insert_iterator(_Container& __x) + : container(std::addressof(__x)) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& + operator=(const typename _Container::value_type& __value) { + container->push_front(__value); + return *this; + } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator=(typename _Container::value_type&& __value) - {container->push_front(std::move(__value)); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& + operator=(typename _Container::value_type&& __value) { + container->push_front(std::move(__value)); + return *this; + } #endif // _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator*() {return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator++() {return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator operator++(int) {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator operator++(int) { return *this; } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(front_insert_iterator); template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -front_insert_iterator<_Container> -front_inserter(_Container& __x) -{ - return front_insert_iterator<_Container>(__x); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator<_Container> +front_inserter(_Container& __x) { + return front_insert_iterator<_Container>(__x); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/incrementable_traits.h b/libcxx/include/__iterator/incrementable_traits.h index 604e9580ef7cadce15e3e990ef9cadf87dda46ac..a228b228f6e552046314d7dceeddf7d196327137 100644 --- a/libcxx/include/__iterator/incrementable_traits.h +++ b/libcxx/include/__iterator/incrementable_traits.h @@ -29,33 +29,33 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 // [incrementable.traits] -template struct incrementable_traits {}; +template +struct incrementable_traits {}; -template -requires is_object_v<_Tp> +template + requires is_object_v<_Tp> struct incrementable_traits<_Tp*> { using difference_type = ptrdiff_t; }; -template +template struct incrementable_traits : incrementable_traits<_Ip> {}; -template +template concept __has_member_difference_type = requires { typename _Tp::difference_type; }; -template<__has_member_difference_type _Tp> +template <__has_member_difference_type _Tp> struct incrementable_traits<_Tp> { using difference_type = typename _Tp::difference_type; }; -template -concept __has_integral_minus = - requires(const _Tp& __x, const _Tp& __y) { - { __x - __y } -> integral; - }; +template +concept __has_integral_minus = requires(const _Tp& __x, const _Tp& __y) { + { __x - __y } -> integral; +}; -template<__has_integral_minus _Tp> -requires (!__has_member_difference_type<_Tp>) +template <__has_integral_minus _Tp> + requires(!__has_member_difference_type<_Tp>) struct incrementable_traits<_Tp> { using difference_type = make_signed_t() - std::declval<_Tp>())>; }; @@ -67,9 +67,10 @@ struct iterator_traits; // `incrementable_traits::difference_type` if `iterator_traits` names a specialization // generated from the primary template, and `iterator_traits::difference_type` otherwise. template -using iter_difference_t = typename conditional_t<__is_primary_template > >::value, - incrementable_traits >, - iterator_traits > >::difference_type; +using iter_difference_t = + typename conditional_t<__is_primary_template > >::value, + incrementable_traits >, + iterator_traits > >::difference_type; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/indirectly_comparable.h b/libcxx/include/__iterator/indirectly_comparable.h index e60ba25ca768783cd5e8721478b4e52aee15c3db..e8a7398bacd2b0ce562f6d38f513aa00f3649124 100644 --- a/libcxx/include/__iterator/indirectly_comparable.h +++ b/libcxx/include/__iterator/indirectly_comparable.h @@ -24,8 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -concept indirectly_comparable = - indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; +concept indirectly_comparable = indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/insert_iterator.h b/libcxx/include/__iterator/insert_iterator.h index 1a9c74a16f4fdb2be53d20cd3f5b149abbacdd25..8b7574dc9ec0afdfafb59854360d74a743631fc3 100644 --- a/libcxx/include/__iterator/insert_iterator.h +++ b/libcxx/include/__iterator/insert_iterator.h @@ -42,41 +42,50 @@ class _LIBCPP_TEMPLATE_VIS insert_iterator : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + protected: - _Container* container; - __insert_iterator_iter_t<_Container> iter; + _Container* container; + __insert_iterator_iter_t<_Container> iter; + public: - typedef output_iterator_tag iterator_category; - typedef void value_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; #if _LIBCPP_STD_VER >= 20 - typedef ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; #else - typedef void difference_type; + typedef void difference_type; #endif - typedef void pointer; - typedef void reference; - typedef _Container container_type; + typedef void pointer; + typedef void reference; + typedef _Container container_type; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator(_Container& __x, __insert_iterator_iter_t<_Container> __i) - : container(std::addressof(__x)), iter(__i) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator=(const typename _Container::value_type& __value) - {iter = container->insert(iter, __value); ++iter; return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + insert_iterator(_Container& __x, __insert_iterator_iter_t<_Container> __i) + : container(std::addressof(__x)), iter(__i) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& + operator=(const typename _Container::value_type& __value) { + iter = container->insert(iter, __value); + ++iter; + return *this; + } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator=(typename _Container::value_type&& __value) - {iter = container->insert(iter, std::move(__value)); ++iter; return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& + operator=(typename _Container::value_type&& __value) { + iter = container->insert(iter, std::move(__value)); + ++iter; + return *this; + } #endif // _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator*() {return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++() {return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++(int) {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++(int) { return *this; } }; template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -insert_iterator<_Container> -inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i) -{ - return insert_iterator<_Container>(__x, __i); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator<_Container> +inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i) { + return insert_iterator<_Container>(__x, __i); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/istream_iterator.h b/libcxx/include/__iterator/istream_iterator.h index 2efe5772ba6148e25bceb6d707d0ea409cb4dd72..58c9ac6d4ccceab42066051f90192e20dcb5640b 100644 --- a/libcxx/include/__iterator/istream_iterator.h +++ b/libcxx/include/__iterator/istream_iterator.h @@ -26,78 +26,73 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH -template , class _Distance = ptrdiff_t> +template , class _Distance = ptrdiff_t> class _LIBCPP_TEMPLATE_VIS istream_iterator #if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + public: - typedef input_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _Distance difference_type; - typedef const _Tp* pointer; - typedef const _Tp& reference; - typedef _CharT char_type; - typedef _Traits traits_type; - typedef basic_istream<_CharT,_Traits> istream_type; + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_istream<_CharT, _Traits> istream_type; + private: - istream_type* __in_stream_; - _Tp __value_; + istream_type* __in_stream_; + _Tp __value_; + public: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {} #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {} + _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {} #endif // _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI istream_iterator(istream_type& __s) : __in_stream_(std::addressof(__s)) - { - if (!(*__in_stream_ >> __value_)) - __in_stream_ = nullptr; - } + _LIBCPP_HIDE_FROM_ABI istream_iterator(istream_type& __s) : __in_stream_(std::addressof(__s)) { + if (!(*__in_stream_ >> __value_)) + __in_stream_ = nullptr; + } - _LIBCPP_HIDE_FROM_ABI const _Tp& operator*() const {return __value_;} - _LIBCPP_HIDE_FROM_ABI const _Tp* operator->() const {return std::addressof((operator*()));} - _LIBCPP_HIDE_FROM_ABI istream_iterator& operator++() - { - if (!(*__in_stream_ >> __value_)) - __in_stream_ = nullptr; - return *this; - } - _LIBCPP_HIDE_FROM_ABI istream_iterator operator++(int) - {istream_iterator __t(*this); ++(*this); return __t;} + _LIBCPP_HIDE_FROM_ABI const _Tp& operator*() const { return __value_; } + _LIBCPP_HIDE_FROM_ABI const _Tp* operator->() const { return std::addressof((operator*())); } + _LIBCPP_HIDE_FROM_ABI istream_iterator& operator++() { + if (!(*__in_stream_ >> __value_)) + __in_stream_ = nullptr; + return *this; + } + _LIBCPP_HIDE_FROM_ABI istream_iterator operator++(int) { + istream_iterator __t(*this); + ++(*this); + return __t; + } - template - friend _LIBCPP_HIDE_FROM_ABI - bool - operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x, - const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y); + template + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x, + const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y); #if _LIBCPP_STD_VER >= 20 - friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) { - return __i.__in_stream_ == nullptr; - } + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) { + return __i.__in_stream_ == nullptr; + } #endif // _LIBCPP_STD_VER >= 20 }; template -inline _LIBCPP_HIDE_FROM_ABI -bool -operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, - const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) -{ - return __x.__in_stream_ == __y.__in_stream_; +inline _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) { + return __x.__in_stream_ == __y.__in_stream_; } #if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_HIDE_FROM_ABI -bool -operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, - const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) -{ - return !(__x == __y); +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) { + return !(__x == __y); } #endif // _LIBCPP_STD_VER <= 17 diff --git a/libcxx/include/__iterator/istreambuf_iterator.h b/libcxx/include/__iterator/istreambuf_iterator.h index ed5012a68d82d49481b13c1c431efa7e2039b6fc..51c4ecff351f52b8009fa0c0519c072af1487b1e 100644 --- a/libcxx/include/__iterator/istreambuf_iterator.h +++ b/libcxx/include/__iterator/istreambuf_iterator.h @@ -24,95 +24,84 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH -template +template class _LIBCPP_TEMPLATE_VIS istreambuf_iterator #if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) - : public iterator + : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + public: - typedef input_iterator_tag iterator_category; - typedef _CharT value_type; - typedef typename _Traits::off_type difference_type; - typedef _CharT* pointer; - typedef _CharT reference; - typedef _CharT char_type; - typedef _Traits traits_type; - typedef typename _Traits::int_type int_type; - typedef basic_streambuf<_CharT,_Traits> streambuf_type; - typedef basic_istream<_CharT,_Traits> istream_type; + typedef input_iterator_tag iterator_category; + typedef _CharT value_type; + typedef typename _Traits::off_type difference_type; + typedef _CharT* pointer; + typedef _CharT reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_istream<_CharT, _Traits> istream_type; + private: - mutable streambuf_type* __sbuf_; - - class __proxy - { - char_type __keep_; - streambuf_type* __sbuf_; - _LIBCPP_HIDE_FROM_ABI - explicit __proxy(char_type __c, streambuf_type* __s) - : __keep_(__c), __sbuf_(__s) {} - friend class istreambuf_iterator; - public: - _LIBCPP_HIDE_FROM_ABI char_type operator*() const {return __keep_;} - }; - - _LIBCPP_HIDE_FROM_ABI - bool __test_for_eof() const - { - if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof())) - __sbuf_ = nullptr; - return __sbuf_ == nullptr; - } + mutable streambuf_type* __sbuf_; + + class __proxy { + char_type __keep_; + streambuf_type* __sbuf_; + _LIBCPP_HIDE_FROM_ABI explicit __proxy(char_type __c, streambuf_type* __s) : __keep_(__c), __sbuf_(__s) {} + friend class istreambuf_iterator; + + public: + _LIBCPP_HIDE_FROM_ABI char_type operator*() const { return __keep_; } + }; + + _LIBCPP_HIDE_FROM_ABI bool __test_for_eof() const { + if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof())) + __sbuf_ = nullptr; + return __sbuf_ == nullptr; + } + public: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {} #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI constexpr istreambuf_iterator(default_sentinel_t) noexcept - : istreambuf_iterator() {} + _LIBCPP_HIDE_FROM_ABI constexpr istreambuf_iterator(default_sentinel_t) noexcept : istreambuf_iterator() {} #endif // _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(istream_type& __s) _NOEXCEPT - : __sbuf_(__s.rdbuf()) {} - _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(streambuf_type* __s) _NOEXCEPT - : __sbuf_(__s) {} - _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(const __proxy& __p) _NOEXCEPT - : __sbuf_(__p.__sbuf_) {} - - _LIBCPP_HIDE_FROM_ABI char_type operator*() const - {return static_cast(__sbuf_->sgetc());} - _LIBCPP_HIDE_FROM_ABI istreambuf_iterator& operator++() - { - __sbuf_->sbumpc(); - return *this; - } - _LIBCPP_HIDE_FROM_ABI __proxy operator++(int) - { - return __proxy(__sbuf_->sbumpc(), __sbuf_); - } - - _LIBCPP_HIDE_FROM_ABI bool equal(const istreambuf_iterator& __b) const - {return __test_for_eof() == __b.__test_for_eof();} + _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(istream_type& __s) _NOEXCEPT : __sbuf_(__s.rdbuf()) {} + _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(streambuf_type* __s) _NOEXCEPT : __sbuf_(__s) {} + _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(const __proxy& __p) _NOEXCEPT : __sbuf_(__p.__sbuf_) {} + + _LIBCPP_HIDE_FROM_ABI char_type operator*() const { return static_cast(__sbuf_->sgetc()); } + _LIBCPP_HIDE_FROM_ABI istreambuf_iterator& operator++() { + __sbuf_->sbumpc(); + return *this; + } + _LIBCPP_HIDE_FROM_ABI __proxy operator++(int) { return __proxy(__sbuf_->sbumpc(), __sbuf_); } + + _LIBCPP_HIDE_FROM_ABI bool equal(const istreambuf_iterator& __b) const { + return __test_for_eof() == __b.__test_for_eof(); + } #if _LIBCPP_STD_VER >= 20 - friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) { - return __i.__test_for_eof(); - } + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) { + return __i.__test_for_eof(); + } #endif // _LIBCPP_STD_VER >= 20 }; template -inline _LIBCPP_HIDE_FROM_ABI -bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a, - const istreambuf_iterator<_CharT,_Traits>& __b) - {return __a.equal(__b);} +inline _LIBCPP_HIDE_FROM_ABI bool +operator==(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { + return __a.equal(__b); +} #if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_HIDE_FROM_ABI -bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a, - const istreambuf_iterator<_CharT,_Traits>& __b) - {return !__a.equal(__b);} +inline _LIBCPP_HIDE_FROM_ABI bool +operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { + return !__a.equal(__b); +} #endif // _LIBCPP_STD_VER <= 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/iter_move.h b/libcxx/include/__iterator/iter_move.h index d9ff90bf65456611ebd3b8b88ce44d5dde595773..202b94cccc5ac6557e5467be8f1925a05abbaa64 100644 --- a/libcxx/include/__iterator/iter_move.h +++ b/libcxx/include/__iterator/iter_move.h @@ -38,66 +38,60 @@ namespace __iter_move { void iter_move(); template -concept __unqualified_iter_move = - __class_or_enum> && - requires (_Tp&& __t) { - // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap - iter_move(std::forward<_Tp>(__t)); - }; - -template -concept __move_deref = - !__unqualified_iter_move<_Tp> && - requires (_Tp&& __t) { - *__t; - requires is_lvalue_reference_v; - }; - -template -concept __just_deref = - !__unqualified_iter_move<_Tp> && - !__move_deref<_Tp> && - requires (_Tp&& __t) { - *__t; - requires (!is_lvalue_reference_v); - }; +concept __unqualified_iter_move = __class_or_enum> && requires(_Tp&& __t) { + // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap + iter_move(std::forward<_Tp>(__t)); +}; + +template +concept __move_deref = !__unqualified_iter_move<_Tp> && requires(_Tp&& __t) { + *__t; + requires is_lvalue_reference_v; +}; + +template +concept __just_deref = !__unqualified_iter_move<_Tp> && !__move_deref<_Tp> && requires(_Tp&& __t) { + *__t; + requires(!is_lvalue_reference_v); +}; // [iterator.cust.move] struct __fn { // NOLINTBEGIN(libcpp-robust-against-adl) iter_move ADL calls should only be made through ranges::iter_move - template + template requires __unqualified_iter_move<_Ip> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const - noexcept(noexcept(iter_move(std::forward<_Ip>(__i)))) - { + noexcept(noexcept(iter_move(std::forward<_Ip>(__i)))) { return iter_move(std::forward<_Ip>(__i)); } // NOLINTEND(libcpp-robust-against-adl) - template + template requires __move_deref<_Ip> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const - noexcept(noexcept(std::move(*std::forward<_Ip>(__i)))) - -> decltype( std::move(*std::forward<_Ip>(__i))) - { return std::move(*std::forward<_Ip>(__i)); } + noexcept(noexcept(std::move(*std::forward<_Ip>(__i)))) -> decltype(std::move(*std::forward<_Ip>(__i))) { + return std::move(*std::forward<_Ip>(__i)); + } - template + template requires __just_deref<_Ip> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const - noexcept(noexcept(*std::forward<_Ip>(__i))) - -> decltype( *std::forward<_Ip>(__i)) - { return *std::forward<_Ip>(__i); } + noexcept(noexcept(*std::forward<_Ip>(__i))) -> decltype(*std::forward<_Ip>(__i)) { + return *std::forward<_Ip>(__i); + } }; } // namespace __iter_move inline namespace __cpo { - inline constexpr auto iter_move = __iter_move::__fn{}; +inline constexpr auto iter_move = __iter_move::__fn{}; } // namespace __cpo } // namespace ranges -template<__dereferenceable _Tp> - requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; } +template <__dereferenceable _Tp> + requires requires(_Tp& __t) { + { ranges::iter_move(__t) } -> __can_reference; + } using iter_rvalue_reference_t = decltype(ranges::iter_move(std::declval<_Tp&>())); #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/iter_swap.h b/libcxx/include/__iterator/iter_swap.h index 23d3e4009f536e70562289b945111f5c55ab58e0..52c3f095e7fb1bbd1edc32fb09e890c73c8226e3 100644 --- a/libcxx/include/__iterator/iter_swap.h +++ b/libcxx/include/__iterator/iter_swap.h @@ -37,77 +37,67 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __iter_swap { - template - void iter_swap(_I1, _I2) = delete; +template +void iter_swap(_I1, _I2) = delete; - template - concept __unqualified_iter_swap = - (__class_or_enum> || __class_or_enum>) && - requires (_T1&& __x, _T2&& __y) { +template +concept __unqualified_iter_swap = + (__class_or_enum> || __class_or_enum>)&&requires(_T1&& __x, _T2&& __y) { // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap iter_swap(std::forward<_T1>(__x), std::forward<_T2>(__y)); }; - template - concept __readable_swappable = +template +concept __readable_swappable = indirectly_readable<_T1> && indirectly_readable<_T2> && swappable_with, iter_reference_t<_T2>>; - - struct __fn { - // NOLINTBEGIN(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap - template - requires __unqualified_iter_swap<_T1, _T2> - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()(_T1&& __x, _T2&& __y) const - noexcept(noexcept(iter_swap(std::forward<_T1>(__x), std::forward<_T2>(__y)))) - { - (void)iter_swap(std::forward<_T1>(__x), std::forward<_T2>(__y)); - } - // NOLINTEND(libcpp-robust-against-adl) - - template - requires (!__unqualified_iter_swap<_T1, _T2>) && - __readable_swappable<_T1, _T2> - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()(_T1&& __x, _T2&& __y) const - noexcept(noexcept(ranges::swap(*std::forward<_T1>(__x), *std::forward<_T2>(__y)))) - { - ranges::swap(*std::forward<_T1>(__x), *std::forward<_T2>(__y)); - } - - template - requires (!__unqualified_iter_swap<_T1, _T2> && // - !__readable_swappable<_T1, _T2>) && // - indirectly_movable_storable<_T1, _T2> && // - indirectly_movable_storable<_T2, _T1> - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()(_T1&& __x, _T2&& __y) const +struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap + template + requires __unqualified_iter_swap<_T1, _T2> + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(iter_swap(std::forward<_T1>(__x), std::forward<_T2>(__y)))) { + (void)iter_swap(std::forward<_T1>(__x), std::forward<_T2>(__y)); + } + // NOLINTEND(libcpp-robust-against-adl) + + template + requires(!__unqualified_iter_swap<_T1, _T2>) && __readable_swappable<_T1, _T2> + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(ranges::swap(*std::forward<_T1>(__x), *std::forward<_T2>(__y)))) { + ranges::swap(*std::forward<_T1>(__x), *std::forward<_T2>(__y)); + } + + template + requires(!__unqualified_iter_swap<_T1, _T2> && // + !__readable_swappable<_T1, _T2>) && // + indirectly_movable_storable<_T1, _T2> && // + indirectly_movable_storable<_T2, _T1> + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_T1&& __x, _T2&& __y) const noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) && // - noexcept(*__y = ranges::iter_move(__x)) && // - noexcept(*std::forward<_T1>(__x) = std::declval>())) - { - iter_value_t<_T2> __old(ranges::iter_move(__y)); - *__y = ranges::iter_move(__x); - *std::forward<_T1>(__x) = std::move(__old); - } - }; + noexcept(*__y = ranges::iter_move(__x)) && // + noexcept(*std::forward<_T1>(__x) = std::declval>())) { + iter_value_t<_T2> __old(ranges::iter_move(__y)); + *__y = ranges::iter_move(__x); + *std::forward<_T1>(__x) = std::move(__old); + } +}; } // namespace __iter_swap inline namespace __cpo { - inline constexpr auto iter_swap = __iter_swap::__fn{}; +inline constexpr auto iter_swap = __iter_swap::__fn{}; } // namespace __cpo } // namespace ranges -template +template concept indirectly_swappable = - indirectly_readable<_I1> && indirectly_readable<_I2> && - requires(const _I1 __i1, const _I2 __i2) { - ranges::iter_swap(__i1, __i1); - ranges::iter_swap(__i2, __i2); - ranges::iter_swap(__i1, __i2); - ranges::iter_swap(__i2, __i1); - }; + indirectly_readable<_I1> && indirectly_readable<_I2> && requires(const _I1 __i1, const _I2 __i2) { + ranges::iter_swap(__i1, __i1); + ranges::iter_swap(__i2, __i2); + ranges::iter_swap(__i1, __i2); + ranges::iter_swap(__i2, __i1); + }; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/iterator.h b/libcxx/include/__iterator/iterator.h index b417eeab79bfe66b9bc2773423547e307b960704..ba9308f3c2243013da46ccef745c2082dc95054a 100644 --- a/libcxx/include/__iterator/iterator.h +++ b/libcxx/include/__iterator/iterator.h @@ -19,15 +19,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator -{ - typedef _Tp value_type; - typedef _Distance difference_type; - typedef _Pointer pointer; - typedef _Reference reference; - typedef _Category iterator_category; +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator { + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Pointer pointer; + typedef _Reference reference; + typedef _Category iterator_category; }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h index 248987e9b5605bafd042629d9f0651da6745fb90..dae8cc75ae349e9600d5daf1ac3b0394313f562f 100644 --- a/libcxx/include/__iterator/iterator_traits.h +++ b/libcxx/include/__iterator/iterator_traits.h @@ -49,9 +49,7 @@ template using __with_reference = _Tp&; template -concept __can_reference = requires { - typename __with_reference<_Tp>; -}; +concept __can_reference = requires { typename __with_reference<_Tp>; }; template concept __dereferenceable = requires(_Tp& __t) { @@ -59,7 +57,7 @@ concept __dereferenceable = requires(_Tp& __t) { }; // [iterator.traits] -template<__dereferenceable _Tp> +template <__dereferenceable _Tp> using iter_reference_t = decltype(*std::declval<_Tp&>()); #endif // _LIBCPP_STD_VER >= 20 @@ -69,20 +67,16 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits; struct _LIBCPP_TEMPLATE_VIS input_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {}; -struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {}; #if _LIBCPP_STD_VER >= 20 -struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag : public random_access_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag : public random_access_iterator_tag {}; #endif template struct __iter_traits_cache { - using type = _If< - __is_primary_template >::value, - _Iter, - iterator_traits<_Iter> - >; + using type = _If< __is_primary_template >::value, _Iter, iterator_traits<_Iter> >; }; template using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type; @@ -97,64 +91,61 @@ struct __iter_concept_category_test { }; struct __iter_concept_random_fallback { template - using _Apply = __enable_if_t< - __is_primary_template >::value, - random_access_iterator_tag - >; + using _Apply = __enable_if_t< __is_primary_template >::value, random_access_iterator_tag >; }; -template struct __test_iter_concept - : _IsValidExpansion<_Tester::template _Apply, _Iter>, - _Tester -{ -}; +template +struct __test_iter_concept : _IsValidExpansion<_Tester::template _Apply, _Iter>, _Tester {}; template struct __iter_concept_cache { - using type = _Or< - __test_iter_concept<_Iter, __iter_concept_concept_test>, - __test_iter_concept<_Iter, __iter_concept_category_test>, - __test_iter_concept<_Iter, __iter_concept_random_fallback> - >; + using type = _Or< __test_iter_concept<_Iter, __iter_concept_concept_test>, + __test_iter_concept<_Iter, __iter_concept_category_test>, + __test_iter_concept<_Iter, __iter_concept_random_fallback> >; }; template using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>; - template -struct __has_iterator_typedefs -{ +struct __has_iterator_typedefs { private: - template static false_type __test(...); - template static true_type __test(__void_t* = nullptr, - __void_t* = nullptr, - __void_t* = nullptr, - __void_t* = nullptr, - __void_t* = nullptr); + template + static false_type __test(...); + template + static true_type + __test(__void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr); + public: - static const bool value = decltype(__test<_Tp>(0,0,0,0,0))::value; + static const bool value = decltype(__test<_Tp>(0, 0, 0, 0, 0))::value; }; - template -struct __has_iterator_category -{ +struct __has_iterator_category { private: - template static false_type __test(...); - template static true_type __test(typename _Up::iterator_category* = nullptr); + template + static false_type __test(...); + template + static true_type __test(typename _Up::iterator_category* = nullptr); + public: - static const bool value = decltype(__test<_Tp>(nullptr))::value; + static const bool value = decltype(__test<_Tp>(nullptr))::value; }; template -struct __has_iterator_concept -{ +struct __has_iterator_concept { private: - template static false_type __test(...); - template static true_type __test(typename _Up::iterator_concept* = nullptr); + template + static false_type __test(...); + template + static true_type __test(typename _Up::iterator_concept* = nullptr); + public: - static const bool value = decltype(__test<_Tp>(nullptr))::value; + static const bool value = decltype(__test<_Tp>(nullptr))::value; }; #if _LIBCPP_STD_VER >= 20 @@ -163,200 +154,194 @@ public: // from `[iterator.cpp17]`. To avoid confusion between the two, the exposition-only concepts have been banished to // a "detail" namespace indicating they have a niche use-case. namespace __iterator_traits_detail { -template -concept __cpp17_iterator = - requires(_Ip __i) { - { *__i } -> __can_reference; - { ++__i } -> same_as<_Ip&>; - { *__i++ } -> __can_reference; - } && - copyable<_Ip>; - -template -concept __cpp17_input_iterator = - __cpp17_iterator<_Ip> && - equality_comparable<_Ip> && - requires(_Ip __i) { - typename incrementable_traits<_Ip>::difference_type; - typename indirectly_readable_traits<_Ip>::value_type; - typename common_reference_t&&, - typename indirectly_readable_traits<_Ip>::value_type&>; - typename common_reference_t::value_type&>; - requires signed_integral::difference_type>; - }; - -template +template +concept __cpp17_iterator = requires(_Ip __i) { + { *__i } -> __can_reference; + { ++__i } -> same_as<_Ip&>; + { *__i++ } -> __can_reference; +} && copyable<_Ip>; + +template +concept __cpp17_input_iterator = __cpp17_iterator<_Ip> && equality_comparable<_Ip> && requires(_Ip __i) { + typename incrementable_traits<_Ip>::difference_type; + typename indirectly_readable_traits<_Ip>::value_type; + typename common_reference_t&&, typename indirectly_readable_traits<_Ip>::value_type&>; + typename common_reference_t::value_type&>; + requires signed_integral::difference_type>; +}; + +template concept __cpp17_forward_iterator = - __cpp17_input_iterator<_Ip> && - constructible_from<_Ip> && - is_reference_v> && - same_as>, - typename indirectly_readable_traits<_Ip>::value_type> && - requires(_Ip __i) { - { __i++ } -> convertible_to<_Ip const&>; - { *__i++ } -> same_as>; - }; - -template -concept __cpp17_bidirectional_iterator = - __cpp17_forward_iterator<_Ip> && - requires(_Ip __i) { - { --__i } -> same_as<_Ip&>; - { __i-- } -> convertible_to<_Ip const&>; - { *__i-- } -> same_as>; - }; - -template + __cpp17_input_iterator<_Ip> && constructible_from<_Ip> && is_reference_v> && + same_as>, typename indirectly_readable_traits<_Ip>::value_type> && + requires(_Ip __i) { + { __i++ } -> convertible_to<_Ip const&>; + { *__i++ } -> same_as>; + }; + +template +concept __cpp17_bidirectional_iterator = __cpp17_forward_iterator<_Ip> && requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> convertible_to<_Ip const&>; + { *__i-- } -> same_as>; +}; + +template concept __cpp17_random_access_iterator = - __cpp17_bidirectional_iterator<_Ip> && - totally_ordered<_Ip> && - requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) { - { __i += __n } -> same_as<_Ip&>; - { __i -= __n } -> same_as<_Ip&>; - { __i + __n } -> same_as<_Ip>; - { __n + __i } -> same_as<_Ip>; - { __i - __n } -> same_as<_Ip>; - { __i - __i } -> same_as; // NOLINT(misc-redundant-expression) ; This is llvm.org/PR54114 - { __i[__n] } -> convertible_to>; - }; + __cpp17_bidirectional_iterator<_Ip> && totally_ordered<_Ip> && + requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) { + { __i += __n } -> same_as<_Ip&>; + { __i -= __n } -> same_as<_Ip&>; + { __i + __n } -> same_as<_Ip>; + { __n + __i } -> same_as<_Ip>; + { __i - __n } -> same_as<_Ip>; + { __i - __i } -> same_as; // NOLINT(misc-redundant-expression) ; This is llvm.org/PR54114 + { __i[__n] } -> convertible_to>; + }; } // namespace __iterator_traits_detail -template +template concept __has_member_reference = requires { typename _Ip::reference; }; -template +template concept __has_member_pointer = requires { typename _Ip::pointer; }; -template +template concept __has_member_iterator_category = requires { typename _Ip::iterator_category; }; -template +template concept __specifies_members = requires { - typename _Ip::value_type; - typename _Ip::difference_type; - requires __has_member_reference<_Ip>; - requires __has_member_iterator_category<_Ip>; - }; + typename _Ip::value_type; + typename _Ip::difference_type; + requires __has_member_reference<_Ip>; + requires __has_member_iterator_category<_Ip>; +}; -template +template struct __iterator_traits_member_pointer_or_void { using type = void; }; -template<__has_member_pointer _Tp> +template <__has_member_pointer _Tp> struct __iterator_traits_member_pointer_or_void<_Tp> { using type = typename _Tp::pointer; }; -template -concept __cpp17_iterator_missing_members = - !__specifies_members<_Tp> && - __iterator_traits_detail::__cpp17_iterator<_Tp>; +template +concept __cpp17_iterator_missing_members = !__specifies_members<_Tp> && __iterator_traits_detail::__cpp17_iterator<_Tp>; -template +template concept __cpp17_input_iterator_missing_members = - __cpp17_iterator_missing_members<_Tp> && - __iterator_traits_detail::__cpp17_input_iterator<_Tp>; + __cpp17_iterator_missing_members<_Tp> && __iterator_traits_detail::__cpp17_input_iterator<_Tp>; // Otherwise, `pointer` names `void`. -template -struct __iterator_traits_member_pointer_or_arrow_or_void { using type = void; }; +template +struct __iterator_traits_member_pointer_or_arrow_or_void { + using type = void; +}; // [iterator.traits]/3.2.1 // If the qualified-id `I::pointer` is valid and denotes a type, `pointer` names that type. -template<__has_member_pointer _Ip> -struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typename _Ip::pointer; }; +template <__has_member_pointer _Ip> +struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { + using type = typename _Ip::pointer; +}; // Otherwise, if `decltype(declval().operator->())` is well-formed, then `pointer` names that // type. -template +template requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>) struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = decltype(std::declval<_Ip&>().operator->()); }; // Otherwise, `reference` names `iter-reference-t`. -template -struct __iterator_traits_member_reference { using type = iter_reference_t<_Ip>; }; +template +struct __iterator_traits_member_reference { + using type = iter_reference_t<_Ip>; +}; // [iterator.traits]/3.2.2 // If the qualified-id `I::reference` is valid and denotes a type, `reference` names that type. -template<__has_member_reference _Ip> -struct __iterator_traits_member_reference<_Ip> { using type = typename _Ip::reference; }; +template <__has_member_reference _Ip> +struct __iterator_traits_member_reference<_Ip> { + using type = typename _Ip::reference; +}; // [iterator.traits]/3.2.3.4 // input_iterator_tag -template +template struct __deduce_iterator_category { using type = input_iterator_tag; }; // [iterator.traits]/3.2.3.1 // `random_access_iterator_tag` if `I` satisfies `cpp17-random-access-iterator`, or otherwise -template<__iterator_traits_detail::__cpp17_random_access_iterator _Ip> +template <__iterator_traits_detail::__cpp17_random_access_iterator _Ip> struct __deduce_iterator_category<_Ip> { using type = random_access_iterator_tag; }; // [iterator.traits]/3.2.3.2 // `bidirectional_iterator_tag` if `I` satisfies `cpp17-bidirectional-iterator`, or otherwise -template<__iterator_traits_detail::__cpp17_bidirectional_iterator _Ip> +template <__iterator_traits_detail::__cpp17_bidirectional_iterator _Ip> struct __deduce_iterator_category<_Ip> { using type = bidirectional_iterator_tag; }; // [iterator.traits]/3.2.3.3 // `forward_iterator_tag` if `I` satisfies `cpp17-forward-iterator`, or otherwise -template<__iterator_traits_detail::__cpp17_forward_iterator _Ip> +template <__iterator_traits_detail::__cpp17_forward_iterator _Ip> struct __deduce_iterator_category<_Ip> { using type = forward_iterator_tag; }; -template +template struct __iterator_traits_iterator_category : __deduce_iterator_category<_Ip> {}; // [iterator.traits]/3.2.3 // If the qualified-id `I::iterator-category` is valid and denotes a type, `iterator-category` names // that type. -template<__has_member_iterator_category _Ip> +template <__has_member_iterator_category _Ip> struct __iterator_traits_iterator_category<_Ip> { using type = typename _Ip::iterator_category; }; // otherwise, it names void. -template -struct __iterator_traits_difference_type { using type = void; }; +template +struct __iterator_traits_difference_type { + using type = void; +}; // If the qualified-id `incrementable_traits::difference_type` is valid and denotes a type, then // `difference_type` names that type; -template -requires requires { typename incrementable_traits<_Ip>::difference_type; } +template + requires requires { typename incrementable_traits<_Ip>::difference_type; } struct __iterator_traits_difference_type<_Ip> { using type = typename incrementable_traits<_Ip>::difference_type; }; // [iterator.traits]/3.4 // Otherwise, `iterator_traits` has no members by any of the above names. -template +template struct __iterator_traits {}; // [iterator.traits]/3.1 // If `I` has valid ([temp.deduct]) member types `difference-type`, `value-type`, `reference`, and // `iterator-category`, then `iterator-traits` has the following publicly accessible members: -template<__specifies_members _Ip> +template <__specifies_members _Ip> struct __iterator_traits<_Ip> { - using iterator_category = typename _Ip::iterator_category; - using value_type = typename _Ip::value_type; - using difference_type = typename _Ip::difference_type; - using pointer = typename __iterator_traits_member_pointer_or_void<_Ip>::type; - using reference = typename _Ip::reference; + using iterator_category = typename _Ip::iterator_category; + using value_type = typename _Ip::value_type; + using difference_type = typename _Ip::difference_type; + using pointer = typename __iterator_traits_member_pointer_or_void<_Ip>::type; + using reference = typename _Ip::reference; }; // [iterator.traits]/3.2 // Otherwise, if `I` satisfies the exposition-only concept `cpp17-input-iterator`, // `iterator-traits` has the following publicly accessible members: -template<__cpp17_input_iterator_missing_members _Ip> +template <__cpp17_input_iterator_missing_members _Ip> struct __iterator_traits<_Ip> { using iterator_category = typename __iterator_traits_iterator_category<_Ip>::type; using value_type = typename indirectly_readable_traits<_Ip>::value_type; @@ -367,7 +352,7 @@ struct __iterator_traits<_Ip> { // Otherwise, if `I` satisfies the exposition-only concept `cpp17-iterator`, then // `iterator_traits` has the following publicly accessible members: -template<__cpp17_iterator_missing_members _Ip> +template <__cpp17_iterator_missing_members _Ip> struct __iterator_traits<_Ip> { using iterator_category = output_iterator_tag; using value_type = void; @@ -376,36 +361,33 @@ struct __iterator_traits<_Ip> { using reference = void; }; -template +template struct iterator_traits : __iterator_traits<_Ip> { using __primary_template = iterator_traits; }; -#else // _LIBCPP_STD_VER >= 20 +#else // _LIBCPP_STD_VER >= 20 -template struct __iterator_traits {}; +template +struct __iterator_traits {}; -template struct __iterator_traits_impl {}; +template +struct __iterator_traits_impl {}; template -struct __iterator_traits_impl<_Iter, true> -{ - typedef typename _Iter::difference_type difference_type; - typedef typename _Iter::value_type value_type; - typedef typename _Iter::pointer pointer; - typedef typename _Iter::reference reference; - typedef typename _Iter::iterator_category iterator_category; +struct __iterator_traits_impl<_Iter, true> { + typedef typename _Iter::difference_type difference_type; + typedef typename _Iter::value_type value_type; + typedef typename _Iter::pointer pointer; + typedef typename _Iter::reference reference; + typedef typename _Iter::iterator_category iterator_category; }; template struct __iterator_traits<_Iter, true> - : __iterator_traits_impl - < - _Iter, - is_convertible::value || - is_convertible::value - > -{}; + : __iterator_traits_impl< _Iter, + is_convertible::value || + is_convertible::value > {}; // iterator_traits will only have the nested types if Iterator::iterator_category // exists. Else iterator_traits will be an empty class. This is a @@ -413,41 +395,35 @@ struct __iterator_traits<_Iter, true> // the client expects instead of failing at compile time. template -struct _LIBCPP_TEMPLATE_VIS iterator_traits - : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> { - +struct _LIBCPP_TEMPLATE_VIS iterator_traits : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> { using __primary_template = iterator_traits; }; #endif // _LIBCPP_STD_VER >= 20 -template +template #if _LIBCPP_STD_VER >= 20 -requires is_object_v<_Tp> + requires is_object_v<_Tp> #endif -struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> -{ - typedef ptrdiff_t difference_type; - typedef __remove_cv_t<_Tp> value_type; - typedef _Tp* pointer; - typedef _Tp& reference; - typedef random_access_iterator_tag iterator_category; +struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> { + typedef ptrdiff_t difference_type; + typedef __remove_cv_t<_Tp> value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + typedef random_access_iterator_tag iterator_category; #if _LIBCPP_STD_VER >= 20 - typedef contiguous_iterator_tag iterator_concept; + typedef contiguous_iterator_tag iterator_concept; #endif }; template >::value> -struct __has_iterator_category_convertible_to - : is_convertible::iterator_category, _Up> -{}; +struct __has_iterator_category_convertible_to : is_convertible::iterator_category, _Up> { +}; template struct __has_iterator_category_convertible_to<_Tp, _Up, false> : false_type {}; template ::value> -struct __has_iterator_concept_convertible_to - : is_convertible -{}; +struct __has_iterator_concept_convertible_to : is_convertible {}; template struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {}; @@ -473,10 +449,9 @@ using __has_random_access_iterator_category = __has_iterator_category_convertibl // #if _LIBCPP_STD_VER >= 20 template -struct __libcpp_is_contiguous_iterator : _Or< - __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>, - __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag> -> {}; +struct __libcpp_is_contiguous_iterator + : _Or< __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>, + __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag> > {}; #else template struct __libcpp_is_contiguous_iterator : false_type {}; @@ -486,41 +461,40 @@ struct __libcpp_is_contiguous_iterator : false_type {}; template struct __libcpp_is_contiguous_iterator<_Up*> : true_type {}; - template class __wrap_iter; template -using __has_exactly_input_iterator_category - = integral_constant::value && - !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value>; +using __has_exactly_input_iterator_category = + integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value>; template -using __has_exactly_forward_iterator_category - = integral_constant::value && - !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value>; +using __has_exactly_forward_iterator_category = + integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value>; template -using __has_exactly_bidirectional_iterator_category - = integral_constant::value && - !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>; +using __has_exactly_bidirectional_iterator_category = + integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>; -template +template using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; -template +template using __iter_key_type = __remove_const_t::value_type::first_type>; -template +template using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type; -template -using __iter_to_alloc_type = pair< - typename add_const::value_type::first_type>::type, - typename iterator_traits<_InputIterator>::value_type::second_type>; +template +using __iter_to_alloc_type = + pair< typename add_const::value_type::first_type>::type, + typename iterator_traits<_InputIterator>::value_type::second_type>; template using __iterator_category_type = typename iterator_traits<_Iter>::iterator_category; @@ -543,9 +517,10 @@ using __iter_reference = typename iterator_traits<_Iter>::reference; // generated from the primary template, and `iterator_traits::value_type` otherwise. // This has to be in this file and not readable_traits.h to break the include cycle between the two. template -using iter_value_t = typename conditional_t<__is_primary_template > >::value, - indirectly_readable_traits >, - iterator_traits > >::value_type; +using iter_value_t = + typename conditional_t<__is_primary_template > >::value, + indirectly_readable_traits >, + iterator_traits > >::value_type; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/mergeable.h b/libcxx/include/__iterator/mergeable.h index 494fda956e27796d512bde85af764cd983a60f08..7976d751095e581d815d0205a6d2a197816c80c6 100644 --- a/libcxx/include/__iterator/mergeable.h +++ b/libcxx/include/__iterator/mergeable.h @@ -24,14 +24,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template +template concept mergeable = - input_iterator<_Input1> && - input_iterator<_Input2> && - weakly_incrementable<_Output> && - indirectly_copyable<_Input1, _Output> && - indirectly_copyable<_Input2, _Output> && + input_iterator<_Input1> && input_iterator<_Input2> && weakly_incrementable<_Output> && + indirectly_copyable<_Input1, _Output> && indirectly_copyable<_Input2, _Output> && indirect_strict_weak_order<_Comp, projected<_Input1, _Proj1>, projected<_Input2, _Proj2>>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/move_iterator.h b/libcxx/include/__iterator/move_iterator.h index 2f79d9a3d263a1df7cc779364272b6bccd4b2906..d1bd0138bdda10db5e4d0a93957f818ec737231e 100644 --- a/libcxx/include/__iterator/move_iterator.h +++ b/libcxx/include/__iterator/move_iterator.h @@ -45,22 +45,21 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template +template struct __move_iter_category_base {}; -template +template requires requires { typename iterator_traits<_Iter>::iterator_category; } struct __move_iter_category_base<_Iter> { - using iterator_category = _If< - derived_from::iterator_category, random_access_iterator_tag>, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category - >; + using iterator_category = + _If< derived_from::iterator_category, random_access_iterator_tag>, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category >; }; -template +template concept __move_iter_comparable = requires { - { std::declval() == std::declval<_Sent>() } -> convertible_to; + { std::declval() == std::declval<_Sent>() } -> convertible_to; }; #endif // _LIBCPP_STD_VER >= 20 @@ -70,282 +69,270 @@ class _LIBCPP_TEMPLATE_VIS move_iterator : public __move_iter_category_base<_Iter> #endif { - #if _LIBCPP_STD_VER >= 20 +#if _LIBCPP_STD_VER >= 20 + private: - _LIBCPP_HIDE_FROM_ABI - static constexpr auto __get_iter_concept() { - if constexpr (random_access_iterator<_Iter>) { - return random_access_iterator_tag{}; - } else if constexpr (bidirectional_iterator<_Iter>) { - return bidirectional_iterator_tag{}; - } else if constexpr (forward_iterator<_Iter>) { - return forward_iterator_tag{}; - } else { - return input_iterator_tag{}; - } + _LIBCPP_HIDE_FROM_ABI static constexpr auto __get_iter_concept() { + if constexpr (random_access_iterator<_Iter>) { + return random_access_iterator_tag{}; + } else if constexpr (bidirectional_iterator<_Iter>) { + return bidirectional_iterator_tag{}; + } else if constexpr (forward_iterator<_Iter>) { + return forward_iterator_tag{}; + } else { + return input_iterator_tag{}; } + } #endif // _LIBCPP_STD_VER >= 20 + public: #if _LIBCPP_STD_VER >= 20 - using iterator_type = _Iter; - using iterator_concept = decltype(__get_iter_concept()); - // iterator_category is inherited and not always present - using value_type = iter_value_t<_Iter>; - using difference_type = iter_difference_t<_Iter>; - using pointer = _Iter; - using reference = iter_rvalue_reference_t<_Iter>; + using iterator_type = _Iter; + using iterator_concept = decltype(__get_iter_concept()); + // iterator_category is inherited and not always present + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using pointer = _Iter; + using reference = iter_rvalue_reference_t<_Iter>; #else - typedef _Iter iterator_type; - typedef _If< - __has_random_access_iterator_category<_Iter>::value, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category - > iterator_category; - typedef typename iterator_traits::value_type value_type; - typedef typename iterator_traits::difference_type difference_type; - typedef iterator_type pointer; - - typedef typename iterator_traits::reference __reference; - typedef typename conditional< - is_reference<__reference>::value, - __libcpp_remove_reference_t<__reference>&&, - __reference - >::type reference; + typedef _Iter iterator_type; + typedef _If< __has_random_access_iterator_category<_Iter>::value, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category > + iterator_category; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::difference_type difference_type; + typedef iterator_type pointer; + + typedef typename iterator_traits::reference __reference; + typedef typename conditional< is_reference<__reference>::value, + __libcpp_remove_reference_t<__reference>&&, + __reference >::type reference; #endif // _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator& operator++() { ++__current_; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator++() { + ++__current_; + return *this; + } - _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - pointer operator->() const { return __current_; } + _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pointer operator->() const { + return __current_; + } #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI constexpr - move_iterator() requires is_constructible_v<_Iter> : __current_() {} - - template - requires (!_IsSame<_Up, _Iter>::value) && convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr - move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} - - template - requires (!_IsSame<_Up, _Iter>::value) && - convertible_to && - assignable_from<_Iter&, const _Up&> - _LIBCPP_HIDE_FROM_ABI constexpr - move_iterator& operator=(const move_iterator<_Up>& __u) { - __current_ = __u.base(); - return *this; - } - - _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; } - _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } - - _LIBCPP_HIDE_FROM_ABI constexpr - reference operator*() const { return ranges::iter_move(__current_); } - _LIBCPP_HIDE_FROM_ABI constexpr - reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); } - - _LIBCPP_HIDE_FROM_ABI constexpr - auto operator++(int) - requires forward_iterator<_Iter> - { - move_iterator __tmp(*this); ++__current_; return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI constexpr - void operator++(int) { ++__current_; } + _LIBCPP_HIDE_FROM_ABI constexpr move_iterator() + requires is_constructible_v<_Iter> + : __current_() {} + + template + requires(!_IsSame<_Up, _Iter>::value) && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} + + template + requires(!_IsSame<_Up, _Iter>::value) && convertible_to && assignable_from<_Iter&, const _Up&> + _LIBCPP_HIDE_FROM_ABI constexpr move_iterator& operator=(const move_iterator<_Up>& __u) { + __current_ = __u.base(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const& noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } + + _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return ranges::iter_move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const { + return ranges::iter_move(__current_ + __n); + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto operator++(int) + requires forward_iterator<_Iter> + { + move_iterator __tmp(*this); + ++__current_; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; } #else - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator() : __current_() {} - - template ::value && is_convertible::value - > > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} - - template ::value && - is_convertible::value && - is_assignable<_Iter&, const _Up&>::value - > > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator& operator=(const move_iterator<_Up>& __u) { - __current_ = __u.base(); - return *this; - } - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - _Iter base() const { return __current_; } - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reference operator*() const { return static_cast(*__current_); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reference operator[](difference_type __n) const { return static_cast(__current_[__n]); } - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator() : __current_() {} + + template ::value && is_convertible::value > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator(const move_iterator<_Up>& __u) + : __current_(__u.base()) {} + + template ::value && is_convertible::value && + is_assignable<_Iter&, const _Up&>::value > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator=(const move_iterator<_Up>& __u) { + __current_ = __u.base(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter base() const { return __current_; } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator*() const { + return static_cast(*__current_); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](difference_type __n) const { + return static_cast(__current_[__n]); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator++(int) { + move_iterator __tmp(*this); + ++__current_; + return __tmp; + } #endif // _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator& operator--() { --__current_; return *this; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator--() { + --__current_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator--(int) { + move_iterator __tmp(*this); + --__current_; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator+(difference_type __n) const { + return move_iterator(__current_ + __n); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator+=(difference_type __n) { + __current_ += __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator-(difference_type __n) const { + return move_iterator(__current_ - __n); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator-=(difference_type __n) { + __current_ -= __n; + return *this; + } #if _LIBCPP_STD_VER >= 20 - template _Sent> - friend _LIBCPP_HIDE_FROM_ABI constexpr - bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) - requires __move_iter_comparable<_Iter, _Sent> - { - return __x.base() == __y.base(); - } - - template _Sent> - friend _LIBCPP_HIDE_FROM_ABI constexpr - iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) - { - return __x.base() - __y.base(); - } - - template _Sent> - friend _LIBCPP_HIDE_FROM_ABI constexpr - iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) - { - return __x.base() - __y.base(); - } + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) + requires __move_iter_comparable<_Iter, _Sent> + { + return __x.base() == __y.base(); + } - friend _LIBCPP_HIDE_FROM_ABI constexpr - iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i) - noexcept(noexcept(ranges::iter_move(__i.__current_))) - { - return ranges::iter_move(__i.__current_); - } + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> + operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) { + return __x.base() - __y.base(); + } - template _It2> - friend _LIBCPP_HIDE_FROM_ABI constexpr - void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y) - noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) - { - return ranges::iter_swap(__x.__current_, __y.__current_); - } + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> + operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) { + return __x.base() - __y.base(); + } + + friend _LIBCPP_HIDE_FROM_ABI constexpr iter_rvalue_reference_t<_Iter> + iter_move(const move_iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__current_))) { + return ranges::iter_move(__i.__current_); + } + + template _It2> + friend _LIBCPP_HIDE_FROM_ABI constexpr void + iter_swap(const move_iterator& __x, + const move_iterator<_It2>& __y) noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) { + return ranges::iter_swap(__x.__current_, __y.__current_); + } #endif // _LIBCPP_STD_VER >= 20 private: - template friend class move_iterator; + template + friend class move_iterator; - _Iter __current_; + _Iter __current_; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator); template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() == __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() == __y.base(); } #if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() != __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() != __y.base(); } #endif // _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() < __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() < __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() > __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() > __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() <= __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() <= __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() >= __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() >= __y.base(); } #if _LIBCPP_STD_VER >= 20 template _Iter2> -inline _LIBCPP_HIDE_FROM_ABI constexpr -auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) - -> compare_three_way_result_t<_Iter1, _Iter2> -{ - return __x.base() <=> __y.base(); +inline _LIBCPP_HIDE_FROM_ABI constexpr auto +operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) + -> compare_three_way_result_t<_Iter1, _Iter2> { + return __x.base() <=> __y.base(); } #endif // _LIBCPP_STD_VER >= 20 #ifndef _LIBCPP_CXX03_LANG template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) - -> decltype(__x.base() - __y.base()) -{ - return __x.base() - __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto +operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -> decltype(__x.base() - __y.base()) { + return __x.base() - __y.base(); } #else template -inline _LIBCPP_HIDE_FROM_ABI -typename move_iterator<_Iter1>::difference_type -operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() - __y.base(); +inline _LIBCPP_HIDE_FROM_ABI typename move_iterator<_Iter1>::difference_type +operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() - __y.base(); } #endif // !_LIBCPP_CXX03_LANG #if _LIBCPP_STD_VER >= 20 template -inline _LIBCPP_HIDE_FROM_ABI constexpr -move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) - requires requires { { __x.base() + __n } -> same_as<_Iter>; } +inline _LIBCPP_HIDE_FROM_ABI constexpr move_iterator<_Iter> +operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) + requires requires { + { __x.base() + __n } -> same_as<_Iter>; + } { - return __x + __n; + return __x + __n; } #else template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -move_iterator<_Iter> -operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) -{ - return move_iterator<_Iter>(__x.base() + __n); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> +operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) { + return move_iterator<_Iter>(__x.base() + __n); } #endif // _LIBCPP_STD_VER >= 20 template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -move_iterator<_Iter> -make_move_iterator(_Iter __i) -{ - return move_iterator<_Iter>(std::move(__i)); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> make_move_iterator(_Iter __i) { + return move_iterator<_Iter>(std::move(__i)); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/move_sentinel.h b/libcxx/include/__iterator/move_sentinel.h index 34b3c25417c445023d4a121054af6721c375db59..4a2a09ef0611d248fe598646abe1e4201a817237 100644 --- a/libcxx/include/__iterator/move_sentinel.h +++ b/libcxx/include/__iterator/move_sentinel.h @@ -27,30 +27,27 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -class _LIBCPP_TEMPLATE_VIS move_sentinel -{ +class _LIBCPP_TEMPLATE_VIS move_sentinel { public: - _LIBCPP_HIDE_FROM_ABI - move_sentinel() = default; + _LIBCPP_HIDE_FROM_ABI move_sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr - explicit move_sentinel(_Sent __s) : __last_(std::move(__s)) {} + _LIBCPP_HIDE_FROM_ABI constexpr explicit move_sentinel(_Sent __s) : __last_(std::move(__s)) {} template requires convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr - move_sentinel(const move_sentinel<_S2>& __s) : __last_(__s.base()) {} + _LIBCPP_HIDE_FROM_ABI constexpr move_sentinel(const move_sentinel<_S2>& __s) : __last_(__s.base()) {} template requires assignable_from<_Sent&, const _S2&> - _LIBCPP_HIDE_FROM_ABI constexpr - move_sentinel& operator=(const move_sentinel<_S2>& __s) - { __last_ = __s.base(); return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr move_sentinel& operator=(const move_sentinel<_S2>& __s) { + __last_ = __s.base(); + return *this; + } _LIBCPP_HIDE_FROM_ABI constexpr _Sent base() const { return __last_; } private: - _Sent __last_ = _Sent(); + _Sent __last_ = _Sent(); }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel); diff --git a/libcxx/include/__iterator/next.h b/libcxx/include/__iterator/next.h index ae98229bdabf4e6d3e224b7b1de0d80ab977d763..da60aacfd08d26af24c097847362086ce26c4ffc 100644 --- a/libcxx/include/__iterator/next.h +++ b/libcxx/include/__iterator/next.h @@ -25,9 +25,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - _InputIter - next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _InputIter +next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value, "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); @@ -44,15 +43,13 @@ namespace __next { struct __fn { template - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { ++__x; return __x; } template - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { ranges::advance(__x, __n); return __x; } @@ -73,7 +70,7 @@ struct __fn { } // namespace __next inline namespace __cpo { - inline constexpr auto next = __next::__fn{}; +inline constexpr auto next = __next::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/libcxx/include/__iterator/ostream_iterator.h b/libcxx/include/__iterator/ostream_iterator.h index 381f75832fc65367b548becf59c0eac27cf2d115..05697e62d9dcb9751e425af65d676d1817cb121d 100644 --- a/libcxx/include/__iterator/ostream_iterator.h +++ b/libcxx/include/__iterator/ostream_iterator.h @@ -31,40 +31,43 @@ class _LIBCPP_TEMPLATE_VIS ostream_iterator : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + public: - typedef output_iterator_tag iterator_category; - typedef void value_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; #if _LIBCPP_STD_VER >= 20 - typedef ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; #else - typedef void difference_type; + typedef void difference_type; #endif - typedef void pointer; - typedef void reference; - typedef _CharT char_type; - typedef _Traits traits_type; - typedef basic_ostream<_CharT, _Traits> ostream_type; + typedef void pointer; + typedef void reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; private: - ostream_type* __out_stream_; - const char_type* __delim_; + ostream_type* __out_stream_; + const char_type* __delim_; + public: - _LIBCPP_HIDE_FROM_ABI ostream_iterator(ostream_type& __s) _NOEXCEPT - : __out_stream_(std::addressof(__s)), __delim_(nullptr) {} - _LIBCPP_HIDE_FROM_ABI ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT - : __out_stream_(std::addressof(__s)), __delim_(__delimiter) {} - _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator=(const _Tp& __value) - { - *__out_stream_ << __value; - if (__delim_) - *__out_stream_ << __delim_; - return *this; - } + _LIBCPP_HIDE_FROM_ABI ostream_iterator(ostream_type& __s) _NOEXCEPT + : __out_stream_(std::addressof(__s)), + __delim_(nullptr) {} + _LIBCPP_HIDE_FROM_ABI ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT + : __out_stream_(std::addressof(__s)), + __delim_(__delimiter) {} + _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator=(const _Tp& __value) { + *__out_stream_ << __value; + if (__delim_) + *__out_stream_ << __delim_; + return *this; + } - _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator*() {return *this;} - _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator++() {return *this;} - _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator++(int) {return *this;} + _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator++(int) { return *this; } }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/ostreambuf_iterator.h b/libcxx/include/__iterator/ostreambuf_iterator.h index 6f7491eda5b493916641c6a717b5c796dd5c5dbe..dda0094dc3f5351a6e004d13ed92c63ae4140443 100644 --- a/libcxx/include/__iterator/ostreambuf_iterator.h +++ b/libcxx/include/__iterator/ostreambuf_iterator.h @@ -29,47 +29,42 @@ class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + public: - typedef output_iterator_tag iterator_category; - typedef void value_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; #if _LIBCPP_STD_VER >= 20 - typedef ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; #else - typedef void difference_type; + typedef void difference_type; #endif - typedef void pointer; - typedef void reference; - typedef _CharT char_type; - typedef _Traits traits_type; - typedef basic_streambuf<_CharT, _Traits> streambuf_type; - typedef basic_ostream<_CharT, _Traits> ostream_type; + typedef void pointer; + typedef void reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; private: - streambuf_type* __sbuf_; + streambuf_type* __sbuf_; + public: - _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator(ostream_type& __s) _NOEXCEPT - : __sbuf_(__s.rdbuf()) {} - _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT - : __sbuf_(__s) {} - _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator=(_CharT __c) - { - if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof())) - __sbuf_ = nullptr; - return *this; - } - _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator*() {return *this;} - _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator++() {return *this;} - _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator++(int) {return *this;} - _LIBCPP_HIDE_FROM_ABI bool failed() const _NOEXCEPT {return __sbuf_ == nullptr;} + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator(ostream_type& __s) _NOEXCEPT : __sbuf_(__s.rdbuf()) {} + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT : __sbuf_(__s) {} + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator=(_CharT __c) { + if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof())) + __sbuf_ = nullptr; + return *this; + } + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator++(int) { return *this; } + _LIBCPP_HIDE_FROM_ABI bool failed() const _NOEXCEPT { return __sbuf_ == nullptr; } - template - friend - _LIBCPP_HIDE_FROM_ABI - ostreambuf_iterator<_Ch, _Tr> - __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s, - const _Ch* __ob, const _Ch* __op, const _Ch* __oe, - ios_base& __iob, _Ch __fl); + template + friend _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator<_Ch, _Tr> __pad_and_output( + ostreambuf_iterator<_Ch, _Tr> __s, const _Ch* __ob, const _Ch* __op, const _Ch* __oe, ios_base& __iob, _Ch __fl); }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/permutable.h b/libcxx/include/__iterator/permutable.h index adf88f506529fd147ae955a03cebe9038e0a0e50..f65ba3bfbbaad44c47a475ca2bddde205bd17cfb 100644 --- a/libcxx/include/__iterator/permutable.h +++ b/libcxx/include/__iterator/permutable.h @@ -24,8 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template concept permutable = - forward_iterator<_Iterator> && - indirectly_movable_storable<_Iterator, _Iterator> && + forward_iterator<_Iterator> && indirectly_movable_storable<_Iterator, _Iterator> && indirectly_swappable<_Iterator, _Iterator>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/prev.h b/libcxx/include/__iterator/prev.h index 3bc29a27e743ecfa5667d34f7c10df1f27626c57..1651942acea9e79212a02ad21aadae7014b236a1 100644 --- a/libcxx/include/__iterator/prev.h +++ b/libcxx/include/__iterator/prev.h @@ -25,9 +25,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - _InputIter - prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _InputIter +prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { _LIBCPP_ASSERT_UNCATEGORIZED(__n <= 0 || __has_bidirectional_iterator_category<_InputIter>::value, "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator"); std::advance(__x, -__n); @@ -43,15 +42,13 @@ namespace __prev { struct __fn { template - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { --__x; return __x; } template - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { ranges::advance(__x, -__n); return __x; } @@ -66,7 +63,7 @@ struct __fn { } // namespace __prev inline namespace __cpo { - inline constexpr auto prev = __prev::__fn{}; +inline constexpr auto prev = __prev::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/libcxx/include/__iterator/readable_traits.h b/libcxx/include/__iterator/readable_traits.h index 9e101fc28a6f1d97006c4d41d3fb02ab66d51f50..25e74567fff11dd93782468170c84a3a24c18452 100644 --- a/libcxx/include/__iterator/readable_traits.h +++ b/libcxx/include/__iterator/readable_traits.h @@ -29,50 +29,50 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 // [readable.traits] -template struct __cond_value_type {}; +template +struct __cond_value_type {}; -template -requires is_object_v<_Tp> -struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; }; +template + requires is_object_v<_Tp> +struct __cond_value_type<_Tp> { + using value_type = remove_cv_t<_Tp>; +}; -template +template concept __has_member_value_type = requires { typename _Tp::value_type; }; -template +template concept __has_member_element_type = requires { typename _Tp::element_type; }; -template struct indirectly_readable_traits {}; +template +struct indirectly_readable_traits {}; -template -requires is_array_v<_Ip> +template + requires is_array_v<_Ip> struct indirectly_readable_traits<_Ip> { using value_type = remove_cv_t>; }; -template +template struct indirectly_readable_traits : indirectly_readable_traits<_Ip> {}; -template +template struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {}; -template<__has_member_value_type _Tp> -struct indirectly_readable_traits<_Tp> - : __cond_value_type {}; +template <__has_member_value_type _Tp> +struct indirectly_readable_traits<_Tp> : __cond_value_type {}; -template<__has_member_element_type _Tp> -struct indirectly_readable_traits<_Tp> - : __cond_value_type {}; +template <__has_member_element_type _Tp> +struct indirectly_readable_traits<_Tp> : __cond_value_type {}; -template<__has_member_value_type _Tp> +template <__has_member_value_type _Tp> requires __has_member_element_type<_Tp> struct indirectly_readable_traits<_Tp> {}; -template<__has_member_value_type _Tp> +template <__has_member_value_type _Tp> requires __has_member_element_type<_Tp> && - same_as, - remove_cv_t> -struct indirectly_readable_traits<_Tp> - : __cond_value_type {}; + same_as, remove_cv_t> +struct indirectly_readable_traits<_Tp> : __cond_value_type {}; #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__iterator/reverse_access.h b/libcxx/include/__iterator/reverse_access.h index 5e01f667e115fb2382a7d0babfc27f4265caeb6d..54d7270b04a53784a2a791fc97f3bdbe86e0ada0 100644 --- a/libcxx/include/__iterator/reverse_access.h +++ b/libcxx/include/__iterator/reverse_access.h @@ -24,73 +24,53 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 14 template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) -{ - return reverse_iterator<_Tp*>(__array + _Np); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) { + return reverse_iterator<_Tp*>(__array + _Np); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) -{ - return reverse_iterator<_Tp*>(__array); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) { + return reverse_iterator<_Tp*>(__array); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator rbegin(initializer_list<_Ep> __il) -{ - return reverse_iterator(__il.end()); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin(initializer_list<_Ep> __il) { + return reverse_iterator(__il.end()); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator rend(initializer_list<_Ep> __il) -{ - return reverse_iterator(__il.begin()); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend(initializer_list<_Ep> __il) { + return reverse_iterator(__il.begin()); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto rbegin(_Cp& __c) -> decltype(__c.rbegin()) -{ - return __c.rbegin(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rbegin(_Cp& __c) -> decltype(__c.rbegin()) { + return __c.rbegin(); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto rbegin(const _Cp& __c) -> decltype(__c.rbegin()) -{ - return __c.rbegin(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rbegin(const _Cp& __c) -> decltype(__c.rbegin()) { + return __c.rbegin(); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto rend(_Cp& __c) -> decltype(__c.rend()) -{ - return __c.rend(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rend(_Cp& __c) -> decltype(__c.rend()) { + return __c.rend(); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto rend(const _Cp& __c) -> decltype(__c.rend()) -{ - return __c.rend(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rend(const _Cp& __c) -> decltype(__c.rend()) { + return __c.rend(); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto crbegin(const _Cp& __c) -> decltype(std::rbegin(__c)) -{ - return std::rbegin(__c); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crbegin(const _Cp& __c) -> decltype(std::rbegin(__c)) { + return std::rbegin(__c); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto crend(const _Cp& __c) -> decltype(std::rend(__c)) -{ - return std::rend(__c); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crend(const _Cp& __c) -> decltype(std::rend(__c)) { + return std::rend(__c); } #endif // _LIBCPP_STD_VER >= 14 diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h index 552699bfafa4e4009b81d944c551ac038db72f3c..79b48bcea57a1b9e080de003edeb3ec1c764d582 100644 --- a/libcxx/include/__iterator/reverse_iterator.h +++ b/libcxx/include/__iterator/reverse_iterator.h @@ -57,279 +57,262 @@ class _LIBCPP_TEMPLATE_VIS reverse_iterator typename iterator_traits<_Iter>::reference> #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + private: #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES - _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break + _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break #endif #if _LIBCPP_STD_VER >= 20 - static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>, - "reverse_iterator requires It to be a bidirectional iterator."); + static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>, + "reverse_iterator requires It to be a bidirectional iterator."); #endif // _LIBCPP_STD_VER >= 20 protected: - _Iter current; + _Iter current; + public: - using iterator_type = _Iter; + using iterator_type = _Iter; - using iterator_category = _If<__has_random_access_iterator_category<_Iter>::value, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category>; - using pointer = typename iterator_traits<_Iter>::pointer; + using iterator_category = + _If<__has_random_access_iterator_category<_Iter>::value, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category>; + using pointer = typename iterator_traits<_Iter>::pointer; #if _LIBCPP_STD_VER >= 20 - using iterator_concept = _If, random_access_iterator_tag, bidirectional_iterator_tag>; - using value_type = iter_value_t<_Iter>; - using difference_type = iter_difference_t<_Iter>; - using reference = iter_reference_t<_Iter>; + using iterator_concept = _If, random_access_iterator_tag, bidirectional_iterator_tag>; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; #else - using value_type = typename iterator_traits<_Iter>::value_type; - using difference_type = typename iterator_traits<_Iter>::difference_type; - using reference = typename iterator_traits<_Iter>::reference; + using value_type = typename iterator_traits<_Iter>::value_type; + using difference_type = typename iterator_traits<_Iter>::difference_type; + using reference = typename iterator_traits<_Iter>::reference; #endif #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator() : __t_(), current() {} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {} - - template ::value && is_convertible<_Up const&, _Iter>::value - > > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator(const reverse_iterator<_Up>& __u) - : __t_(__u.base()), current(__u.base()) - { } - - template ::value && - is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter&, _Up const&>::value - > > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { - __t_ = current = __u.base(); - return *this; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator() : __t_(), current() {} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {} + + template ::value && is_convertible<_Up const&, _Iter>::value > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator(const reverse_iterator<_Up>& __u) + : __t_(__u.base()), current(__u.base()) {} + + template ::value && is_convertible<_Up const&, _Iter>::value && + is_assignable<_Iter&, _Up const&>::value > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { + __t_ = current = __u.base(); + return *this; + } #else - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator() : current() {} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - explicit reverse_iterator(_Iter __x) : current(__x) {} - - template ::value && is_convertible<_Up const&, _Iter>::value - > > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator(const reverse_iterator<_Up>& __u) - : current(__u.base()) - { } - - template ::value && - is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter&, _Up const&>::value - > > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { - current = __u.base(); - return *this; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator() : current() {} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x) : current(__x) {} + + template ::value && is_convertible<_Up const&, _Iter>::value > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator(const reverse_iterator<_Up>& __u) + : current(__u.base()) {} + + template ::value && is_convertible<_Up const&, _Iter>::value && + is_assignable<_Iter&, _Up const&>::value > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { + current = __u.base(); + return *this; + } #endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - _Iter base() const {return current;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reference operator*() const {_Iter __tmp = current; return *--__tmp;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter base() const { return current; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator*() const { + _Iter __tmp = current; + return *--__tmp; + } #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI - constexpr pointer operator->() const - requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); } - { - if constexpr (is_pointer_v<_Iter>) { - return std::prev(current); - } else { - return std::prev(current).operator->(); - } + _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const + requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); } + { + if constexpr (is_pointer_v<_Iter>) { + return std::prev(current); + } else { + return std::prev(current).operator->(); } + } #else - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - pointer operator->() const { - return std::addressof(operator*()); - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pointer operator->() const { return std::addressof(operator*()); } #endif // _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator++() {--current; return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator--() {++current; return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reference operator[](difference_type __n) const {return *(*this + __n);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator++() { + --current; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator operator++(int) { + reverse_iterator __tmp(*this); + --current; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator--() { + ++current; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator operator--(int) { + reverse_iterator __tmp(*this); + ++current; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator operator+(difference_type __n) const { + return reverse_iterator(current - __n); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator+=(difference_type __n) { + current -= __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator operator-(difference_type __n) const { + return reverse_iterator(current + __n); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator-=(difference_type __n) { + current += __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](difference_type __n) const { + return *(*this + __n); + } #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI friend constexpr - iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i) - noexcept(is_nothrow_copy_constructible_v<_Iter> && - noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { - auto __tmp = __i.base(); - return ranges::iter_move(--__tmp); - } + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i) noexcept( + is_nothrow_copy_constructible_v<_Iter>&& noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { + auto __tmp = __i.base(); + return ranges::iter_move(--__tmp); + } - template _Iter2> - _LIBCPP_HIDE_FROM_ABI friend constexpr - void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y) - noexcept(is_nothrow_copy_constructible_v<_Iter> && - is_nothrow_copy_constructible_v<_Iter2> && - noexcept(ranges::iter_swap(--std::declval<_Iter&>(), --std::declval<_Iter2&>()))) { - auto __xtmp = __x.base(); - auto __ytmp = __y.base(); - ranges::iter_swap(--__xtmp, --__ytmp); - } + template _Iter2> + _LIBCPP_HIDE_FROM_ABI friend constexpr void + iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y) noexcept( + is_nothrow_copy_constructible_v<_Iter> && + is_nothrow_copy_constructible_v<_Iter2>&& noexcept( + ranges::iter_swap(--std::declval<_Iter&>(), --std::declval<_Iter2&>()))) { + auto __xtmp = __x.base(); + auto __ytmp = __y.base(); + ranges::iter_swap(--__xtmp, --__ytmp); + } #endif // _LIBCPP_STD_VER >= 20 }; template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() == __y.base() } -> convertible_to; - } + requires requires { + { __x.base() == __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() == __y.base(); + return __x.base() == __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() > __y.base() } -> convertible_to; - } + requires requires { + { __x.base() > __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() > __y.base(); + return __x.base() > __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() != __y.base() } -> convertible_to; - } + requires requires { + { __x.base() != __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() != __y.base(); + return __x.base() != __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() < __y.base() } -> convertible_to; - } + requires requires { + { __x.base() < __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() < __y.base(); + return __x.base() < __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() <= __y.base() } -> convertible_to; - } + requires requires { + { __x.base() <= __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() <= __y.base(); + return __x.base() <= __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() >= __y.base() } -> convertible_to; - } + requires requires { + { __x.base() >= __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() >= __y.base(); + return __x.base() >= __y.base(); } #if _LIBCPP_STD_VER >= 20 template _Iter2> -_LIBCPP_HIDE_FROM_ABI constexpr -compare_three_way_result_t<_Iter1, _Iter2> -operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) -{ - return __y.base() <=> __x.base(); +_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Iter1, _Iter2> +operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { + return __y.base() <=> __x.base(); } #endif // _LIBCPP_STD_VER >= 20 #ifndef _LIBCPP_CXX03_LANG template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) --> decltype(__y.base() - __x.base()) -{ - return __y.base() - __x.base(); + -> decltype(__y.base() - __x.base()) { + return __y.base() - __x.base(); } #else template -inline _LIBCPP_HIDE_FROM_ABI -typename reverse_iterator<_Iter1>::difference_type -operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) -{ - return __y.base() - __x.base(); +inline _LIBCPP_HIDE_FROM_ABI typename reverse_iterator<_Iter1>::difference_type +operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { + return __y.base() - __x.base(); } #endif template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator<_Iter> -operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) -{ - return reverse_iterator<_Iter>(__x.base() - __n); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Iter> +operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) { + return reverse_iterator<_Iter>(__x.base() - __n); } #if _LIBCPP_STD_VER >= 20 template - requires (!sized_sentinel_for<_Iter1, _Iter2>) + requires(!sized_sentinel_for<_Iter1, _Iter2>) inline constexpr bool disable_sized_sentinel_for, reverse_iterator<_Iter2>> = true; #endif // _LIBCPP_STD_VER >= 20 #if _LIBCPP_STD_VER >= 14 template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) -{ - return reverse_iterator<_Iter>(__i); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) { + return reverse_iterator<_Iter>(__i); } #endif @@ -369,13 +352,15 @@ public: using iterator_type = _Iter; using iterator_category = - _If<__has_random_access_iterator_category<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>; - using pointer = __iterator_pointer_type<_Iter>; - using value_type = iter_value_t<_Iter>; + _If<__has_random_access_iterator_category<_Iter>::value, + random_access_iterator_tag, + __iterator_category_type<_Iter>>; + using pointer = __iterator_pointer_type<_Iter>; + using value_type = iter_value_t<_Iter>; using difference_type = iter_difference_t<_Iter>; - using reference = iter_reference_t<_Iter>; + using reference = iter_reference_t<_Iter>; - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator() = default; + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator() = default; _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator(const __unconstrained_reverse_iterator&) = default; _LIBCPP_HIDE_FROM_ABI constexpr explicit __unconstrained_reverse_iterator(_Iter __iter) : __iter_(__iter) {} @@ -393,10 +378,9 @@ public: } } - _LIBCPP_HIDE_FROM_ABI friend constexpr - iter_rvalue_reference_t<_Iter> iter_move(const __unconstrained_reverse_iterator& __i) - noexcept(is_nothrow_copy_constructible_v<_Iter> && - noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> + iter_move(const __unconstrained_reverse_iterator& __i) noexcept( + is_nothrow_copy_constructible_v<_Iter>&& noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { auto __tmp = __i.base(); return ranges::iter_move(--__tmp); } @@ -484,7 +468,7 @@ public: template