From c2c917f7f6680ec7a1214af9f5105c2beb9ba162 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Mon, 8 May 2023 14:02:48 -0500 Subject: [PATCH 001/608] [Clang] Change default triple to LLVM_HOST_TRIPLE for the CUDA toolchain When cross-compiling NVPTX we use the triple to indicate which paths to search for the CUDA toolchain. Currently this uses the default target triple. This might not be exactly correct, as this is the default triple used to compile binaries, not the host system. We want the host triple because it indicates which folders should hold CUDA. Reviewed By: tra Differential Revision: https://reviews.llvm.org/D150136 --- clang/lib/Driver/ToolChains/Cuda.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index c0fcdad861994..37b0b9c2ed05b 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -711,8 +711,7 @@ NVPTXToolChain::NVPTXToolChain(const Driver &D, const llvm::Triple &Triple, /// system's default triple if not provided. NVPTXToolChain::NVPTXToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : NVPTXToolChain(D, Triple, - llvm::Triple(llvm::sys::getDefaultTargetTriple()), Args, + : NVPTXToolChain(D, Triple, llvm::Triple(LLVM_HOST_TRIPLE), Args, /*Freestanding=*/true) {} llvm::opt::DerivedArgList * From 39c1005227fd39b528992dc9fb8126302f611c65 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Fri, 5 May 2023 17:28:41 -0700 Subject: [PATCH 002/608] [NFC][msan] Rename function parameter --- compiler-rt/lib/msan/msan_interceptors.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp index 757dc46739bea..4dbcd064d41eb 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/compiler-rt/lib/msan/msan_interceptors.cpp @@ -1112,9 +1112,9 @@ INTERCEPTOR(int, __libc_thr_keycreate, __sanitizer_pthread_key_t *m, ALIAS(WRAPPER_NAME(pthread_key_create)); #endif -INTERCEPTOR(int, pthread_join, void *th, void **retval) { +INTERCEPTOR(int, pthread_join, void *thread, void **retval) { ENSURE_MSAN_INITED(); - int res = REAL(pthread_join)(th, retval); + int res = REAL(pthread_join)(thread, retval); if (!res && retval) __msan_unpoison(retval, sizeof(*retval)); return res; From 5ec62943ac188994d7c7d54ea995398a4c62e74f Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Fri, 5 May 2023 17:28:57 -0700 Subject: [PATCH 003/608] [msan] Add pthread_*join_np interceptors --- compiler-rt/lib/msan/msan_interceptors.cpp | 22 +++++++++++++++++++ .../TestCases/Linux/pthread_join.cpp | 2 -- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp index 4dbcd064d41eb..8cf724b3949f2 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/compiler-rt/lib/msan/msan_interceptors.cpp @@ -1120,6 +1120,24 @@ INTERCEPTOR(int, pthread_join, void *thread, void **retval) { return res; } +#if SANITIZER_GLIBC +INTERCEPTOR(int, pthread_tryjoin_np, void *thread, void **retval) { + ENSURE_MSAN_INITED(); + int res = REAL(pthread_tryjoin_np)(thread, retval); + if (!res && retval) + __msan_unpoison(retval, sizeof(*retval)); + return res; +} + +INTERCEPTOR(int, pthread_timedjoin_np, void *thread, void **retval, + const struct timespec *abstime) { + int res = REAL(pthread_timedjoin_np)(thread, retval, abstime); + if (!res && retval) + __msan_unpoison(retval, sizeof(*retval)); + return res; +} +#endif + DEFINE_REAL_PTHREAD_FUNCTIONS extern char *tzname[2]; @@ -1777,6 +1795,10 @@ void InitializeInterceptors() { #endif INTERCEPT_FUNCTION(pthread_join); INTERCEPT_FUNCTION(pthread_key_create); +#if SANITIZER_GLIBC + INTERCEPT_FUNCTION(pthread_tryjoin_np); + INTERCEPT_FUNCTION(pthread_timedjoin_np); +#endif #if SANITIZER_NETBSD INTERCEPT_FUNCTION(__libc_thr_keycreate); diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp index 2b35b163b1430..212a28dd3985b 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp @@ -4,8 +4,6 @@ // FIXME: Crashes on some bots in pthread_exit. // RUN: %run %t %if tsan %{ 0 %} %else %{ 1 %} -// XFAIL: msan - // REQUIRES: glibc #include From 27cf6ba1d7bc623a5dca5c0ae82af98d0cdfc390 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Wed, 19 Apr 2023 11:59:43 -0700 Subject: [PATCH 004/608] [flang][runtime] Initialize uninitialized pointer components Pointer components without default initialization pose some difficult (or impossible) problems when they appear as right-hand side targets in pointer assignment statements; they may contain garbage or stale data that looks enough like a valid descriptor to cause a crash. Solve the problem by avoiding it -- ensure that pointers' descriptors are at least minimally established. Differential Revision: https://reviews.llvm.org/D149979 --- flang/include/flang/Semantics/tools.h | 2 +- flang/include/flang/Semantics/type.h | 3 ++- flang/lib/Semantics/check-data.cpp | 3 ++- flang/lib/Semantics/expression.cpp | 14 ++++++++------ flang/lib/Semantics/runtime-type-info.cpp | 4 ++-- flang/lib/Semantics/tools.cpp | 12 +++++++----- flang/lib/Semantics/type.cpp | 6 ++++-- flang/runtime/derived.cpp | 10 ++++++++++ flang/runtime/type-info.cpp | 2 +- flang/test/Semantics/canondo01.f90 | 1 - flang/test/Semantics/structconst07.f90 | 9 +++++++++ flang/test/Semantics/structconst07.f90# | 5 ----- flang/test/Semantics/typeinfo03.f90 | 9 +++++++++ 13 files changed, 55 insertions(+), 25 deletions(-) create mode 100644 flang/test/Semantics/structconst07.f90 delete mode 100644 flang/test/Semantics/structconst07.f90# create mode 100644 flang/test/Semantics/typeinfo03.f90 diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h index 4a78b31c5a792..ee62b66d54b0f 100644 --- a/flang/include/flang/Semantics/tools.h +++ b/flang/include/flang/Semantics/tools.h @@ -117,7 +117,7 @@ bool CanBeTypeBoundProc(const Symbol &); bool HasDeclarationInitializer(const Symbol &); // Is the symbol explicitly or implicitly initialized in any way? bool IsInitialized(const Symbol &, bool ignoreDATAstatements = false, - bool ignoreAllocatable = false); + bool ignoreAllocatable = false, bool ignorePointer = true); // Is the symbol a component subject to deallocation or finalization? bool IsDestructible(const Symbol &, const Symbol *derivedType = nullptr); bool HasIntrinsicTypeName(const Symbol &); diff --git a/flang/include/flang/Semantics/type.h b/flang/include/flang/Semantics/type.h index 76866c8e994b0..3fcd438eaf134 100644 --- a/flang/include/flang/Semantics/type.h +++ b/flang/include/flang/Semantics/type.h @@ -266,7 +266,8 @@ class DerivedTypeSpec { bool MightBeParameterized() const; bool IsForwardReferenced() const; - bool HasDefaultInitialization(bool ignoreAllocatable = false) const; + bool HasDefaultInitialization( + bool ignoreAllocatable = false, bool ignorePointer = true) const; bool HasDestruction() const; // The "raw" type parameter list is a simple transcription from the diff --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp index f33258ea7c19a..6916870907a63 100644 --- a/flang/lib/Semantics/check-data.cpp +++ b/flang/lib/Semantics/check-data.cpp @@ -63,7 +63,8 @@ class DataVarChecker : public evaluate::AllTraverse { : IsFunctionResult(symbol) ? "Function result" : IsAllocatable(symbol) ? "Allocatable" : IsInitialized(symbol, true /*ignore DATA*/, - true /*ignore allocatable components*/) + true /*ignore allocatable components*/, + true /*ignore uninitialized pointer components*/) ? "Default-initialized" : IsProcedure(symbol) && !IsPointer(symbol) ? "Procedure" // remaining checks don't apply to components diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index cec936c8f5e42..5ec83344d03d0 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -2066,13 +2066,15 @@ MaybeExpr ExpressionAnalyzer::Analyze( if (!symbol.test(Symbol::Flag::ParentComp) && unavailable.find(symbol.name()) == unavailable.cend()) { if (IsAllocatable(symbol)) { - // Set all remaining allocatables to explicit NULL() + // Set all remaining allocatables to explicit NULL(). result.Add(symbol, Expr{NullPointer{}}); - } else if (const auto *details{ - symbol.detailsIf()}) { - if (details->init()) { - result.Add(symbol, common::Clone(*details->init())); - } else { // C799 + } else { + const auto *object{symbol.detailsIf()}; + if (object && object->init()) { + result.Add(symbol, common::Clone(*object->init())); + } else if (IsPointer(symbol)) { + result.Add(symbol, Expr{NullPointer{}}); + } else if (object) { // C799 AttachDeclaration(Say(typeName, "Structure constructor lacks a value for " "component '%s'"_err_en_US, diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp index 15a2a67103236..acd3c49b39098 100644 --- a/flang/lib/Semantics/runtime-type-info.cpp +++ b/flang/lib/Semantics/runtime-type-info.cpp @@ -626,8 +626,8 @@ const Symbol *RuntimeTableBuilder::DescribeType(Scope &dtScope) { // instances without any initialized components, analyze the type // and set a flag if there's nothing to do for it at run time. AddValue(dtValues, derivedTypeSchema_, "noinitializationneeded"s, - IntExpr<1>( - derivedTypeSpec && !derivedTypeSpec->HasDefaultInitialization())); + IntExpr<1>(derivedTypeSpec && + !derivedTypeSpec->HasDefaultInitialization(false, false))); // Similarly, a flag to short-circuit destruction when not needed. AddValue(dtValues, derivedTypeSchema_, "nodestructionneeded"s, IntExpr<1>(isAbstractType || diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp index fb2710b54284c..711537ec4947b 100644 --- a/flang/lib/Semantics/tools.cpp +++ b/flang/lib/Semantics/tools.cpp @@ -642,21 +642,23 @@ bool HasDeclarationInitializer(const Symbol &symbol) { } } -bool IsInitialized( - const Symbol &symbol, bool ignoreDataStatements, bool ignoreAllocatable) { +bool IsInitialized(const Symbol &symbol, bool ignoreDataStatements, + bool ignoreAllocatable, bool ignorePointer) { if (!ignoreAllocatable && IsAllocatable(symbol)) { return true; } else if (!ignoreDataStatements && symbol.test(Symbol::Flag::InDataStmt)) { return true; } else if (HasDeclarationInitializer(symbol)) { return true; - } else if (IsNamedConstant(symbol) || IsFunctionResult(symbol) || - IsPointer(symbol)) { + } else if (IsPointer(symbol)) { + return !ignorePointer; + } else if (IsNamedConstant(symbol) || IsFunctionResult(symbol)) { return false; } else if (const auto *object{symbol.detailsIf()}) { if (!object->isDummy() && object->type()) { if (const auto *derived{object->type()->AsDerived()}) { - return derived->HasDefaultInitialization(ignoreAllocatable); + return derived->HasDefaultInitialization( + ignoreAllocatable, ignorePointer); } } } diff --git a/flang/lib/Semantics/type.cpp b/flang/lib/Semantics/type.cpp index d895f01dba2ea..667fdc453687a 100644 --- a/flang/lib/Semantics/type.cpp +++ b/flang/lib/Semantics/type.cpp @@ -179,11 +179,13 @@ bool DerivedTypeSpec::IsForwardReferenced() const { return typeSymbol_.get().isForwardReferenced(); } -bool DerivedTypeSpec::HasDefaultInitialization(bool ignoreAllocatable) const { +bool DerivedTypeSpec::HasDefaultInitialization( + bool ignoreAllocatable, bool ignorePointer) const { DirectComponentIterator components{*this}; return bool{std::find_if( components.begin(), components.end(), [&](const Symbol &component) { - return IsInitialized(component, true, ignoreAllocatable); + return IsInitialized(component, /*ignoreDataStatements=*/true, + ignoreAllocatable, ignorePointer); })}; } diff --git a/flang/runtime/derived.cpp b/flang/runtime/derived.cpp index 981ddb2a6e9d4..814fcfa1e1e7d 100644 --- a/flang/runtime/derived.cpp +++ b/flang/runtime/derived.cpp @@ -58,6 +58,16 @@ int Initialize(const Descriptor &instance, const typeInfo::DerivedType &derived, char *ptr{instance.ZeroBasedIndexedElement(j) + comp.offset()}; std::memcpy(ptr, init, bytes); } + } else if (comp.genre() == typeInfo::Component::Genre::Pointer) { + // Data pointers without explicit initialization are established + // so that they are valid right-hand side targets of pointer + // assignment statements. + for (std::size_t j{0}; j < elements; ++j) { + Descriptor &ptrDesc{*instance.OffsetElement( + j * byteStride + comp.offset())}; + comp.EstablishDescriptor(ptrDesc, instance, terminator); + ptrDesc.raw().attribute = CFI_attribute_pointer; + } } else if (comp.genre() == typeInfo::Component::Genre::Data && comp.derivedType() && !comp.derivedType()->noInitializationNeeded()) { // Default initialization of non-pointer non-allocatable/automatic diff --git a/flang/runtime/type-info.cpp b/flang/runtime/type-info.cpp index 84ec05d02705f..9b624a664a2f5 100644 --- a/flang/runtime/type-info.cpp +++ b/flang/runtime/type-info.cpp @@ -112,7 +112,7 @@ void Component::EstablishDescriptor(Descriptor &descriptor, } else { descriptor.Establish(cat, kind_, nullptr, rank_, nullptr, attribute); } - if (rank_ && genre_ != Genre::Allocatable) { + if (rank_ && genre_ != Genre::Allocatable && genre_ != Genre::Pointer) { const typeInfo::Value *boundValues{bounds()}; RUNTIME_CHECK(terminator, boundValues != nullptr); auto byteStride{static_cast(descriptor.ElementBytes())}; diff --git a/flang/test/Semantics/canondo01.f90 b/flang/test/Semantics/canondo01.f90 index 50ffa489019e2..7a48db346e9a7 100644 --- a/flang/test/Semantics/canondo01.f90 +++ b/flang/test/Semantics/canondo01.f90 @@ -1,4 +1,3 @@ - ! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s ! CHECK: end do diff --git a/flang/test/Semantics/structconst07.f90 b/flang/test/Semantics/structconst07.f90 new file mode 100644 index 0000000000000..a34289a817af4 --- /dev/null +++ b/flang/test/Semantics/structconst07.f90 @@ -0,0 +1,9 @@ +! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s +type :: hasPointer + class(*), pointer :: sp +end type +type(hasPointer) hp +!CHECK: hp=haspointer(sp=NULL()) +hp = hasPointer() +end + diff --git a/flang/test/Semantics/structconst07.f90# b/flang/test/Semantics/structconst07.f90# deleted file mode 100644 index af75b43658d32..0000000000000 --- a/flang/test/Semantics/structconst07.f90# +++ /dev/null @@ -1,5 +0,0 @@ -! RUN: %python %S/test_errors.py %s %flang_fc1 -! C1594(4) -module m - type t1 - diff --git a/flang/test/Semantics/typeinfo03.f90 b/flang/test/Semantics/typeinfo03.f90 new file mode 100644 index 0000000000000..f0c0a817da4a4 --- /dev/null +++ b/flang/test/Semantics/typeinfo03.f90 @@ -0,0 +1,9 @@ +!RUN: bbc --dump-symbols %s | FileCheck %s +!RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s +!Ensure that type with pointer component(s) has "noinitializationneeded=0" +module m + type hasPointer + class(*), pointer :: sp, ap(:) + end type +end module +!CHECK: .dt.haspointer, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.haspointer,sizeinbytes=104_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.haspointer,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) From 30b4351c7c75296dc60fc887212cdc98e85e9996 Mon Sep 17 00:00:00 2001 From: Jon Roelofs Date: Mon, 8 May 2023 14:10:18 -0700 Subject: [PATCH 005/608] cmake: add missing dependencies on Attributes.inc Differential revision: https://reviews.llvm.org/D150144 --- llvm/unittests/Analysis/CMakeLists.txt | 2 ++ llvm/utils/TableGen/CMakeLists.txt | 3 +++ 2 files changed, 5 insertions(+) diff --git a/llvm/unittests/Analysis/CMakeLists.txt b/llvm/unittests/Analysis/CMakeLists.txt index c21ad3afa18a3..847430bf17697 100644 --- a/llvm/unittests/Analysis/CMakeLists.txt +++ b/llvm/unittests/Analysis/CMakeLists.txt @@ -64,6 +64,8 @@ add_llvm_unittest_with_input_files(AnalysisTests ${ANALYSIS_TEST_SOURCES} ) +add_dependencies(AnalysisTests intrinsics_gen) + target_link_libraries(AnalysisTests PRIVATE LLVMTestingSupport) # On AIX, enable run-time linking to allow symbols from the plugins shared diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt index 7bdc33d115cc0..880188bd0030f 100644 --- a/llvm/utils/TableGen/CMakeLists.txt +++ b/llvm/utils/TableGen/CMakeLists.txt @@ -86,6 +86,9 @@ add_tablegen(llvm-tblgen LLVM X86RecognizableInstr.cpp WebAssemblyDisassemblerEmitter.cpp $ + + DEPENDS + intrinsics_gen # via llvm-min-tablegen ) target_link_libraries(llvm-tblgen PRIVATE LLVMTableGenGlobalISel) set_target_properties(llvm-tblgen PROPERTIES FOLDER "Tablegenning") From 69520fc771279fbe6e7783ce7119b5350b14a61b Mon Sep 17 00:00:00 2001 From: Alexander Yermolovich Date: Mon, 8 May 2023 15:39:10 -0700 Subject: [PATCH 006/608] [BOLT][DWARF] Fix dwarf5-one-loclists-two-bases test Fix assembly for the helper file to work with the new DWARF rewriter. Reviewed By: maksfb Differential Revision: https://reviews.llvm.org/D150147 --- .../X86/Inputs/dwarf5-loc-base-no-loc-accesshelper.s | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/bolt/test/X86/Inputs/dwarf5-loc-base-no-loc-accesshelper.s b/bolt/test/X86/Inputs/dwarf5-loc-base-no-loc-accesshelper.s index dcf9f6a23a07b..8705755062efd 100644 --- a/bolt/test/X86/Inputs/dwarf5-loc-base-no-loc-accesshelper.s +++ b/bolt/test/X86/Inputs/dwarf5-loc-base-no-loc-accesshelper.s @@ -286,11 +286,10 @@ fooVar: .long .Lloclists_table_base0 # DW_AT_loclists_base .byte 2 # Abbrev [2] 0x27:0xb DW_TAG_variable .byte 3 # DW_AT_name - .long 50 # DW_AT_type + .long 39 # DW_AT_type # DW_AT_external .byte 0 # DW_AT_decl_file .byte 1 # DW_AT_decl_line - .byte 0 .byte 3 # Abbrev [3] 0x32:0x4 DW_TAG_base_type .byte 4 # DW_AT_name .byte 5 # DW_AT_encoding @@ -319,7 +318,7 @@ fooVar: .long 88 # DW_AT_type .byte 0 # End Of Children Mark .byte 8 # Abbrev [8] 0x58:0x5 DW_TAG_pointer_type - .long 50 # DW_AT_type + .long 39 # DW_AT_type .byte 9 # Abbrev [9] 0x5d:0x31 DW_TAG_subprogram .byte 2 # DW_AT_low_pc .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc @@ -330,18 +329,18 @@ fooVar: .byte 9 # DW_AT_name .byte 0 # DW_AT_decl_file .byte 6 # DW_AT_decl_line - .long 50 # DW_AT_type + .long 39 # DW_AT_type # DW_AT_external .byte 10 # Abbrev [10] 0x6d:0xa DW_TAG_formal_parameter .byte 10 # DW_AT_name .byte 0 # DW_AT_decl_file .byte 6 # DW_AT_decl_line - .long 50 # DW_AT_type + .long 39 # DW_AT_type .byte 11 # Abbrev [11] 0x77:0x9 DW_TAG_variable .byte 7 # DW_AT_name .byte 0 # DW_AT_decl_file .byte 7 # DW_AT_decl_line - .long 50 # DW_AT_type + .long 39 # DW_AT_type .byte 12 # Abbrev [12] 0x80:0xd DW_TAG_inlined_subroutine .long 74 # DW_AT_abstract_origin .byte 2 # DW_AT_low_pc From d15491e90c5bf1891f64ce15a712659c9570c861 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Thu, 20 Apr 2023 14:12:24 -0700 Subject: [PATCH 007/608] [flang] Procedure pointers are not descriptors Code in Evaluate/type.cpp was maintaining a very old assumption that procedure pointers would need to be represented as descriptors. This is not the case -- they are code or thunk addresses. Differential Revision: https://reviews.llvm.org/D149984 --- flang/lib/Evaluate/type.cpp | 12 +----------- flang/test/Semantics/data05.f90 | 16 ++++++++-------- flang/test/Semantics/typeinfo01.f90 | 2 +- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/flang/lib/Evaluate/type.cpp b/flang/lib/Evaluate/type.cpp index a8d0fca70c0c1..83a4ee5c45887 100644 --- a/flang/lib/Evaluate/type.cpp +++ b/flang/lib/Evaluate/type.cpp @@ -47,23 +47,13 @@ static bool IsDescriptor(const ObjectEntityDetails &details) { return false; } -static bool IsDescriptor(const ProcEntityDetails &details) { - // TODO: refine this placeholder; procedure pointers and dummy - // procedures should now be simple addresses (possibly of thunks) - return details.HasExplicitInterface(); -} - bool IsDescriptor(const Symbol &symbol) { return common::visit( common::visitors{ [&](const ObjectEntityDetails &d) { return IsAllocatableOrPointer(symbol) || IsDescriptor(d); }, - [&](const ProcEntityDetails &d) { - return (symbol.attrs().test(Attr::POINTER) || - symbol.attrs().test(Attr::EXTERNAL)) && - IsDescriptor(d); - }, + [&](const ProcEntityDetails &d) { return false; }, [&](const EntityDetails &d) { return IsDescriptor(d.type()); }, [](const AssocEntityDetails &d) { if (const auto &expr{d.expr()}) { diff --git a/flang/test/Semantics/data05.f90 b/flang/test/Semantics/data05.f90 index 7d7693ba3d21f..35b9ed1548d60 100644 --- a/flang/test/Semantics/data05.f90 +++ b/flang/test/Semantics/data05.f90 @@ -25,7 +25,7 @@ real function rfunc(x) end type contains subroutine s1 - procedure(ifunc), pointer :: ifptr ! CHECK: ifptr, EXTERNAL, POINTER (Function, InDataStmt) size=24 offset=0: ProcEntity ifunc => ifunc + procedure(ifunc), pointer :: ifptr ! CHECK: ifptr, EXTERNAL, POINTER (Function, InDataStmt) size=8 offset=0: ProcEntity ifunc => ifunc data ifptr/ifunc/ end subroutine subroutine s2 @@ -59,7 +59,7 @@ real function rfunc2(x) rfunc2 = x + 1. end function subroutine s8 - procedure(rfunc), pointer :: rfptr ! CHECK: rfptr, EXTERNAL, POINTER (Function, InDataStmt) size=24 offset=0: ProcEntity rfunc => rfunc2 + procedure(rfunc), pointer :: rfptr ! CHECK: rfptr, EXTERNAL, POINTER (Function, InDataStmt) size=8 offset=0: ProcEntity rfunc => rfunc2 data rfptr/rfunc2/ end subroutine subroutine s10 @@ -73,20 +73,20 @@ integer function ifunc2(n) end function subroutine s11 real, target, save :: arr(3,4) ! CHECK: arr, SAVE, TARGET size=48 offset=0: ObjectEntity type: REAL(4) shape: 1_8:3_8,1_8:4_8 - type(t1) :: d1 = t1(1,reshape([1,2,3,4],[2,2]),(6.,7.),.false.,'ab',arr,ifunc2,rfunc,extrfunc) ! CHECK: d1 size=168 offset=48: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) + type(t1) :: d1 = t1(1,reshape([1,2,3,4],[2,2]),(6.,7.),.false.,'ab',arr,ifunc2,rfunc,extrfunc) ! CHECK: d1 size=136 offset=48: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) type(t1(4,len=1)) :: d2 = t1(4)(xrp=extrfunc,rp=rfunc,ifptr=ifunc2,xp=arr,c='a& - &b',t=.false.,z=(6.,7.),x=reshape([1,2,3,4],[2,2]),j=1) ! CHECK: d2 size=168 offset=216: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) - type(t1(2+2)) :: d3 ! CHECK: d3 (InDataStmt) size=168 offset=384: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) + &b',t=.false.,z=(6.,7.),x=reshape([1,2,3,4],[2,2]),j=1) ! CHECK: d2 size=136 offset=184: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) + type(t1(2+2)) :: d3 ! CHECK: d3 (InDataStmt) size=136 offset=320: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) data d3/t1(1,reshape([1,2,3,4],[2,2]),(6.,7.),.false.,'ab',arr,ifunc2,rfunc,extrfunc)/ - type(t1) :: d4 ! CHECK: d4 (InDataStmt) size=168 offset=552: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) + type(t1) :: d4 ! CHECK: d4 (InDataStmt) size=136 offset=456: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","a"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) data d4/t1(4)(xrp=extrfunc,rp=rfunc,ifptr=ifunc2,xp=arr,c='ab',t=.false.,z=(6& &.,7.),x=reshape([1,2,3,4],[2,2]),j=1)/ - type(t1) :: d5 ! CHECK: d5 (InDataStmt) size=168 offset=720: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","b"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) + type(t1) :: d5 ! CHECK: d5 (InDataStmt) size=136 offset=592: ObjectEntity type: TYPE(t1(kind=4_1,len=1_2)) init:t1(kind=4_1,len=1_2)(j=1_4,x=reshape([REAL(4)::1._4,2._4,3._4,4._4],shape=[2,2]),z=(6._4,7._4),t=.false._4,c=[CHARACTER(KIND=1,LEN=1)::"a","b"],xp=arr,ifptr=ifunc2,rp=rfunc,xrp=extrfunc) data d5%j/1/,d5%x/1,2,3,4/,d5%z%re/6./,d5%z%im/7./,d5%t/.false./,d5%c(1:1)/'a'/,d5%c(2:& &2)/'b'/,d5%xp/arr/,d5%ifptr/ifunc2/,d5%rp/rfunc/,d5%xrp/extrfunc/ end subroutine subroutine s12 - procedure(rfunc), pointer :: pp ! CHECK: pp, EXTERNAL, POINTER (Function, InDataStmt) size=24 offset=0: ProcEntity rfunc => rfunc2 + procedure(rfunc), pointer :: pp ! CHECK: pp, EXTERNAL, POINTER (Function, InDataStmt) size=8 offset=0: ProcEntity rfunc => rfunc2 data pp/rfunc2/ end subroutine end module diff --git a/flang/test/Semantics/typeinfo01.f90 b/flang/test/Semantics/typeinfo01.f90 index e0e742148cb97..336a5cb623692 100644 --- a/flang/test/Semantics/typeinfo01.f90 +++ b/flang/test/Semantics/typeinfo01.f90 @@ -62,7 +62,7 @@ module m05 subroutine s1(x) class(t), intent(in) :: x end subroutine -!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=24_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=.p.t,special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=8_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=.p.t,special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) !CHECK: .p.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(procptrcomponent) shape: 0_8:0_8 init:[procptrcomponent::procptrcomponent(name=.n.p1,offset=0_8,initialization=s1)] end module From 5da7f30f24c4620c4f4425206fbdd0921d333dc0 Mon Sep 17 00:00:00 2001 From: Michael Francis Date: Sun, 19 Mar 2023 22:42:35 +0000 Subject: [PATCH 008/608] [AIX][Clang][K] Create `-K` Option for AIX. `-K` is a linker option on AIX, that is used to align the header, text, data, and loader sections of the output file so that each section begins on a page boundary. This patch creates the `-K` option in clang. On non-AIX targets, the "unsupported option" error is thrown. Differential Revision: https://reviews.llvm.org/D146399 --- clang/include/clang/Driver/Options.td | 1 + clang/lib/Driver/ToolChains/Clang.cpp | 5 +++++ clang/test/Driver/aix-ld.c | 24 ++++++++++++++++++++++++ clang/test/Driver/unsupported-target-K.c | 8 ++++++++ 4 files changed, 38 insertions(+) create mode 100644 clang/test/Driver/unsupported-target-K.c diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 182f0290736d8..496264b74d460 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3421,6 +3421,7 @@ def vfsoverlay : JoinedOrSeparate<["-", "--"], "vfsoverlay">, Flags<[CC1Option, HelpText<"Overlay the virtual filesystem described by file over the real file system. " "Additionally, pass this overlay file to the linker if it supports it">; def imultilib : Separate<["-"], "imultilib">, Group; +def K : Flag<["-"], "K">, Flags<[LinkerInput]>; def keep__private__externs : Flag<["-"], "keep_private_externs">; def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>, Group; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 32ba56066af58..c12a6ab88097b 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6326,6 +6326,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + if (Arg *A = Args.getLastArgNoClaim(options::OPT_K); + A && !TC.getTriple().isOSAIX()) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << TripleStr; + if (Args.getLastArg(options::OPT_fapple_kext) || (Args.hasArg(options::OPT_mkernel) && types::isCXX(InputType))) CmdArgs.push_back("-fapple-kext"); diff --git a/clang/test/Driver/aix-ld.c b/clang/test/Driver/aix-ld.c index eb2910db239ff..d5c595495976a 100644 --- a/clang/test/Driver/aix-ld.c +++ b/clang/test/Driver/aix-ld.c @@ -1096,3 +1096,27 @@ // CHECK-RELOCATABLE-NOT: "[[SYSROOT]]/usr/lib{{/|\\\\}}crti.o" // CHECK-RELOCATABLE-NOT: "-l{{.*}}" // CHECK-RELOCATABLE-NOT: "-L{{.*}}" + +// Check powerpc-ibm-aix7.1.0.0. -K is a passthrough linker option. +// RUN: %clang %s 2>&1 -### \ +// RUN: --target=powerpc-ibm-aix7.1.0.0 \ +// RUN: --sysroot %S/Inputs/aix_ppc_tree \ +// RUN: --unwindlib=libunwind \ +// RUN: -K \ +// RUN: | FileCheck --check-prefixes=CHECK-K %s +// CHECK-K: "-cc1" "-triple" "powerpc-ibm-aix7.1.0.0" +// CHECK-K: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-K: "{{.*}}ld{{(.exe)?}}" +// CHECK-K: "[[SYSROOT]]/usr/lib{{/|\\\\}}crt0.o" +// CHECK-K: "[[SYSROOT]]/usr/lib{{/|\\\\}}crti.o" +// CHECK-K: "-K" + +// Check powerpc-ibm-aix7.1.0.0. -K unused when not linking. +// RUN: %clang %s 2>&1 -### \ +// RUN: --target=powerpc-ibm-aix7.1.0.0 \ +// RUN: --sysroot %S/Inputs/aix_ppc_tree \ +// RUN: --unwindlib=libunwind \ +// RUN: -K \ +// RUN: -c \ +// RUN: | FileCheck --check-prefixes=CHECK-K-UNUSED %s +// CHECK-K-UNUSED: clang: warning: -K: 'linker' input unused [-Wunused-command-line-argument] diff --git a/clang/test/Driver/unsupported-target-K.c b/clang/test/Driver/unsupported-target-K.c new file mode 100644 index 0000000000000..8b9a6f529c326 --- /dev/null +++ b/clang/test/Driver/unsupported-target-K.c @@ -0,0 +1,8 @@ +// Check powerpc64-unknown-linux-gnu. -K not supported. +// RUN: %clang %s 2>&1 -### \ +// RUN: --target=powerpc64-unknown-linux-gnu \ +// RUN: --sysroot %S/Inputs/aix_ppc_tree \ +// RUN: --unwindlib=libunwind \ +// RUN: -K \ +// RUN: | FileCheck --check-prefixes=CHECK-K-SUPPORT %s +// CHECK-K-SUPPORT: clang: error: unsupported option '-K' for target 'powerpc64-unknown-linux-gnu' From a88cee1fd06dd633fc6551d242c55f4235d4862d Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Fri, 21 Apr 2023 10:03:17 -0700 Subject: [PATCH 009/608] [flang] Semantics for ISO_C_BINDING's C_LOC() Make __builtin_c_loc() into an intrinsic function and verify the special semantic requirements on its actual arguments. Differential Revision: https://reviews.llvm.org/D149988 --- flang/include/flang/Evaluate/type.h | 3 +- flang/lib/Evaluate/characteristics.cpp | 8 +- flang/lib/Evaluate/check-expression.cpp | 19 +++- flang/lib/Evaluate/intrinsics.cpp | 99 +++++++++++++++---- flang/lib/Evaluate/tools.cpp | 6 +- flang/lib/Evaluate/type.cpp | 8 +- flang/lib/Semantics/expression.cpp | 4 +- flang/module/__fortran_builtins.f90 | 3 +- .../HLFIR/intrinsic-module-procedures.f90 | 2 +- flang/test/Semantics/c_loc01.f90 | 37 +++++++ 10 files changed, 156 insertions(+), 33 deletions(-) create mode 100644 flang/test/Semantics/c_loc01.f90 diff --git a/flang/include/flang/Evaluate/type.h b/flang/include/flang/Evaluate/type.h index 4b13a3155ab00..2183b0dad5d1a 100644 --- a/flang/include/flang/Evaluate/type.h +++ b/flang/include/flang/Evaluate/type.h @@ -472,7 +472,8 @@ int SelectedCharKind(const std::string &, int defaultKind); std::optional ComparisonType( const DynamicType &, const DynamicType &); -bool IsInteroperableIntrinsicType(const DynamicType &); +bool IsInteroperableIntrinsicType( + const DynamicType &, bool checkCharLength = true); // Determine whether two derived type specs are sufficiently identical // to be considered the "same" type even if declared separately. diff --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp index b8cb822866dbf..62b1573010f95 100644 --- a/flang/lib/Evaluate/characteristics.cpp +++ b/flang/lib/Evaluate/characteristics.cpp @@ -149,7 +149,13 @@ std::optional TypeAndShape::Characterize( std::optional TypeAndShape::Characterize( const ActualArgument &arg, FoldingContext &context) { - return Characterize(arg.UnwrapExpr(), context); + if (const auto *expr{arg.UnwrapExpr()}) { + return Characterize(*expr, context); + } else if (const Symbol * assumed{arg.GetAssumedTypeDummy()}) { + return Characterize(*assumed, context); + } else { + return std::nullopt; + } } bool TypeAndShape::IsCompatibleWith(parser::ContextualMessages &messages, diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp index d307af6a9e14c..206e9578a28b8 100644 --- a/flang/lib/Evaluate/check-expression.cpp +++ b/flang/lib/Evaluate/check-expression.cpp @@ -819,10 +819,21 @@ class IsContiguousHelper characteristics::Procedure::Characterize(x.proc(), context_)}) { if (chars->functionResult) { const auto &result{*chars->functionResult}; - return !result.IsProcedurePointer() && - result.attrs.test(characteristics::FunctionResult::Attr::Pointer) && - result.attrs.test( - characteristics::FunctionResult::Attr::Contiguous); + if (!result.IsProcedurePointer()) { + if (result.attrs.test( + characteristics::FunctionResult::Attr::Contiguous)) { + return true; + } + if (!result.attrs.test( + characteristics::FunctionResult::Attr::Pointer)) { + return true; + } + if (const auto *type{result.GetTypeAndShape()}; + type && type->Rank() == 0) { + return true; // pointer to scalar + } + // Must be non-CONTIGUOUS pointer to array + } } } return std::nullopt; diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp index 649d46886e98d..7b7ce78e9cbe8 100644 --- a/flang/lib/Evaluate/intrinsics.cpp +++ b/flang/lib/Evaluate/intrinsics.cpp @@ -2410,6 +2410,8 @@ class IntrinsicProcTable::Implementation { SpecificCall HandleNull(ActualArguments &, FoldingContext &) const; std::optional HandleC_F_Pointer( ActualArguments &, FoldingContext &) const; + std::optional HandleC_Loc( + ActualArguments &, FoldingContext &) const; const std::string &ResolveAlias(const std::string &name) const { auto iter{aliases_.find(name)}; return iter == aliases_.end() ? name : iter->second; @@ -2435,7 +2437,7 @@ bool IntrinsicProcTable::Implementation::IsIntrinsicFunction( return true; } // special cases - return name == "null"; + return name == "__builtin_c_loc" || name == "null"; } bool IntrinsicProcTable::Implementation::IsIntrinsicSubroutine( const std::string &name) const { @@ -2691,6 +2693,78 @@ IntrinsicProcTable::Implementation::HandleC_F_Pointer( } } +static bool CheckForCoindexedObject(FoldingContext &context, + const std::optional &arg, const std::string &procName, + const std::string &argName) { + bool ok{true}; + if (arg) { + if (ExtractCoarrayRef(arg->UnwrapExpr())) { + ok = false; + context.messages().Say(arg->sourceLocation(), + "'%s' argument to '%s' may not be a coindexed object"_err_en_US, + argName, procName); + } + } + return ok; +} + +// Function C_LOC(X) from intrinsic module ISO_C_BINDING (18.2.3.6) +std::optional IntrinsicProcTable::Implementation::HandleC_Loc( + ActualArguments &arguments, FoldingContext &context) const { + static const char *const keywords[]{"x", nullptr}; + if (CheckAndRearrangeArguments(arguments, context.messages(), keywords)) { + CHECK(arguments.size() == 1); + CheckForCoindexedObject(context, arguments[0], "c_loc", "x"); + const auto *expr{arguments[0].value().UnwrapExpr()}; + if (expr && + !(IsObjectPointer(*expr, context) || + (IsVariable(*expr) && GetLastTarget(GetSymbolVector(*expr))))) { + context.messages().Say(arguments[0]->sourceLocation(), + "C_LOC() argument must be a data pointer or target"_err_en_US); + } + if (auto typeAndShape{characteristics::TypeAndShape::Characterize( + arguments[0], context)}) { + if (expr && !IsContiguous(*expr, context).value_or(true)) { + context.messages().Say(arguments[0]->sourceLocation(), + "C_LOC() argument must be contiguous"_err_en_US); + } + if (auto constExtents{AsConstantExtents(context, typeAndShape->shape())}; + constExtents && GetSize(*constExtents) == 0) { + context.messages().Say(arguments[0]->sourceLocation(), + "C_LOC() argument may not be a zero-sized array"_err_en_US); + } + if (!(typeAndShape->type().category() != TypeCategory::Derived || + typeAndShape->type().IsAssumedType() || + (!typeAndShape->type().IsPolymorphic() && + CountNonConstantLenParameters( + typeAndShape->type().GetDerivedTypeSpec()) == 0))) { + context.messages().Say(arguments[0]->sourceLocation(), + "C_LOC() argument must have an intrinsic type, assumed type, or non-polymorphic derived type with no non-constant length parameter"_err_en_US); + } else if (typeAndShape->type().knownLength().value_or(1) == 0) { + context.messages().Say(arguments[0]->sourceLocation(), + "C_LOC() argument may not be zero-length character"_err_en_US); + } else if (typeAndShape->type().category() != TypeCategory::Derived && + !IsInteroperableIntrinsicType(typeAndShape->type())) { + context.messages().Say(arguments[0]->sourceLocation(), + "C_LOC() argument has non-interoperable intrinsic type, kind, or length"_warn_en_US); + } + + return SpecificCall{SpecificIntrinsic{"__builtin_c_loc"s, + characteristics::Procedure{ + characteristics::FunctionResult{ + DynamicType{GetBuiltinDerivedType( + builtinsScope_, "__builtin_c_ptr")}}, + characteristics::DummyArguments{ + characteristics::DummyArgument{"x"s, + characteristics::DummyDataObject{ + std::move(*typeAndShape)}}}, + characteristics::Procedure::Attrs{}}}, + std::move(arguments)}; + } + } + return std::nullopt; +} + static bool CheckForNonPositiveValues(FoldingContext &context, const ActualArgument &arg, const std::string &procName, const std::string &argName) { @@ -2751,21 +2825,6 @@ static bool CheckDimAgainstCorank(SpecificCall &call, FoldingContext &context) { return ok; } -static bool CheckForCoindexedObject(FoldingContext &context, - const std::optional &arg, const std::string &procName, - const std::string &argName) { - bool ok{true}; - if (arg) { - if (ExtractCoarrayRef(arg->UnwrapExpr())) { - ok = false; - context.messages().Say(arg->sourceLocation(), - "'%s' argument to '%s' may not be a coindexed object"_err_en_US, - argName, procName); - } - } - return ok; -} - static bool CheckAtomicDefineAndRef(FoldingContext &context, const std::optional &atomArg, const std::optional &valueArg, @@ -3013,8 +3072,12 @@ std::optional IntrinsicProcTable::Implementation::Probe( "RANDOM_SEED must have either 1 or no arguments"_err_en_US); } } - } else if (call.name == "null") { - return HandleNull(arguments, context); + } else { // function + if (call.name == "__builtin_c_loc") { + return HandleC_Loc(arguments, context); + } else if (call.name == "null") { + return HandleNull(arguments, context); + } } if (call.isSubroutineCall) { diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp index 5d7129b32fc0b..b9fb511b47cba 100644 --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -1555,9 +1555,11 @@ bool IsBuiltinDerivedType(const DerivedTypeSpec *derived, const char *name) { } bool IsBuiltinCPtr(const Symbol &symbol) { - if (const DeclTypeSpec *declType = symbol.GetType()) - if (const DerivedTypeSpec *derived = declType->AsDerived()) + if (const DeclTypeSpec *declType = symbol.GetType()) { + if (const DerivedTypeSpec *derived = declType->AsDerived()) { return IsIsoCType(derived); + } + } return false; } diff --git a/flang/lib/Evaluate/type.cpp b/flang/lib/Evaluate/type.cpp index 83a4ee5c45887..0b9292a18d3fa 100644 --- a/flang/lib/Evaluate/type.cpp +++ b/flang/lib/Evaluate/type.cpp @@ -734,7 +734,8 @@ std::optional ComparisonType( } } -bool IsInteroperableIntrinsicType(const DynamicType &type) { +bool IsInteroperableIntrinsicType( + const DynamicType &type, bool checkCharLength) { switch (type.category()) { case TypeCategory::Integer: return true; @@ -744,7 +745,10 @@ bool IsInteroperableIntrinsicType(const DynamicType &type) { case TypeCategory::Logical: return type.kind() == 1; // C_BOOL case TypeCategory::Character: - return type.kind() == 1 /* C_CHAR */ && type.knownLength().value_or(0) == 1; + if (checkCharLength && type.knownLength().value_or(0) != 1) { + return false; + } + return type.kind() == 1 /* C_CHAR */; default: // Derived types are tested in Semantics/check-declarations.cpp return false; diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 5ec83344d03d0..1440147feecdf 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -216,7 +216,7 @@ MaybeExpr ExpressionAnalyzer::Designate(DataRef &&ref) { DIE("unexpected alternative in DataRef"); } else if (!symbol.attrs().test(semantics::Attr::INTRINSIC)) { if (symbol.has()) { - Say("'%s' is not a specific procedure"_err_en_US, symbol.name()); + Say("'%s' is not a specific procedure"_err_en_US, last.name()); } else { return Expr{ProcedureDesignator{symbol}}; } @@ -229,7 +229,7 @@ MaybeExpr ExpressionAnalyzer::Designate(DataRef &&ref) { return Expr{ProcedureDesignator{std::move(intrinsic)}}; } else { Say("'%s' is not an unrestricted specific intrinsic procedure"_err_en_US, - symbol.name()); + last.name()); } return std::nullopt; } else if (MaybeExpr result{AsGenericExpr(std::move(ref))}) { diff --git a/flang/module/__fortran_builtins.f90 b/flang/module/__fortran_builtins.f90 index a22aa4699f7ad..1dee77e3c10cf 100644 --- a/flang/module/__fortran_builtins.f90 +++ b/flang/module/__fortran_builtins.f90 @@ -12,6 +12,7 @@ ! standard names of the procedures. module __Fortran_builtins + intrinsic :: __builtin_c_loc intrinsic :: __builtin_c_f_pointer intrinsic :: sizeof ! extension @@ -42,8 +43,6 @@ integer, parameter :: __builtin_atomic_int_kind = selected_int_kind(18) integer, parameter :: __builtin_atomic_logical_kind = __builtin_atomic_int_kind - procedure(type(__builtin_c_ptr)) :: __builtin_c_loc - intrinsic :: __builtin_ieee_is_nan, __builtin_ieee_is_negative, & __builtin_ieee_is_normal intrinsic :: __builtin_ieee_next_after, __builtin_ieee_next_down, & diff --git a/flang/test/Lower/HLFIR/intrinsic-module-procedures.f90 b/flang/test/Lower/HLFIR/intrinsic-module-procedures.f90 index 40bb39e967265..7a124e2886510 100644 --- a/flang/test/Lower/HLFIR/intrinsic-module-procedures.f90 +++ b/flang/test/Lower/HLFIR/intrinsic-module-procedures.f90 @@ -8,7 +8,7 @@ subroutine foo(cptr, x) use iso_c_binding, only : c_ptr, c_loc type(c_ptr) :: cptr - integer :: x + integer, target :: x cptr = c_loc(x) end subroutine ! CHECK-LABEL: func.func @_QPfoo( diff --git a/flang/test/Semantics/c_loc01.f90 b/flang/test/Semantics/c_loc01.f90 new file mode 100644 index 0000000000000..02f32e3801d91 --- /dev/null +++ b/flang/test/Semantics/c_loc01.f90 @@ -0,0 +1,37 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +module m + use iso_c_binding + type haslen(L) + integer, len :: L + end type + contains + subroutine test(assumedType, poly, nclen) + type(*), target :: assumedType + class(*), target :: poly + type(c_ptr) cp + real notATarget + procedure(sin), pointer :: pptr + real, target :: arr(3) + type(hasLen(1)), target :: clen + type(hasLen(*)), target :: nclen + character(2), target :: ch + !ERROR: C_LOC() argument must be a data pointer or target + cp = c_loc(notATarget) + !ERROR: C_LOC() argument must be a data pointer or target + cp = c_loc(pptr) + !ERROR: C_LOC() argument must be contiguous + cp = c_loc(arr(1:3:2)) + !ERROR: C_LOC() argument may not be a zero-sized array + cp = c_loc(arr(3:1)) + !ERROR: C_LOC() argument must have an intrinsic type, assumed type, or non-polymorphic derived type with no non-constant length parameter + cp = c_loc(poly) + cp = c_loc(clen) ! ok + !ERROR: C_LOC() argument must have an intrinsic type, assumed type, or non-polymorphic derived type with no non-constant length parameter + cp = c_loc(nclen) + !ERROR: C_LOC() argument may not be zero-length character + cp = c_loc(ch(2:1)) + !WARNING: C_LOC() argument has non-interoperable intrinsic type, kind, or length + cp = c_loc(ch) + cp = c_loc(ch(1:1)) ! ok) + end +end module From 281195a22f07e5afe90ac4b4cbe4b79ecd961b68 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 8 May 2023 15:58:24 -0700 Subject: [PATCH 010/608] [NFC][sanitizer] Rename internal function --- compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp | 2 +- compiler-rt/lib/sanitizer_common/sanitizer_posix.h | 2 +- compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index 37b2b57c0c844..42013f4718705 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -148,7 +148,7 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, pthread_attr_t attr; pthread_attr_init(&attr); CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0); - my_pthread_attr_getstack(&attr, &stackaddr, &stacksize); + internal_pthread_attr_getstack(&attr, &stackaddr, &stacksize); pthread_attr_destroy(&attr); #endif // SANITIZER_SOLARIS diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h index f91e26e74b87c..76b4174e927e8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h @@ -90,7 +90,7 @@ int real_pthread_join(void *th, void **ret); } \ } // namespace __sanitizer -int my_pthread_attr_getstack(void *attr, void **addr, uptr *size); +int internal_pthread_attr_getstack(void *attr, void **addr, uptr *size); // A routine named real_sigaction() must be implemented by each sanitizer in // order for internal_sigaction() to bypass interceptors. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp index 46e41c669738c..e88e654eec5a1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -383,7 +383,7 @@ SANITIZER_WEAK_ATTRIBUTE int real_pthread_attr_getstack(void *attr, void **addr, size_t *size); } // extern "C" -int my_pthread_attr_getstack(void *attr, void **addr, uptr *size) { +int internal_pthread_attr_getstack(void *attr, void **addr, uptr *size) { #if !SANITIZER_GO && !SANITIZER_APPLE if (&real_pthread_attr_getstack) return real_pthread_attr_getstack((pthread_attr_t *)attr, addr, @@ -397,7 +397,7 @@ void AdjustStackSize(void *attr_) { pthread_attr_t *attr = (pthread_attr_t *)attr_; uptr stackaddr = 0; uptr stacksize = 0; - my_pthread_attr_getstack(attr, (void**)&stackaddr, &stacksize); + internal_pthread_attr_getstack(attr, (void **)&stackaddr, &stacksize); // GLibC will return (0 - stacksize) as the stack address in the case when // stacksize is set, but stackaddr is not. bool stack_set = (stackaddr != 0) && (stackaddr + stacksize != 0); From 16a76397abb32e852a163a7c709682f0f88c2b1d Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 8 May 2023 15:32:55 -0700 Subject: [PATCH 011/608] [NFC][HWASAN] Hide thread_list_placeholder --- compiler-rt/lib/hwasan/hwasan_thread_list.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler-rt/lib/hwasan/hwasan_thread_list.cpp b/compiler-rt/lib/hwasan/hwasan_thread_list.cpp index d528f520cc9eb..1ae3664f28273 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread_list.cpp +++ b/compiler-rt/lib/hwasan/hwasan_thread_list.cpp @@ -1,13 +1,16 @@ #include "hwasan_thread_list.h" namespace __hwasan { -static ALIGNED(16) char thread_list_placeholder[sizeof(HwasanThreadList)]; + static HwasanThreadList *hwasan_thread_list; HwasanThreadList &hwasanThreadList() { return *hwasan_thread_list; } void InitThreadList(uptr storage, uptr size) { CHECK_EQ(hwasan_thread_list, nullptr); + + static ALIGNED(alignof( + HwasanThreadList)) char thread_list_placeholder[sizeof(HwasanThreadList)]; hwasan_thread_list = new (thread_list_placeholder) HwasanThreadList(storage, size); } From cc1ed07dc459fb3ed523ccf4ddf0ef074450b12e Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 8 May 2023 15:03:22 -0700 Subject: [PATCH 012/608] [NFC][HWASAN] Reformat the file --- .../lib/hwasan/hwasan_interceptors.cpp | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp index d5866b8b94b05..f07c24e34a087 100644 --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp @@ -25,7 +25,7 @@ using namespace __hwasan; -#if HWASAN_WITH_INTERCEPTORS +# if HWASAN_WITH_INTERCEPTORS struct ThreadStartArg { thread_callback_t callback; @@ -35,7 +35,7 @@ struct ThreadStartArg { static void *HwasanThreadStartFunc(void *arg) { __hwasan_thread_enter(); - ThreadStartArg A = *reinterpret_cast(arg); + ThreadStartArg A = *reinterpret_cast(arg); SetSigProcMask(&A.starting_sigset_, nullptr); UnmapOrDie(arg, GetPageSizeCached()); return A.callback(A.param); @@ -57,12 +57,12 @@ static void *HwasanThreadStartFunc(void *arg) { # include "sanitizer_common/sanitizer_common_syscalls.inc" # include "sanitizer_common/sanitizer_syscalls_netbsd.inc" -INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), - void * param) { +INTERCEPTOR(int, pthread_create, void *th, void *attr, + void *(*callback)(void *), void *param) { EnsureMainThreadIDIsCorrect(); ScopedTaggingDisabler tagging_disabler; - ThreadStartArg *A = reinterpret_cast (MmapOrDie( - GetPageSizeCached(), "pthread_create")); + ThreadStartArg *A = reinterpret_cast( + MmapOrDie(GetPageSizeCached(), "pthread_create")); A->callback = callback; A->param = param; ScopedBlockSignals block(&A->starting_sigset_); @@ -104,13 +104,13 @@ DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork) // Get and/or change the set of blocked signals. extern "C" int sigprocmask(int __how, const __hw_sigset_t *__restrict __set, __hw_sigset_t *__restrict __oset); -#define SIG_BLOCK 0 -#define SIG_SETMASK 2 +# define SIG_BLOCK 0 +# define SIG_SETMASK 2 extern "C" int __sigjmp_save(__hw_sigjmp_buf env, int savemask) { env[0].__magic = kHwJmpBufMagic; env[0].__mask_was_saved = - (savemask && sigprocmask(SIG_BLOCK, (__hw_sigset_t *)0, - &env[0].__saved_mask) == 0); + (savemask && + sigprocmask(SIG_BLOCK, (__hw_sigset_t *)0, &env[0].__saved_mask) == 0); return 0; } @@ -139,26 +139,27 @@ InternalLongjmp(__hw_register_buf env, int retval) { # if defined(__aarch64__) register long int retval_tmp asm("x1") = retval; register void *env_address asm("x0") = &env[0]; - asm volatile("ldp x19, x20, [%0, #0<<3];" - "ldp x21, x22, [%0, #2<<3];" - "ldp x23, x24, [%0, #4<<3];" - "ldp x25, x26, [%0, #6<<3];" - "ldp x27, x28, [%0, #8<<3];" - "ldp x29, x30, [%0, #10<<3];" - "ldp d8, d9, [%0, #14<<3];" - "ldp d10, d11, [%0, #16<<3];" - "ldp d12, d13, [%0, #18<<3];" - "ldp d14, d15, [%0, #20<<3];" - "ldr x5, [%0, #13<<3];" - "mov sp, x5;" - // Return the value requested to return through arguments. - // This should be in x1 given what we requested above. - "cmp %1, #0;" - "mov x0, #1;" - "csel x0, %1, x0, ne;" - "br x30;" - : "+r"(env_address) - : "r"(retval_tmp)); + asm volatile( + "ldp x19, x20, [%0, #0<<3];" + "ldp x21, x22, [%0, #2<<3];" + "ldp x23, x24, [%0, #4<<3];" + "ldp x25, x26, [%0, #6<<3];" + "ldp x27, x28, [%0, #8<<3];" + "ldp x29, x30, [%0, #10<<3];" + "ldp d8, d9, [%0, #14<<3];" + "ldp d10, d11, [%0, #16<<3];" + "ldp d12, d13, [%0, #18<<3];" + "ldp d14, d15, [%0, #20<<3];" + "ldr x5, [%0, #13<<3];" + "mov sp, x5;" + // Return the value requested to return through arguments. + // This should be in x1 given what we requested above. + "cmp %1, #0;" + "mov x0, #1;" + "csel x0, %1, x0, ne;" + "br x30;" + : "+r"(env_address) + : "r"(retval_tmp)); # elif defined(__x86_64__) register long int retval_tmp asm("%rsi") = retval; register void *env_address asm("%rdi") = &env[0]; @@ -234,8 +235,7 @@ INTERCEPTOR(void, siglongjmp, __hw_sigjmp_buf env, int val) { if (env[0].__mask_was_saved) // Restore the saved signal mask. - (void)sigprocmask(SIG_SETMASK, &env[0].__saved_mask, - (__hw_sigset_t *)0); + (void)sigprocmask(SIG_SETMASK, &env[0].__saved_mask, (__hw_sigset_t *)0); InternalLongjmp(env[0].__jmpbuf, val); } @@ -257,8 +257,8 @@ INTERCEPTOR(void, longjmp, __hw_jmp_buf env, int val) { } InternalLongjmp(env[0].__jmpbuf, val); } -#undef SIG_BLOCK -#undef SIG_SETMASK +# undef SIG_BLOCK +# undef SIG_SETMASK # endif // HWASAN_WITH_INTERCEPTORS @@ -273,7 +273,7 @@ int OnExit() { return 0; } -} // namespace __hwasan +} // namespace __hwasan namespace __hwasan { @@ -300,6 +300,6 @@ void InitializeInterceptors() { inited = 1; } -} // namespace __hwasan +} // namespace __hwasan #endif // #if !SANITIZER_FUCHSIA From 82ddf1b8ec6c2e7ab81a8ca6f078a878e1688b0e Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 8 May 2023 15:15:15 -0700 Subject: [PATCH 013/608] [NFC][HWASAN] Move HwasanThreadStartFunc --- .../lib/hwasan/hwasan_interceptors.cpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp index f07c24e34a087..3854ad62f41a2 100644 --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp @@ -27,20 +27,6 @@ using namespace __hwasan; # if HWASAN_WITH_INTERCEPTORS -struct ThreadStartArg { - thread_callback_t callback; - void *param; - __sanitizer_sigset_t starting_sigset_; -}; - -static void *HwasanThreadStartFunc(void *arg) { - __hwasan_thread_enter(); - ThreadStartArg A = *reinterpret_cast(arg); - SetSigProcMask(&A.starting_sigset_, nullptr); - UnmapOrDie(arg, GetPageSizeCached()); - return A.callback(A.param); -} - # define COMMON_SYSCALL_PRE_READ_RANGE(p, s) __hwasan_loadN((uptr)p, (uptr)s) # define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \ __hwasan_storeN((uptr)p, (uptr)s) @@ -57,6 +43,20 @@ static void *HwasanThreadStartFunc(void *arg) { # include "sanitizer_common/sanitizer_common_syscalls.inc" # include "sanitizer_common/sanitizer_syscalls_netbsd.inc" +struct ThreadStartArg { + thread_callback_t callback; + void *param; + __sanitizer_sigset_t starting_sigset_; +}; + +static void *HwasanThreadStartFunc(void *arg) { + __hwasan_thread_enter(); + ThreadStartArg A = *reinterpret_cast(arg); + SetSigProcMask(&A.starting_sigset_, nullptr); + UnmapOrDie(arg, GetPageSizeCached()); + return A.callback(A.param); +} + INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void *), void *param) { EnsureMainThreadIDIsCorrect(); From f4999d3535af93919d58e3cc56ccb50f2ccb8453 Mon Sep 17 00:00:00 2001 From: Alan Zhao Date: Mon, 8 May 2023 16:26:32 -0700 Subject: [PATCH 014/608] Revert "[CodeGen][ShrinkWrap] Split restore point" This reverts commit 1ddfd1c8186735c62b642df05c505dc4907ffac4. The original commit causes a Chrome build assertion failure with ThinLTO: https://crbug.com/1443635 --- llvm/lib/CodeGen/ShrinkWrap.cpp | 396 +-------- .../AArch64/aarch64-matrix-umull-smull.ll | 4 +- .../dont-shrink-wrap-stack-mayloadorstore.mir | 4 +- llvm/test/CodeGen/AArch64/ragreedy-csr.ll | 18 +- .../shrinkwrap-split-restore-point.mir | 760 ------------------ llvm/test/CodeGen/AArch64/taildup-cfi.ll | 2 +- .../ARM/ParallelDSP/multi-use-loads.ll | 88 +- llvm/test/CodeGen/ARM/code-placement.ll | 1 + llvm/test/CodeGen/ARM/mbp.ll | 51 +- llvm/test/CodeGen/ARM/ssat-unroll-loops.ll | 26 +- .../CodeGen/PowerPC/common-chain-aix32.ll | 18 +- llvm/test/CodeGen/PowerPC/common-chain.ll | 27 +- .../PowerPC/loop-instr-form-prepare.ll | 49 +- .../CodeGen/PowerPC/lsr-profitable-chain.ll | 22 +- llvm/test/CodeGen/PowerPC/shrink-wrap.ll | 50 +- llvm/test/CodeGen/PowerPC/shrink-wrap.mir | 43 +- llvm/test/CodeGen/RISCV/aext-to-sext.ll | 7 +- llvm/test/CodeGen/RISCV/fli-licm.ll | 14 +- .../Thumb2/LowOverheadLoops/inlineasm.ll | 26 +- .../Thumb2/LowOverheadLoops/memcall.ll | 35 +- .../LowOverheadLoops/mve-float-loops.ll | 48 +- .../Thumb2/LowOverheadLoops/reductions.ll | 16 +- .../Thumb2/LowOverheadLoops/sibling-loops.ll | 12 +- .../Thumb2/LowOverheadLoops/spillingmove.ll | 58 +- .../Thumb2/LowOverheadLoops/while-loops.ll | 11 +- .../CodeGen/Thumb2/mve-float32regloops.ll | 19 +- .../CodeGen/Thumb2/mve-gather-increment.ll | 34 +- .../CodeGen/Thumb2/mve-gather-tailpred.ll | 11 +- llvm/test/CodeGen/Thumb2/mve-memtp-loop.ll | 22 +- llvm/test/CodeGen/Thumb2/mve-postinc-dct.ll | 14 +- .../CodeGen/Thumb2/mve-scatter-increment.ll | 12 +- .../Thumb2/mve-tailpred-nonzerostart.ll | 12 +- llvm/test/CodeGen/Thumb2/mve-vmull-loop.ll | 15 +- llvm/test/CodeGen/X86/fold-call-3.ll | 18 +- .../X86/negative-stride-fptosi-user.ll | 10 +- llvm/test/CodeGen/X86/pr44412.ll | 14 +- llvm/test/CodeGen/X86/x86-shrink-wrapping.ll | 24 +- .../LoopStrengthReduce/AArch64/pr53625.ll | 6 +- .../LoopStrengthReduce/X86/ivchain-X86.ll | 7 +- 39 files changed, 419 insertions(+), 1585 deletions(-) delete mode 100644 llvm/test/CodeGen/AArch64/shrinkwrap-split-restore-point.mir diff --git a/llvm/lib/CodeGen/ShrinkWrap.cpp b/llvm/lib/CodeGen/ShrinkWrap.cpp index 90cba95b7f199..b219b83bbc2fe 100644 --- a/llvm/lib/CodeGen/ShrinkWrap.cpp +++ b/llvm/lib/CodeGen/ShrinkWrap.cpp @@ -98,9 +98,6 @@ STATISTIC(NumCandidatesDropped, static cl::opt EnableShrinkWrapOpt("enable-shrink-wrap", cl::Hidden, cl::desc("enable the shrink-wrapping pass")); -static cl::opt EnablePostShrinkWrapOpt( - "enable-shrink-wrap-region-split", cl::init(true), cl::Hidden, - cl::desc("enable splitting of the restore block if possible")); namespace { @@ -188,30 +185,6 @@ class ShrinkWrap : public MachineFunctionPass { /// this call. void updateSaveRestorePoints(MachineBasicBlock &MBB, RegScavenger *RS); - // Try to find safe point based on dominance and block frequency without - // any change in IR. - bool performShrinkWrapping(MachineFunction &MF, RegScavenger *RS); - - /// This function tries to split the restore point if doing so can shrink the - /// save point further. \return True if restore point is split. - bool postShrinkWrapping(bool HasCandidate, MachineFunction &MF, - RegScavenger *RS); - - /// This function analyzes if the restore point can split to create a new - /// restore point. This function collects - /// 1. Any preds of current restore that are reachable by callee save/FI - /// blocks - /// - indicated by DirtyPreds - /// 2. Any preds of current restore that are not DirtyPreds - indicated by - /// CleanPreds - /// Both sets should be non-empty for considering restore point split. - bool checkIfRestoreSplittable( - const MachineBasicBlock *CurRestore, - const DenseSet &ReachableByDirty, - SmallVectorImpl &DirtyPreds, - SmallVectorImpl &CleanPreds, - const TargetInstrInfo *TII, RegScavenger *RS); - /// Initialize the pass for \p MF. void init(MachineFunction &MF) { RCI.runOnMachineFunction(MF); @@ -365,311 +338,18 @@ bool ShrinkWrap::useOrDefCSROrFI(const MachineInstr &MI, /// Helper function to find the immediate (post) dominator. template static MachineBasicBlock *FindIDom(MachineBasicBlock &Block, ListOfBBs BBs, - DominanceAnalysis &Dom, bool Strict = true) { + DominanceAnalysis &Dom) { MachineBasicBlock *IDom = &Block; for (MachineBasicBlock *BB : BBs) { IDom = Dom.findNearestCommonDominator(IDom, BB); if (!IDom) break; } - if (Strict && IDom == &Block) + if (IDom == &Block) return nullptr; return IDom; } -static bool isAnalyzableBB(const TargetInstrInfo &TII, - MachineBasicBlock &Entry) { - // Check if the block is analyzable. - MachineBasicBlock *TBB = nullptr, *FBB = nullptr; - SmallVector Cond; - return !TII.analyzeBranch(Entry, TBB, FBB, Cond); -} - -/// Determines if any predecessor of MBB is on the path from block that has use -/// or def of CSRs/FI to MBB. -/// ReachableByDirty: All blocks reachable from block that has use or def of -/// CSR/FI. -static bool -hasDirtyPred(const DenseSet &ReachableByDirty, - const MachineBasicBlock &MBB) { - for (const MachineBasicBlock *PredBB : MBB.predecessors()) - if (ReachableByDirty.count(PredBB)) - return true; - return false; -} - -/// Derives the list of all the basic blocks reachable from MBB. -static void markAllReachable(DenseSet &Visited, - const MachineBasicBlock &MBB) { - SmallVector Worklist(MBB.succ_begin(), - MBB.succ_end()); - Visited.insert(&MBB); - while (!Worklist.empty()) { - MachineBasicBlock *SuccMBB = Worklist.pop_back_val(); - if (!Visited.insert(SuccMBB).second) - continue; - Worklist.append(SuccMBB->succ_begin(), SuccMBB->succ_end()); - } -} - -/// Collect blocks reachable by use or def of CSRs/FI. -static void collectBlocksReachableByDirty( - const DenseSet &DirtyBBs, - DenseSet &ReachableByDirty) { - for (const MachineBasicBlock *MBB : DirtyBBs) { - if (ReachableByDirty.count(MBB)) - continue; - // Mark all offsprings as reachable. - markAllReachable(ReachableByDirty, *MBB); - } -} - -/// \return true if there is a clean path from SavePoint to the original -/// Restore. -static bool -isSaveReachableThroughClean(const MachineBasicBlock *SavePoint, - ArrayRef CleanPreds) { - DenseSet Visited; - SmallVector Worklist(CleanPreds.begin(), - CleanPreds.end()); - while (!Worklist.empty()) { - MachineBasicBlock *CleanBB = Worklist.pop_back_val(); - if (CleanBB == SavePoint) - return true; - if (!Visited.insert(CleanBB).second || !CleanBB->pred_size()) - continue; - Worklist.append(CleanBB->pred_begin(), CleanBB->pred_end()); - } - return false; -} - -/// This function updates the branches post restore point split. -/// -/// Restore point has been split. -/// Old restore point: MBB -/// New restore point: NMBB -/// Any basic block(say BBToUpdate) which had a fallthrough to MBB -/// previously should -/// 1. Fallthrough to NMBB iff NMBB is inserted immediately above MBB in the -/// block layout OR -/// 2. Branch unconditionally to NMBB iff NMBB is inserted at any other place. -static void updateTerminator(MachineBasicBlock *BBToUpdate, - MachineBasicBlock *NMBB, - const TargetInstrInfo *TII) { - DebugLoc DL = BBToUpdate->findBranchDebugLoc(); - // if NMBB isn't the new layout successor for BBToUpdate, insert unconditional - // branch to it - if (!BBToUpdate->isLayoutSuccessor(NMBB)) - TII->insertUnconditionalBranch(*BBToUpdate, NMBB, DL); -} - -/// This function splits the restore point and returns new restore point/BB. -/// -/// DirtyPreds: Predessors of \p MBB that are ReachableByDirty -/// -/// Decision has been made to split the restore point. -/// old restore point: \p MBB -/// new restore point: \p NMBB -/// This function makes the necessary block layout changes so that -/// 1. \p NMBB points to \p MBB unconditionally -/// 2. All dirtyPreds that previously pointed to \p MBB point to \p NMBB -static MachineBasicBlock * -tryToSplitRestore(MachineBasicBlock *MBB, - ArrayRef DirtyPreds, - const TargetInstrInfo *TII) { - MachineFunction *MF = MBB->getParent(); - - // get the list of DirtyPreds who have a fallthrough to MBB - // before the block layout change. This is just to ensure that if the NMBB is - // inserted after MBB, then we create unconditional branch from - // DirtyPred/CleanPred to NMBB - SmallPtrSet MBBFallthrough; - for (MachineBasicBlock *BB : DirtyPreds) - if (BB->getFallThrough(false) == MBB) - MBBFallthrough.insert(BB); - - MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(); - // Insert this block at the end of the function. Inserting in between may - // interfere with control flow optimizer decisions. - MF->insert(MF->end(), NMBB); - - for (const MachineBasicBlock::RegisterMaskPair &LI : MBB->liveins()) - NMBB->addLiveIn(LI.PhysReg); - - TII->insertUnconditionalBranch(*NMBB, MBB, DebugLoc()); - - // After splitting, all predecessors of the restore point should be dirty - // blocks. - for (MachineBasicBlock *SuccBB : DirtyPreds) - SuccBB->ReplaceUsesOfBlockWith(MBB, NMBB); - - NMBB->addSuccessor(MBB); - - for (MachineBasicBlock *BBToUpdate : MBBFallthrough) - updateTerminator(BBToUpdate, NMBB, TII); - - return NMBB; -} - -/// This function undoes the restore point split done earlier. -/// -/// DirtyPreds: All predecessors of \p NMBB that are ReachableByDirty. -/// -/// Restore point was split and the change needs to be unrolled. Make necessary -/// changes to reset restore point from \p NMBB to \p MBB. -static void rollbackRestoreSplit(MachineFunction &MF, MachineBasicBlock *NMBB, - MachineBasicBlock *MBB, - ArrayRef DirtyPreds, - const TargetInstrInfo *TII) { - // For a BB, if NMBB is fallthrough in the current layout, then in the new - // layout a. BB should fallthrough to MBB OR b. BB should undconditionally - // branch to MBB - SmallPtrSet NMBBFallthrough; - for (MachineBasicBlock *BB : DirtyPreds) - if (BB->getFallThrough(false) == NMBB) - NMBBFallthrough.insert(BB); - - NMBB->removeSuccessor(MBB); - for (MachineBasicBlock *SuccBB : DirtyPreds) - SuccBB->ReplaceUsesOfBlockWith(NMBB, MBB); - - NMBB->erase(NMBB->begin(), NMBB->end()); - NMBB->eraseFromParent(); - - for (MachineBasicBlock *BBToUpdate : NMBBFallthrough) - updateTerminator(BBToUpdate, MBB, TII); -} - -// A block is deemed fit for restore point split iff there exist -// 1. DirtyPreds - preds of CurRestore reachable from use or def of CSR/FI -// 2. CleanPreds - preds of CurRestore that arent DirtyPreds -bool ShrinkWrap::checkIfRestoreSplittable( - const MachineBasicBlock *CurRestore, - const DenseSet &ReachableByDirty, - SmallVectorImpl &DirtyPreds, - SmallVectorImpl &CleanPreds, - const TargetInstrInfo *TII, RegScavenger *RS) { - for (const MachineInstr &MI : *CurRestore) - if (useOrDefCSROrFI(MI, RS)) - return false; - - for (MachineBasicBlock *PredBB : CurRestore->predecessors()) { - if (!isAnalyzableBB(*TII, *PredBB)) - return false; - - if (ReachableByDirty.count(PredBB)) - DirtyPreds.push_back(PredBB); - else - CleanPreds.push_back(PredBB); - } - - return !(CleanPreds.empty() || DirtyPreds.empty()); -} - -bool ShrinkWrap::postShrinkWrapping(bool HasCandidate, MachineFunction &MF, - RegScavenger *RS) { - if (!EnablePostShrinkWrapOpt) - return false; - - MachineBasicBlock *InitSave = nullptr; - MachineBasicBlock *InitRestore = nullptr; - - if (HasCandidate) { - InitSave = Save; - InitRestore = Restore; - } else { - InitRestore = nullptr; - InitSave = &MF.front(); - for (MachineBasicBlock &MBB : MF) { - if (MBB.isEHFuncletEntry()) - return false; - if (MBB.isReturnBlock()) { - // Do not support multiple restore points. - if (InitRestore) - return false; - InitRestore = &MBB; - } - } - } - - if (!InitSave || !InitRestore || InitRestore == InitSave || - !MDT->dominates(InitSave, InitRestore) || - !MPDT->dominates(InitRestore, InitSave)) - return false; - - // Bail out of the optimization if any of the basic block is target of - // INLINEASM_BR instruction - for (MachineBasicBlock &MBB : MF) - if (MBB.isInlineAsmBrIndirectTarget()) - return false; - - DenseSet DirtyBBs; - for (MachineBasicBlock &MBB : MF) { - if (MBB.isEHPad()) { - DirtyBBs.insert(&MBB); - continue; - } - for (const MachineInstr &MI : MBB) - if (useOrDefCSROrFI(MI, RS)) { - DirtyBBs.insert(&MBB); - break; - } - } - - // Find blocks reachable from the use or def of CSRs/FI. - DenseSet ReachableByDirty; - collectBlocksReachableByDirty(DirtyBBs, ReachableByDirty); - - const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); - SmallVector DirtyPreds; - SmallVector CleanPreds; - if (!checkIfRestoreSplittable(InitRestore, ReachableByDirty, DirtyPreds, - CleanPreds, TII, RS)) - return false; - - // Trying to reach out to the new save point which dominates all dirty blocks. - MachineBasicBlock *NewSave = - FindIDom<>(**DirtyPreds.begin(), DirtyPreds, *MDT, false); - - while (NewSave && (hasDirtyPred(ReachableByDirty, *NewSave) || - EntryFreq < MBFI->getBlockFreq(NewSave).getFrequency())) - NewSave = FindIDom<>(**NewSave->pred_begin(), NewSave->predecessors(), *MDT, - false); - - const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); - if (!NewSave || NewSave == InitSave || - isSaveReachableThroughClean(NewSave, CleanPreds) || - !TFI->canUseAsPrologue(*NewSave)) - return false; - - // Now we know that splitting a restore point can isolate the restore point - // from clean blocks and doing so can shrink the save point. - MachineBasicBlock *NewRestore = - tryToSplitRestore(InitRestore, DirtyPreds, TII); - - // Make sure if the new restore point is valid as an epilogue, depending on - // targets. - if (!TFI->canUseAsEpilogue(*NewRestore)) { - rollbackRestoreSplit(MF, NewRestore, InitRestore, DirtyPreds, TII); - return false; - } - - Save = NewSave; - Restore = NewRestore; - - MDT->runOnMachineFunction(MF); - MPDT->runOnMachineFunction(MF); - - assert((MDT->dominates(Save, Restore) && MPDT->dominates(Restore, Save)) && - "Incorrect save or restore point due to dominance relations"); - assert((!MLI->getLoopFor(Save) && !MLI->getLoopFor(Restore)) && - "Unexpected save or restore point in a loop"); - assert((EntryFreq >= MBFI->getBlockFreq(Save).getFrequency() && - EntryFreq >= MBFI->getBlockFreq(Restore).getFrequency()) && - "Incorrect save or restore point based on block frequency"); - return true; -} - void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB, RegScavenger *RS) { // Get rid of the easy cases first. @@ -801,7 +481,31 @@ static bool giveUpWithRemarks(MachineOptimizationRemarkEmitter *ORE, return false; } -bool ShrinkWrap::performShrinkWrapping(MachineFunction &MF, RegScavenger *RS) { +bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) { + if (skipFunction(MF.getFunction()) || MF.empty() || !isShrinkWrapEnabled(MF)) + return false; + + LLVM_DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n'); + + init(MF); + + ReversePostOrderTraversal RPOT(&*MF.begin()); + if (containsIrreducibleCFG(RPOT, *MLI)) { + // If MF is irreducible, a block may be in a loop without + // MachineLoopInfo reporting it. I.e., we may use the + // post-dominance property in loops, which lead to incorrect + // results. Moreover, we may miss that the prologue and + // epilogue are not in the same loop, leading to unbalanced + // construction/deconstruction of the stack frame. + return giveUpWithRemarks(ORE, "UnsupportedIrreducibleCFG", + "Irreducible CFGs are not supported yet.", + MF.getFunction().getSubprogram(), &MF.front()); + } + + const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); + std::unique_ptr RS( + TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : nullptr); + for (MachineBasicBlock &MBB : MF) { LLVM_DEBUG(dbgs() << "Look into: " << MBB.getNumber() << ' ' << MBB.getName() << '\n'); @@ -817,7 +521,7 @@ bool ShrinkWrap::performShrinkWrapping(MachineFunction &MF, RegScavenger *RS) { // are at least at the boundary of the save and restore points. The // problem is that a basic block can jump out from the middle in these // cases, which we do not handle. - updateSaveRestorePoints(MBB, RS); + updateSaveRestorePoints(MBB, RS.get()); if (!ArePointsInteresting()) { LLVM_DEBUG(dbgs() << "EHPad/inlineasm_br prevents shrink-wrapping\n"); return false; @@ -826,11 +530,11 @@ bool ShrinkWrap::performShrinkWrapping(MachineFunction &MF, RegScavenger *RS) { } for (const MachineInstr &MI : MBB) { - if (!useOrDefCSROrFI(MI, RS)) + if (!useOrDefCSROrFI(MI, RS.get())) continue; // Save (resp. restore) point must dominate (resp. post dominate) // MI. Look for the proper basic block for those. - updateSaveRestorePoints(MBB, RS); + updateSaveRestorePoints(MBB, RS.get()); // If we are at a point where we cannot improve the placement of // save/restore instructions, just give up. if (!ArePointsInteresting()) { @@ -884,49 +588,13 @@ bool ShrinkWrap::performShrinkWrapping(MachineFunction &MF, RegScavenger *RS) { break; NewBB = Restore; } - updateSaveRestorePoints(*NewBB, RS); + updateSaveRestorePoints(*NewBB, RS.get()); } while (Save && Restore); if (!ArePointsInteresting()) { ++NumCandidatesDropped; return false; } - return true; -} - -bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) { - if (skipFunction(MF.getFunction()) || MF.empty() || !isShrinkWrapEnabled(MF)) - return false; - - LLVM_DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n'); - - init(MF); - - ReversePostOrderTraversal RPOT(&*MF.begin()); - if (containsIrreducibleCFG(RPOT, *MLI)) { - // If MF is irreducible, a block may be in a loop without - // MachineLoopInfo reporting it. I.e., we may use the - // post-dominance property in loops, which lead to incorrect - // results. Moreover, we may miss that the prologue and - // epilogue are not in the same loop, leading to unbalanced - // construction/deconstruction of the stack frame. - return giveUpWithRemarks(ORE, "UnsupportedIrreducibleCFG", - "Irreducible CFGs are not supported yet.", - MF.getFunction().getSubprogram(), &MF.front()); - } - - const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); - std::unique_ptr RS( - TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : nullptr); - - bool Changed = false; - - bool HasCandidate = performShrinkWrapping(MF, RS.get()); - Changed = postShrinkWrapping(HasCandidate, MF, RS.get()); - if (!HasCandidate && !Changed) - return false; - if (!ArePointsInteresting()) - return Changed; LLVM_DEBUG(dbgs() << "Final shrink wrap candidates:\nSave: " << Save->getNumber() << ' ' << Save->getName() @@ -937,7 +605,7 @@ bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) { MFI.setSavePoint(Save); MFI.setRestorePoint(Restore); ++NumCandidates; - return Changed; + return false; } bool ShrinkWrap::isShrinkWrapEnabled(const MachineFunction &MF) { diff --git a/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll b/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll index 8dd4da1ee4401..49a15528c041a 100644 --- a/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll +++ b/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll @@ -424,8 +424,8 @@ define i16 @red_mla_dup_ext_u8_s8_s16(i8* noalias nocapture noundef readonly %A, ; CHECK-NEXT: mov w8, wzr ; CHECK-NEXT: b .LBB5_7 ; CHECK-NEXT: .LBB5_3: -; CHECK-NEXT: mov w8, wzr -; CHECK-NEXT: b .LBB5_9 +; CHECK-NEXT: mov w0, wzr +; CHECK-NEXT: ret ; CHECK-NEXT: .LBB5_4: // %vector.ph ; CHECK-NEXT: and x11, x10, #0xfffffff0 ; CHECK-NEXT: add x8, x0, #8 diff --git a/llvm/test/CodeGen/AArch64/dont-shrink-wrap-stack-mayloadorstore.mir b/llvm/test/CodeGen/AArch64/dont-shrink-wrap-stack-mayloadorstore.mir index 34fafb750083c..bc60b7b571197 100644 --- a/llvm/test/CodeGen/AArch64/dont-shrink-wrap-stack-mayloadorstore.mir +++ b/llvm/test/CodeGen/AArch64/dont-shrink-wrap-stack-mayloadorstore.mir @@ -6,8 +6,8 @@ ; RUN: llc -x=mir -simplify-mir -run-pass=shrink-wrap -o - %s | FileCheck %s ; CHECK: name: compiler_pop_stack ; CHECK: frameInfo: - ; CHECK: savePoint: '%bb.1' - ; CHECK-NEXT: restorePoint: '%bb.7' + ; CHECK-NOT: savePoint: + ; CHECK-NOT: restorePoint: ; CHECK: stack: ; CHECK: name: f ; CHECK: frameInfo: diff --git a/llvm/test/CodeGen/AArch64/ragreedy-csr.ll b/llvm/test/CodeGen/AArch64/ragreedy-csr.ll index 99f01883dbfb1..98c95c38bbb6b 100644 --- a/llvm/test/CodeGen/AArch64/ragreedy-csr.ll +++ b/llvm/test/CodeGen/AArch64/ragreedy-csr.ll @@ -21,16 +21,16 @@ declare i32 @__maskrune(i32, i64) #7 define fastcc i32 @prune_match(ptr nocapture readonly %a, ptr nocapture readonly %b) #9 { ; CHECK-LABEL: prune_match: ; CHECK: ; %bb.0: ; %entry -; CHECK-NEXT: ldrh w8, [x0] -; CHECK-NEXT: ldrh w9, [x1] -; CHECK-NEXT: cmp w8, w9 -; CHECK-NEXT: b.ne LBB0_47 -; CHECK-NEXT: ; %bb.1: ; %if.end ; CHECK-NEXT: sub sp, sp, #64 ; CHECK-NEXT: .cfi_def_cfa_offset 64 ; CHECK-NEXT: stp x29, x30, [sp, #48] ; 16-byte Folded Spill ; CHECK-NEXT: .cfi_offset w30, -8 ; CHECK-NEXT: .cfi_offset w29, -16 +; CHECK-NEXT: ldrh w8, [x0] +; CHECK-NEXT: ldrh w9, [x1] +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: b.ne LBB0_42 +; CHECK-NEXT: ; %bb.1: ; %if.end ; CHECK-NEXT: Lloh0: ; CHECK-NEXT: adrp x14, __DefaultRuneLocale@GOTPAGE ; CHECK-NEXT: mov x9, xzr @@ -243,7 +243,7 @@ define fastcc i32 @prune_match(ptr nocapture readonly %a, ptr nocapture readonly ; CHECK-NEXT: b.eq LBB0_37 ; CHECK-NEXT: LBB0_42: ; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: LBB0_43: +; CHECK-NEXT: LBB0_43: ; %return ; CHECK-NEXT: ldp x29, x30, [sp, #48] ; 16-byte Folded Reload ; CHECK-NEXT: add sp, sp, #64 ; CHECK-NEXT: ret @@ -259,12 +259,6 @@ define fastcc i32 @prune_match(ptr nocapture readonly %a, ptr nocapture readonly ; CHECK-NEXT: ; %bb.46: ; %land.lhs.true52 ; CHECK-NEXT: cbz w8, LBB0_43 ; CHECK-NEXT: b LBB0_12 -; CHECK-NEXT: LBB0_47: -; CHECK-NEXT: .cfi_def_cfa wsp, 0 -; CHECK-NEXT: .cfi_same_value w30 -; CHECK-NEXT: .cfi_same_value w29 -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ret ; CHECK-NEXT: .loh AdrpLdrGot Lloh0, Lloh1 ; CHECK-NEXT: .loh AdrpLdrGot Lloh2, Lloh3 ; CHECK-NEXT: .loh AdrpLdrGot Lloh4, Lloh5 diff --git a/llvm/test/CodeGen/AArch64/shrinkwrap-split-restore-point.mir b/llvm/test/CodeGen/AArch64/shrinkwrap-split-restore-point.mir deleted file mode 100644 index 5b43dde0ae250..0000000000000 --- a/llvm/test/CodeGen/AArch64/shrinkwrap-split-restore-point.mir +++ /dev/null @@ -1,760 +0,0 @@ -# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2 -# RUN: llc -mtriple=aarch64 -run-pass=shrink-wrap -o - %s | FileCheck %s - ---- | - define void @shrink_test1(i32 %a) { - entry: - %cmp5 = icmp sgt i32 %a, 0 - br i1 %cmp5, label %BB0, label %exit - - BB0: ; preds = %entry - %call = call i32 @fun() - %c = icmp eq i32 %call, 0 - br i1 %c, label %BB1, label %exit - - BB1: ; preds = %BB0 - %call2 = call i32 @fun() - br label %exit - - exit: ; preds = %BB1, %BB0, %entry - ret void - } - - define void @shrink_test2(i32 %a, ptr %P1, ptr %P2) { - BB00: - %cmp5 = icmp sgt i32 %a, 0 - br i1 %cmp5, label %BB01, label %exit - - BB01: ; preds = %BB00 - store i32 %a, ptr %P1, align 4 - %c1 = icmp sgt i32 %a, 1 - br i1 %c1, label %BB02, label %BB03 - - BB02: ; preds = %BB01 - store i32 %a, ptr %P2, align 4 - br label %BB03 - - BB03: ; preds = %BB02, %BB01 - %call03 = call i32 @fun() - %c03 = icmp eq i32 %call03, 0 - br i1 %c03, label %BB04, label %BB05 - - BB04: ; preds = %BB03 - %call04 = call i32 @fun() - br label %BB05 - - BB05: ; preds = %BB04, %BB03 - %call05 = call i32 @fun() - %c05 = icmp eq i32 %call05, 0 - br i1 %c05, label %BB06, label %BB07 - - BB06: ; preds = %BB05 - %call06 = call i32 @fun() - br label %exit - - BB07: ; preds = %BB05 - %call07 = call i32 @fun2() - br label %exit - - exit: ; preds = %BB07, %BB06, %BB00 - ret void - } - - define void @noshrink_test1(i32 %a, i32 %v, i32 %v2) { - entry: - %cmp5 = icmp sgt i32 %a, 0 - br i1 %cmp5, label %BB0, label %exit - - BB0: ; preds = %entry - %c = icmp eq i32 %a, 10 - %c1 = icmp eq i32 %v, 10 - %or.cond = select i1 %c, i1 %c1, i1 false - br i1 %or.cond, label %BB3, label %BB2 - - BB2: ; preds = %BB0 - %c2 = icmp eq i32 %v2, 10 - br i1 %c2, label %BB4, label %exit - - BB3: ; preds = %BB0 - %call3 = call i32 @fun() - br label %exit - - BB4: ; preds = %BB2 - %call4 = call i32 @fun2() - br label %exit - - exit: ; preds = %BB4, %BB3, %BB2, %entry - ret void - } - - define void @noshrink_test2(i32 %a) { - BB00: - %cmp5 = icmp sgt i32 %a, 0 - br i1 %cmp5, label %BB01, label %InfLoop.preheader - - InfLoop.preheader: ; preds = %BB00 - br label %InfLoop - - BB01: ; preds = %BB00 - %call = call i32 @fun() - %c = icmp eq i32 %call, 0 - br i1 %c, label %BB02, label %exit - - BB02: ; preds = %BB01 - %call2 = call i32 @fun() - br label %exit - - InfLoop: ; preds = %InfLoop.preheader, %InfLoop - %call3 = call i32 @fun() - br label %InfLoop - - exit: ; preds = %BB02, %BB01 - ret void - } - - define void @noshrink_test3(i32 %a) { - BB00: - %cmp5 = icmp sgt i32 %a, 0 - %call02 = call i32 @fun() - br i1 %cmp5, label %BB02, label %BB01 - - BB01: ; preds = %BB00 - %0 = icmp eq i32 %call02, 0 - br i1 %0, label %BB01.1, label %exit - - BB01.1: ; preds = %BB01 - call void @abort() #0 - unreachable - - BB02: ; preds = %BB00 - %1 = icmp eq i32 %call02, 0 - br i1 %1, label %BB03, label %BB04 - - BB03: ; preds = %BB02 - %call03 = call i32 @fun() - %c03 = icmp eq i32 %call03, 0 - br i1 %c03, label %BB04, label %exit - - BB04: ; preds = %BB03, %BB02 - %call04 = call i32 @fun() - br label %exit - - exit: ; preds = %BB04, %BB03, %BB01 - ret void - } - - define void @noshrink_bb_as_inlineasmbr_target(i1 %cond) { - entry: - br i1 %cond, label %0, label %exit - - 0: ; preds = %entry - callbr void asm sideeffect "", "!i,~{flags}"() - to label %1 [label %exit] - - 1: ; preds = %0 - call void @dosomething() - br label %exit - - exit: ; preds = %1, %0, %entry - ret void - } - - declare i32 @fun() - declare i32 @fun2() - declare void @abort() - declare void @dosomething() -... ---- -name: shrink_test1 -alignment: 4 -tracksRegLiveness: true -tracksDebugUserValues: true -liveins: - - { reg: '$w0' } -frameInfo: - maxAlignment: 1 - adjustsStack: true - hasCalls: true - maxCallFrameSize: 0 -machineFunctionInfo: {} -body: | - ; CHECK-LABEL: name: shrink_test1 - ; CHECK: bb.0.entry: - ; CHECK-NEXT: successors: %bb.1(0x50000000), %bb.3(0x30000000) - ; CHECK-NEXT: liveins: $w0 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: dead $wzr = SUBSWri killed renamable $w0, 1, 0, implicit-def $nzcv - ; CHECK-NEXT: Bcc 11, %bb.3, implicit killed $nzcv - ; CHECK-NEXT: B %bb.1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.1.BB0: - ; CHECK-NEXT: successors: %bb.2(0x30000000), %bb.4(0x50000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: CBNZW killed renamable $w0, %bb.4 - ; CHECK-NEXT: B %bb.2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.2.BB1: - ; CHECK-NEXT: successors: %bb.4(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: B %bb.4 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.3.exit: - ; CHECK-NEXT: RET_ReallyLR - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.4: - ; CHECK-NEXT: successors: %bb.3(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: B %bb.3 - bb.0.entry: - successors: %bb.1(0x50000000), %bb.3(0x30000000) - liveins: $w0 - - dead $wzr = SUBSWri killed renamable $w0, 1, 0, implicit-def $nzcv - Bcc 11, %bb.3, implicit killed $nzcv - B %bb.1 - - bb.1.BB0: - successors: %bb.2(0x30000000), %bb.3(0x50000000) - - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - CBNZW killed renamable $w0, %bb.3 - B %bb.2 - - bb.2.BB1: - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - - bb.3.exit: - RET_ReallyLR - -... ---- -name: shrink_test2 -alignment: 4 -tracksRegLiveness: true -tracksDebugUserValues: true -liveins: - - { reg: '$w0' } - - { reg: '$x1' } - - { reg: '$x2' } -frameInfo: - maxAlignment: 1 - adjustsStack: true - hasCalls: true - maxCallFrameSize: 0 -machineFunctionInfo: {} -body: | - ; CHECK-LABEL: name: shrink_test2 - ; CHECK: bb.0.BB00: - ; CHECK-NEXT: successors: %bb.1(0x50000000), %bb.8(0x30000000) - ; CHECK-NEXT: liveins: $w0, $x1, $x2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: dead $wzr = SUBSWri renamable $w0, 1, 0, implicit-def $nzcv - ; CHECK-NEXT: Bcc 11, %bb.8, implicit killed $nzcv - ; CHECK-NEXT: B %bb.1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.1.BB01: - ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) - ; CHECK-NEXT: liveins: $w0, $x1, $x2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: dead $wzr = SUBSWri renamable $w0, 2, 0, implicit-def $nzcv - ; CHECK-NEXT: STRWui renamable $w0, killed renamable $x1, 0 :: (store (s32) into %ir.P1) - ; CHECK-NEXT: Bcc 11, %bb.3, implicit killed $nzcv - ; CHECK-NEXT: B %bb.2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.2.BB02: - ; CHECK-NEXT: successors: %bb.3(0x80000000) - ; CHECK-NEXT: liveins: $w0, $x2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: STRWui killed renamable $w0, killed renamable $x2, 0 :: (store (s32) into %ir.P2) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.3.BB03: - ; CHECK-NEXT: successors: %bb.4(0x30000000), %bb.5(0x50000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: CBNZW killed renamable $w0, %bb.5 - ; CHECK-NEXT: B %bb.4 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.4.BB04: - ; CHECK-NEXT: successors: %bb.5(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.5.BB05: - ; CHECK-NEXT: successors: %bb.6(0x30000000), %bb.7(0x50000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: CBNZW killed renamable $w0, %bb.7 - ; CHECK-NEXT: B %bb.6 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.6.BB06: - ; CHECK-NEXT: successors: %bb.9(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: B %bb.9 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.7.BB07: - ; CHECK-NEXT: successors: %bb.9(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun2, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: B %bb.9 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.8.exit: - ; CHECK-NEXT: RET_ReallyLR - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.9: - ; CHECK-NEXT: successors: %bb.8(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: B %bb.8 - bb.0.BB00: - successors: %bb.1(0x50000000), %bb.8(0x30000000) - liveins: $w0, $x1, $x2 - - dead $wzr = SUBSWri renamable $w0, 1, 0, implicit-def $nzcv - Bcc 11, %bb.8, implicit killed $nzcv - B %bb.1 - - bb.1.BB01: - successors: %bb.2, %bb.3 - liveins: $w0, $x1, $x2 - - dead $wzr = SUBSWri renamable $w0, 2, 0, implicit-def $nzcv - STRWui renamable $w0, killed renamable $x1, 0 :: (store (s32) into %ir.P1) - Bcc 11, %bb.3, implicit killed $nzcv - B %bb.2 - - bb.2.BB02: - liveins: $w0, $x2 - - STRWui killed renamable $w0, killed renamable $x2, 0 :: (store (s32) into %ir.P2) - - bb.3.BB03: - successors: %bb.4(0x30000000), %bb.5(0x50000000) - - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - CBNZW killed renamable $w0, %bb.5 - B %bb.4 - - bb.4.BB04: - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - - bb.5.BB05: - successors: %bb.6(0x30000000), %bb.7(0x50000000) - - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - CBNZW killed renamable $w0, %bb.7 - B %bb.6 - - bb.6.BB06: - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - B %bb.8 - - bb.7.BB07: - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun2, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - - bb.8.exit: - RET_ReallyLR - -... ---- -name: noshrink_test1 -alignment: 4 -tracksRegLiveness: true -tracksDebugUserValues: true -liveins: - - { reg: '$w0' } - - { reg: '$w1' } - - { reg: '$w2' } -frameInfo: - maxAlignment: 1 - adjustsStack: true - hasCalls: true - maxCallFrameSize: 0 -machineFunctionInfo: {} -body: | - ; CHECK-LABEL: name: noshrink_test1 - ; CHECK: bb.0.entry: - ; CHECK-NEXT: successors: %bb.1(0x50000000), %bb.6(0x30000000) - ; CHECK-NEXT: liveins: $w0, $w1, $w2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: dead $wzr = SUBSWri renamable $w0, 1, 0, implicit-def $nzcv - ; CHECK-NEXT: Bcc 11, %bb.6, implicit killed $nzcv - ; CHECK-NEXT: B %bb.1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.1.BB0: - ; CHECK-NEXT: successors: %bb.2(0x60000000), %bb.3(0x20000000) - ; CHECK-NEXT: liveins: $w0, $w1, $w2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: dead $wzr = SUBSWri killed renamable $w0, 10, 0, implicit-def $nzcv - ; CHECK-NEXT: Bcc 1, %bb.3, implicit killed $nzcv - ; CHECK-NEXT: B %bb.2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.2.BB0: - ; CHECK-NEXT: successors: %bb.4(0x55555555), %bb.3(0x2aaaaaab) - ; CHECK-NEXT: liveins: $w1, $w2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: dead $wzr = SUBSWri killed renamable $w1, 10, 0, implicit-def $nzcv - ; CHECK-NEXT: Bcc 0, %bb.4, implicit killed $nzcv - ; CHECK-NEXT: B %bb.3 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.3.BB2: - ; CHECK-NEXT: successors: %bb.5(0x40000000), %bb.6(0x40000000) - ; CHECK-NEXT: liveins: $w2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: dead $wzr = SUBSWri killed renamable $w2, 10, 0, implicit-def $nzcv - ; CHECK-NEXT: Bcc 0, %bb.5, implicit killed $nzcv - ; CHECK-NEXT: B %bb.6 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.4.BB3: - ; CHECK-NEXT: successors: %bb.6(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: B %bb.6 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.5.BB4: - ; CHECK-NEXT: successors: %bb.6(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun2, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.6.exit: - ; CHECK-NEXT: RET_ReallyLR - bb.0.entry: - successors: %bb.1(0x50000000), %bb.6(0x30000000) - liveins: $w0, $w1, $w2 - - dead $wzr = SUBSWri renamable $w0, 1, 0, implicit-def $nzcv - Bcc 11, %bb.6, implicit killed $nzcv - B %bb.1 - - bb.1.BB0: - successors: %bb.2(0x60000000), %bb.3(0x20000000) - liveins: $w0, $w1, $w2 - - dead $wzr = SUBSWri killed renamable $w0, 10, 0, implicit-def $nzcv - Bcc 1, %bb.3, implicit killed $nzcv - B %bb.2 - - bb.2.BB0: - successors: %bb.4(0x55555555), %bb.3(0x2aaaaaab) - liveins: $w1, $w2 - - dead $wzr = SUBSWri killed renamable $w1, 10, 0, implicit-def $nzcv - Bcc 0, %bb.4, implicit killed $nzcv - B %bb.3 - - bb.3.BB2: - liveins: $w2 - - dead $wzr = SUBSWri killed renamable $w2, 10, 0, implicit-def $nzcv - Bcc 0, %bb.5, implicit killed $nzcv - B %bb.6 - - bb.4.BB3: - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - B %bb.6 - - bb.5.BB4: - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun2, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - - bb.6.exit: - RET_ReallyLR - -... ---- -name: noshrink_test2 -alignment: 4 -tracksRegLiveness: true -tracksDebugUserValues: true -liveins: - - { reg: '$w0' } -frameInfo: - maxAlignment: 1 - adjustsStack: true - hasCalls: true - maxCallFrameSize: 0 -machineFunctionInfo: {} -body: | - ; CHECK-LABEL: name: noshrink_test2 - ; CHECK: bb.0.BB00: - ; CHECK-NEXT: successors: %bb.2(0x50000000), %bb.1(0x30000000) - ; CHECK-NEXT: liveins: $w0 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: dead $wzr = SUBSWri killed renamable $w0, 0, 0, implicit-def $nzcv - ; CHECK-NEXT: Bcc 12, %bb.2, implicit killed $nzcv - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.1: - ; CHECK-NEXT: successors: %bb.4(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: B %bb.4 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.2.BB01: - ; CHECK-NEXT: successors: %bb.3(0x30000000), %bb.5(0x50000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: CBNZW killed renamable $w0, %bb.5 - ; CHECK-NEXT: B %bb.3 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.3.BB02: - ; CHECK-NEXT: successors: %bb.5(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: B %bb.5 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.4.InfLoop: - ; CHECK-NEXT: successors: %bb.4(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: B %bb.4 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.5.exit: - ; CHECK-NEXT: RET_ReallyLR - bb.0.BB00: - successors: %bb.2(0x50000000), %bb.1(0x30000000) - liveins: $w0 - - dead $wzr = SUBSWri killed renamable $w0, 0, 0, implicit-def $nzcv - Bcc 12, %bb.2, implicit killed $nzcv - - bb.1: - B %bb.4 - - bb.2.BB01: - successors: %bb.3(0x30000000), %bb.5(0x50000000) - - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - CBNZW killed renamable $w0, %bb.5 - B %bb.3 - - bb.3.BB02: - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - B %bb.5 - - bb.4.InfLoop: - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - B %bb.4 - - bb.5.exit: - RET_ReallyLR - -... ---- -name: noshrink_test3 -alignment: 4 -tracksRegLiveness: true -tracksDebugUserValues: true -liveins: - - { reg: '$w0' } -frameInfo: - maxAlignment: 1 - adjustsStack: true - hasCalls: true - maxCallFrameSize: 0 -machineFunctionInfo: {} -body: | - ; CHECK-LABEL: name: noshrink_test3 - ; CHECK: bb.0.BB00: - ; CHECK-NEXT: successors: %bb.3(0x50000000), %bb.1(0x30000000) - ; CHECK-NEXT: liveins: $w0 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: renamable $w19 = COPY $w0 - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: dead $wzr = SUBSWri killed renamable $w19, 0, 0, implicit-def $nzcv - ; CHECK-NEXT: Bcc 12, %bb.3, implicit killed $nzcv - ; CHECK-NEXT: B %bb.1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.1.BB01: - ; CHECK-NEXT: successors: %bb.2(0x00000800), %bb.6(0x7ffff800) - ; CHECK-NEXT: liveins: $w0 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: CBNZW killed renamable $w0, %bb.6 - ; CHECK-NEXT: B %bb.2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.2.BB01.1: - ; CHECK-NEXT: successors: %bb.3(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @abort, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.3.BB02: - ; CHECK-NEXT: successors: %bb.4(0x30000000), %bb.5(0x50000000) - ; CHECK-NEXT: liveins: $w0 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: CBNZW killed renamable $w0, %bb.5 - ; CHECK-NEXT: B %bb.4 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.4.BB03: - ; CHECK-NEXT: successors: %bb.5(0x30000000), %bb.6(0x50000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: CBNZW killed renamable $w0, %bb.6 - ; CHECK-NEXT: B %bb.5 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.5.BB04: - ; CHECK-NEXT: successors: %bb.6(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.6.exit: - ; CHECK-NEXT: RET_ReallyLR - bb.0.BB00: - successors: %bb.3(0x50000000), %bb.1(0x30000000) - liveins: $w0 - - renamable $w19 = COPY $w0 - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - dead $wzr = SUBSWri killed renamable $w19, 0, 0, implicit-def $nzcv - Bcc 12, %bb.3, implicit killed $nzcv - B %bb.1 - - bb.1.BB01: - successors: %bb.2(0x00000800), %bb.6(0x7ffff800) - liveins: $w0 - - CBNZW killed renamable $w0, %bb.6 - B %bb.2 - - bb.2.BB01.1: - - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @abort, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - - bb.3.BB02: - successors: %bb.4(0x30000000), %bb.5(0x50000000) - liveins: $w0 - - CBNZW killed renamable $w0, %bb.5 - B %bb.4 - - bb.4.BB03: - successors: %bb.5(0x30000000), %bb.6(0x50000000) - - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - CBNZW killed renamable $w0, %bb.6 - B %bb.5 - - bb.5.BB04: - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @fun, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - - bb.6.exit: - RET_ReallyLR - -... ---- -name: noshrink_bb_as_inlineasmbr_target -registers: [] -liveins: - - { reg: '$w0', virtual-reg: '' } -frameInfo: - savePoint: '' - restorePoint: '' -body: | - ; CHECK-LABEL: name: noshrink_bb_as_inlineasmbr_target - ; CHECK: bb.0.entry: - ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.3(0x40000000) - ; CHECK-NEXT: liveins: $w0 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: TBZW killed renamable $w0, 0, %bb.3 - ; CHECK-NEXT: B %bb.1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.1 (%ir-block.0): - ; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.3(0x00000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: INLINEASM_BR &"", 1 /* sideeffect attdialect */, 13 /* imm */, %bb.3 - ; CHECK-NEXT: B %bb.2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.2 (%ir-block.1): - ; CHECK-NEXT: successors: %bb.3(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: BL @dosomething, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.3.exit (machine-block-address-taken, inlineasm-br-indirect-target): - ; CHECK-NEXT: RET_ReallyLR - bb.0.entry: - successors: %bb.1(0x40000000), %bb.3(0x40000000) - liveins: $w0 - - TBZW killed renamable $w0, 0, %bb.3 - B %bb.1 - - bb.1 (%ir-block.0): - successors: %bb.2(0x80000000), %bb.3(0x00000000) - - INLINEASM_BR &"", 1 /* sideeffect attdialect */, 13 /* imm */, %bb.3 - B %bb.2 - - bb.2 (%ir-block.1): - successors: %bb.3(0x80000000) - - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - BL @dosomething, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - - bb.3.exit (machine-block-address-taken, inlineasm-br-indirect-target): - RET_ReallyLR - -... diff --git a/llvm/test/CodeGen/AArch64/taildup-cfi.ll b/llvm/test/CodeGen/AArch64/taildup-cfi.ll index 4a87ceefbcf03..221503009cdb6 100644 --- a/llvm/test/CodeGen/AArch64/taildup-cfi.ll +++ b/llvm/test/CodeGen/AArch64/taildup-cfi.ll @@ -32,7 +32,7 @@ if.then: ; preds = %entry store i32 0, ptr @f, align 4, !tbaa !2 br label %if.end -; DARWIN: Merging into block +; DARWIN-NOT: Merging into block ; LINUX: Merging into block if.end: ; preds = %entry.if.end_crit_edge, %if.then diff --git a/llvm/test/CodeGen/ARM/ParallelDSP/multi-use-loads.ll b/llvm/test/CodeGen/ARM/ParallelDSP/multi-use-loads.ll index e45985136cf34..050696ad653eb 100644 --- a/llvm/test/CodeGen/ARM/ParallelDSP/multi-use-loads.ll +++ b/llvm/test/CodeGen/ARM/ParallelDSP/multi-use-loads.ll @@ -5,11 +5,11 @@ define i32 @add_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture readonly %arg2, ptr nocapture readonly %arg3) { ; CHECK-LE-LABEL: add_user: ; CHECK-LE: @ %bb.0: @ %entry +; CHECK-LE-NEXT: .save {r4, lr} +; CHECK-LE-NEXT: push {r4, lr} ; CHECK-LE-NEXT: cmp r0, #1 ; CHECK-LE-NEXT: blt .LBB0_4 ; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader -; CHECK-LE-NEXT: .save {r4, lr} -; CHECK-LE-NEXT: push {r4, lr} ; CHECK-LE-NEXT: sub.w lr, r3, #2 ; CHECK-LE-NEXT: subs r2, #2 ; CHECK-LE-NEXT: mov.w r12, #0 @@ -22,23 +22,22 @@ define i32 @add_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture reado ; CHECK-LE-NEXT: sxtah r1, r1, r3 ; CHECK-LE-NEXT: smlad r12, r4, r3, r12 ; CHECK-LE-NEXT: bne .LBB0_2 -; CHECK-LE-NEXT: @ %bb.3: -; CHECK-LE-NEXT: pop.w {r4, lr} +; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup ; CHECK-LE-NEXT: add.w r0, r12, r1 -; CHECK-LE-NEXT: bx lr +; CHECK-LE-NEXT: pop {r4, pc} ; CHECK-LE-NEXT: .LBB0_4: ; CHECK-LE-NEXT: mov.w r12, #0 ; CHECK-LE-NEXT: movs r1, #0 ; CHECK-LE-NEXT: add.w r0, r12, r1 -; CHECK-LE-NEXT: bx lr +; CHECK-LE-NEXT: pop {r4, pc} ; ; CHECK-BE-LABEL: add_user: ; CHECK-BE: @ %bb.0: @ %entry +; CHECK-BE-NEXT: .save {r4, r5, r7, lr} +; CHECK-BE-NEXT: push {r4, r5, r7, lr} ; CHECK-BE-NEXT: cmp r0, #1 ; CHECK-BE-NEXT: blt .LBB0_4 ; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader -; CHECK-BE-NEXT: .save {r4, r5, r7, lr} -; CHECK-BE-NEXT: push {r4, r5, r7, lr} ; CHECK-BE-NEXT: subs r3, #2 ; CHECK-BE-NEXT: subs r2, #2 ; CHECK-BE-NEXT: mov.w r12, #0 @@ -54,15 +53,14 @@ define i32 @add_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture reado ; CHECK-BE-NEXT: ldrsh.w r4, [r3, #2] ; CHECK-BE-NEXT: smlabb r12, r5, r4, r12 ; CHECK-BE-NEXT: bne .LBB0_2 -; CHECK-BE-NEXT: @ %bb.3: -; CHECK-BE-NEXT: pop.w {r4, r5, r7, lr} +; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup ; CHECK-BE-NEXT: add.w r0, r12, r1 -; CHECK-BE-NEXT: bx lr +; CHECK-BE-NEXT: pop {r4, r5, r7, pc} ; CHECK-BE-NEXT: .LBB0_4: ; CHECK-BE-NEXT: mov.w r12, #0 ; CHECK-BE-NEXT: movs r1, #0 ; CHECK-BE-NEXT: add.w r0, r12, r1 -; CHECK-BE-NEXT: bx lr +; CHECK-BE-NEXT: pop {r4, r5, r7, pc} entry: %cmp24 = icmp sgt i32 %arg, 0 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup @@ -107,11 +105,11 @@ for.body: define i32 @mul_bottom_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture readonly %arg2, ptr nocapture readonly %arg3) { ; CHECK-LE-LABEL: mul_bottom_user: ; CHECK-LE: @ %bb.0: @ %entry +; CHECK-LE-NEXT: .save {r4, lr} +; CHECK-LE-NEXT: push {r4, lr} ; CHECK-LE-NEXT: cmp r0, #1 ; CHECK-LE-NEXT: blt .LBB1_4 ; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader -; CHECK-LE-NEXT: .save {r4, lr} -; CHECK-LE-NEXT: push {r4, lr} ; CHECK-LE-NEXT: sub.w lr, r3, #2 ; CHECK-LE-NEXT: subs r2, #2 ; CHECK-LE-NEXT: mov.w r12, #0 @@ -125,23 +123,22 @@ define i32 @mul_bottom_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocaptur ; CHECK-LE-NEXT: sxth r3, r3 ; CHECK-LE-NEXT: mul r1, r3, r1 ; CHECK-LE-NEXT: bne .LBB1_2 -; CHECK-LE-NEXT: @ %bb.3: -; CHECK-LE-NEXT: pop.w {r4, lr} +; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup ; CHECK-LE-NEXT: add.w r0, r12, r1 -; CHECK-LE-NEXT: bx lr +; CHECK-LE-NEXT: pop {r4, pc} ; CHECK-LE-NEXT: .LBB1_4: ; CHECK-LE-NEXT: mov.w r12, #0 ; CHECK-LE-NEXT: movs r1, #0 ; CHECK-LE-NEXT: add.w r0, r12, r1 -; CHECK-LE-NEXT: bx lr +; CHECK-LE-NEXT: pop {r4, pc} ; ; CHECK-BE-LABEL: mul_bottom_user: ; CHECK-BE: @ %bb.0: @ %entry +; CHECK-BE-NEXT: .save {r4, r5, r7, lr} +; CHECK-BE-NEXT: push {r4, r5, r7, lr} ; CHECK-BE-NEXT: cmp r0, #1 ; CHECK-BE-NEXT: blt .LBB1_4 ; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader -; CHECK-BE-NEXT: .save {r4, r5, r7, lr} -; CHECK-BE-NEXT: push {r4, r5, r7, lr} ; CHECK-BE-NEXT: subs r3, #2 ; CHECK-BE-NEXT: subs r2, #2 ; CHECK-BE-NEXT: mov.w r12, #0 @@ -157,15 +154,14 @@ define i32 @mul_bottom_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocaptur ; CHECK-BE-NEXT: ldrsh.w r4, [r3, #2] ; CHECK-BE-NEXT: smlabb r12, r5, r4, r12 ; CHECK-BE-NEXT: bne .LBB1_2 -; CHECK-BE-NEXT: @ %bb.3: -; CHECK-BE-NEXT: pop.w {r4, r5, r7, lr} +; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup ; CHECK-BE-NEXT: add.w r0, r12, r1 -; CHECK-BE-NEXT: bx lr +; CHECK-BE-NEXT: pop {r4, r5, r7, pc} ; CHECK-BE-NEXT: .LBB1_4: ; CHECK-BE-NEXT: mov.w r12, #0 ; CHECK-BE-NEXT: movs r1, #0 ; CHECK-BE-NEXT: add.w r0, r12, r1 -; CHECK-BE-NEXT: bx lr +; CHECK-BE-NEXT: pop {r4, r5, r7, pc} entry: %cmp24 = icmp sgt i32 %arg, 0 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup @@ -210,11 +206,11 @@ for.body: define i32 @mul_top_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture readonly %arg2, ptr nocapture readonly %arg3) { ; CHECK-LE-LABEL: mul_top_user: ; CHECK-LE: @ %bb.0: @ %entry +; CHECK-LE-NEXT: .save {r4, lr} +; CHECK-LE-NEXT: push {r4, lr} ; CHECK-LE-NEXT: cmp r0, #1 ; CHECK-LE-NEXT: blt .LBB2_4 ; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader -; CHECK-LE-NEXT: .save {r4, lr} -; CHECK-LE-NEXT: push {r4, lr} ; CHECK-LE-NEXT: subs r3, #2 ; CHECK-LE-NEXT: subs r2, #2 ; CHECK-LE-NEXT: mov.w r12, #0 @@ -228,23 +224,22 @@ define i32 @mul_top_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture r ; CHECK-LE-NEXT: asr.w r4, r4, #16 ; CHECK-LE-NEXT: mul r1, r4, r1 ; CHECK-LE-NEXT: bne .LBB2_2 -; CHECK-LE-NEXT: @ %bb.3: -; CHECK-LE-NEXT: pop.w {r4, lr} +; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup ; CHECK-LE-NEXT: add.w r0, r12, r1 -; CHECK-LE-NEXT: bx lr +; CHECK-LE-NEXT: pop {r4, pc} ; CHECK-LE-NEXT: .LBB2_4: ; CHECK-LE-NEXT: mov.w r12, #0 ; CHECK-LE-NEXT: movs r1, #0 ; CHECK-LE-NEXT: add.w r0, r12, r1 -; CHECK-LE-NEXT: bx lr +; CHECK-LE-NEXT: pop {r4, pc} ; ; CHECK-BE-LABEL: mul_top_user: ; CHECK-BE: @ %bb.0: @ %entry +; CHECK-BE-NEXT: .save {r4, lr} +; CHECK-BE-NEXT: push {r4, lr} ; CHECK-BE-NEXT: cmp r0, #1 ; CHECK-BE-NEXT: blt .LBB2_4 ; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader -; CHECK-BE-NEXT: .save {r4, lr} -; CHECK-BE-NEXT: push {r4, lr} ; CHECK-BE-NEXT: subs r3, #2 ; CHECK-BE-NEXT: subs r2, #2 ; CHECK-BE-NEXT: mov.w r12, #0 @@ -260,15 +255,14 @@ define i32 @mul_top_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture r ; CHECK-BE-NEXT: mul r1, r4, r1 ; CHECK-BE-NEXT: smlabb r12, r4, lr, r12 ; CHECK-BE-NEXT: bne .LBB2_2 -; CHECK-BE-NEXT: @ %bb.3: -; CHECK-BE-NEXT: pop.w {r4, lr} +; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup ; CHECK-BE-NEXT: add.w r0, r12, r1 -; CHECK-BE-NEXT: bx lr +; CHECK-BE-NEXT: pop {r4, pc} ; CHECK-BE-NEXT: .LBB2_4: ; CHECK-BE-NEXT: mov.w r12, #0 ; CHECK-BE-NEXT: movs r1, #0 ; CHECK-BE-NEXT: add.w r0, r12, r1 -; CHECK-BE-NEXT: bx lr +; CHECK-BE-NEXT: pop {r4, pc} entry: %cmp24 = icmp sgt i32 %arg, 0 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup @@ -313,11 +307,11 @@ for.body: define i32 @and_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture readonly %arg2, ptr nocapture readonly %arg3) { ; CHECK-LE-LABEL: and_user: ; CHECK-LE: @ %bb.0: @ %entry +; CHECK-LE-NEXT: .save {r4, lr} +; CHECK-LE-NEXT: push {r4, lr} ; CHECK-LE-NEXT: cmp r0, #1 ; CHECK-LE-NEXT: blt .LBB3_4 ; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader -; CHECK-LE-NEXT: .save {r4, lr} -; CHECK-LE-NEXT: push {r4, lr} ; CHECK-LE-NEXT: sub.w lr, r3, #2 ; CHECK-LE-NEXT: subs r2, #2 ; CHECK-LE-NEXT: mov.w r12, #0 @@ -331,23 +325,22 @@ define i32 @and_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture reado ; CHECK-LE-NEXT: uxth r3, r3 ; CHECK-LE-NEXT: mul r1, r3, r1 ; CHECK-LE-NEXT: bne .LBB3_2 -; CHECK-LE-NEXT: @ %bb.3: -; CHECK-LE-NEXT: pop.w {r4, lr} +; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup ; CHECK-LE-NEXT: add.w r0, r12, r1 -; CHECK-LE-NEXT: bx lr +; CHECK-LE-NEXT: pop {r4, pc} ; CHECK-LE-NEXT: .LBB3_4: ; CHECK-LE-NEXT: mov.w r12, #0 ; CHECK-LE-NEXT: movs r1, #0 ; CHECK-LE-NEXT: add.w r0, r12, r1 -; CHECK-LE-NEXT: bx lr +; CHECK-LE-NEXT: pop {r4, pc} ; ; CHECK-BE-LABEL: and_user: ; CHECK-BE: @ %bb.0: @ %entry +; CHECK-BE-NEXT: .save {r4, r5, r7, lr} +; CHECK-BE-NEXT: push {r4, r5, r7, lr} ; CHECK-BE-NEXT: cmp r0, #1 ; CHECK-BE-NEXT: blt .LBB3_4 ; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader -; CHECK-BE-NEXT: .save {r4, r5, r7, lr} -; CHECK-BE-NEXT: push {r4, r5, r7, lr} ; CHECK-BE-NEXT: subs r3, #2 ; CHECK-BE-NEXT: subs r2, #2 ; CHECK-BE-NEXT: mov.w r12, #0 @@ -363,15 +356,14 @@ define i32 @and_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture reado ; CHECK-BE-NEXT: ldrsh.w r4, [r3, #2] ; CHECK-BE-NEXT: smlabb r12, r5, r4, r12 ; CHECK-BE-NEXT: bne .LBB3_2 -; CHECK-BE-NEXT: @ %bb.3: -; CHECK-BE-NEXT: pop.w {r4, r5, r7, lr} +; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup ; CHECK-BE-NEXT: add.w r0, r12, r1 -; CHECK-BE-NEXT: bx lr +; CHECK-BE-NEXT: pop {r4, r5, r7, pc} ; CHECK-BE-NEXT: .LBB3_4: ; CHECK-BE-NEXT: mov.w r12, #0 ; CHECK-BE-NEXT: movs r1, #0 ; CHECK-BE-NEXT: add.w r0, r12, r1 -; CHECK-BE-NEXT: bx lr +; CHECK-BE-NEXT: pop {r4, r5, r7, pc} entry: %cmp24 = icmp sgt i32 %arg, 0 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup diff --git a/llvm/test/CodeGen/ARM/code-placement.ll b/llvm/test/CodeGen/ARM/code-placement.ll index 01d72f134aacb..7755ff53512ef 100644 --- a/llvm/test/CodeGen/ARM/code-placement.ll +++ b/llvm/test/CodeGen/ARM/code-placement.ll @@ -11,6 +11,7 @@ entry: br i1 %0, label %bb2, label %bb bb: +; CHECK: LBB0_1: ; CHECK: LBB0_[[LABEL:[0-9]]]: ; CHECK: bne LBB0_[[LABEL]] ; CHECK-NOT: b LBB0_[[LABEL]] diff --git a/llvm/test/CodeGen/ARM/mbp.ll b/llvm/test/CodeGen/ARM/mbp.ll index 4f96029e06b95..e7ab3860b52ac 100644 --- a/llvm/test/CodeGen/ARM/mbp.ll +++ b/llvm/test/CodeGen/ARM/mbp.ll @@ -1,4 +1,3 @@ -; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 ; RUN: llc < %s | FileCheck %s target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" target triple = "thumbv7-unknown-linux-gnueabihf" @@ -7,50 +6,16 @@ target triple = "thumbv7-unknown-linux-gnueabihf" %List = type { i32, ptr } ; The entry block should be the first block of the function. +; CHECK-LABEL: foo +; CHECK: %entry +; CHECK: %for.body +; CHECK: %for.inc +; CHECK: %if.then +; CHECK: %for.cond.i +; CHECK: %for.body.i +; CHECK: %return define i1 @foo(ptr %ha, i32 %he) !prof !39 { -; CHECK-LABEL: foo: -; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: ldr r2, [r0] -; CHECK-NEXT: cmp r2, #0 -; CHECK-NEXT: itt eq -; CHECK-NEXT: moveq r0, #0 -; CHECK-NEXT: bxeq lr -; CHECK-NEXT: .LBB0_1: @ %for.body.preheader -; CHECK-NEXT: .save {r7, lr} -; CHECK-NEXT: push {r7, lr} -; CHECK-NEXT: b .LBB0_3 -; CHECK-NEXT: .LBB0_2: @ %for.inc -; CHECK-NEXT: @ in Loop: Header=BB0_3 Depth=1 -; CHECK-NEXT: ldr r2, [r2] -; CHECK-NEXT: movs r0, #0 -; CHECK-NEXT: cmp r2, #0 -; CHECK-NEXT: it eq -; CHECK-NEXT: popeq {r7, pc} -; CHECK-NEXT: .LBB0_3: @ %for.body -; CHECK-NEXT: @ =>This Loop Header: Depth=1 -; CHECK-NEXT: @ Child Loop BB0_5 Depth 2 -; CHECK-NEXT: ldr r0, [r2, #4] -; CHECK-NEXT: cmp r0, #0 -; CHECK-NEXT: beq .LBB0_2 -; CHECK-NEXT: @ %bb.4: @ %if.then -; CHECK-NEXT: @ in Loop: Header=BB0_3 Depth=1 -; CHECK-NEXT: ldrd r3, r0, [r0] -; CHECK-NEXT: sub.w r12, r0, #4 -; CHECK-NEXT: .LBB0_5: @ %for.cond.i -; CHECK-NEXT: @ Parent Loop BB0_3 Depth=1 -; CHECK-NEXT: @ => This Inner Loop Header: Depth=2 -; CHECK-NEXT: cmp r3, #1 -; CHECK-NEXT: blt .LBB0_2 -; CHECK-NEXT: @ %bb.6: @ %for.body.i -; CHECK-NEXT: @ in Loop: Header=BB0_5 Depth=2 -; CHECK-NEXT: ldr.w lr, [r12, r3, lsl #2] -; CHECK-NEXT: subs r3, #1 -; CHECK-NEXT: movs r0, #1 -; CHECK-NEXT: cmp lr, r1 -; CHECK-NEXT: bne .LBB0_5 -; CHECK-NEXT: @ %bb.7: -; CHECK-NEXT: pop {r7, pc} entry: %TargetPtr = load ptr, ptr %ha, align 4 %cmp1 = icmp eq ptr %TargetPtr, null diff --git a/llvm/test/CodeGen/ARM/ssat-unroll-loops.ll b/llvm/test/CodeGen/ARM/ssat-unroll-loops.ll index c9724674afd82..2755d354a6244 100644 --- a/llvm/test/CodeGen/ARM/ssat-unroll-loops.ll +++ b/llvm/test/CodeGen/ARM/ssat-unroll-loops.ll @@ -6,11 +6,11 @@ define void @ssat_unroll(ptr %pSrcA, ptr %pSrcB, ptr %pDst, i32 %blockSize) { ; CHECK-LABEL: ssat_unroll: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #0 -; CHECK-NEXT: bxeq lr -; CHECK-NEXT: .LBB0_1: @ %while.body.preheader ; CHECK-NEXT: .save {r11, lr} ; CHECK-NEXT: push {r11, lr} +; CHECK-NEXT: cmp r3, #0 +; CHECK-NEXT: beq .LBB0_5 +; CHECK-NEXT: @ %bb.1: @ %while.body.preheader ; CHECK-NEXT: sub r12, r3, #1 ; CHECK-NEXT: tst r3, #1 ; CHECK-NEXT: beq .LBB0_3 @@ -23,7 +23,7 @@ define void @ssat_unroll(ptr %pSrcA, ptr %pSrcB, ptr %pDst, i32 %blockSize) { ; CHECK-NEXT: mov r3, r12 ; CHECK-NEXT: .LBB0_3: @ %while.body.prol.loopexit ; CHECK-NEXT: cmp r12, #0 -; CHECK-NEXT: beq .LBB0_5 +; CHECK-NEXT: popeq {r11, pc} ; CHECK-NEXT: .LBB0_4: @ %while.body ; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ldrsh r12, [r0] @@ -41,9 +41,8 @@ define void @ssat_unroll(ptr %pSrcA, ptr %pSrcB, ptr %pDst, i32 %blockSize) { ; CHECK-NEXT: strh r12, [r2, #2] ; CHECK-NEXT: add r2, r2, #4 ; CHECK-NEXT: bne .LBB0_4 -; CHECK-NEXT: .LBB0_5: -; CHECK-NEXT: pop {r11, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB0_5: @ %while.end +; CHECK-NEXT: pop {r11, pc} entry: %cmp.not7 = icmp eq i32 %blockSize, 0 br i1 %cmp.not7, label %while.end, label %while.body.preheader @@ -126,11 +125,11 @@ while.end: ; preds = %while.body, %while. define void @ssat_unroll_minmax(ptr nocapture readonly %pSrcA, ptr nocapture readonly %pSrcB, ptr nocapture writeonly %pDst, i32 %blockSize) { ; CHECK-LABEL: ssat_unroll_minmax: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #0 -; CHECK-NEXT: bxeq lr -; CHECK-NEXT: .LBB1_1: @ %while.body.preheader ; CHECK-NEXT: .save {r11, lr} ; CHECK-NEXT: push {r11, lr} +; CHECK-NEXT: cmp r3, #0 +; CHECK-NEXT: beq .LBB1_5 +; CHECK-NEXT: @ %bb.1: @ %while.body.preheader ; CHECK-NEXT: sub r12, r3, #1 ; CHECK-NEXT: tst r3, #1 ; CHECK-NEXT: beq .LBB1_3 @@ -143,7 +142,7 @@ define void @ssat_unroll_minmax(ptr nocapture readonly %pSrcA, ptr nocapture rea ; CHECK-NEXT: mov r3, r12 ; CHECK-NEXT: .LBB1_3: @ %while.body.prol.loopexit ; CHECK-NEXT: cmp r12, #0 -; CHECK-NEXT: beq .LBB1_5 +; CHECK-NEXT: popeq {r11, pc} ; CHECK-NEXT: .LBB1_4: @ %while.body ; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ldrsh r12, [r0] @@ -161,9 +160,8 @@ define void @ssat_unroll_minmax(ptr nocapture readonly %pSrcA, ptr nocapture rea ; CHECK-NEXT: strh r12, [r2, #2] ; CHECK-NEXT: add r2, r2, #4 ; CHECK-NEXT: bne .LBB1_4 -; CHECK-NEXT: .LBB1_5: -; CHECK-NEXT: pop {r11, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB1_5: @ %while.end +; CHECK-NEXT: pop {r11, pc} entry: %cmp.not7 = icmp eq i32 %blockSize, 0 br i1 %cmp.not7, label %while.end, label %while.body.preheader diff --git a/llvm/test/CodeGen/PowerPC/common-chain-aix32.ll b/llvm/test/CodeGen/PowerPC/common-chain-aix32.ll index 35ddcfd9ba6d6..0cf7119eab84c 100644 --- a/llvm/test/CodeGen/PowerPC/common-chain-aix32.ll +++ b/llvm/test/CodeGen/PowerPC/common-chain-aix32.ll @@ -39,19 +39,19 @@ define i64 @two_chain_same_offset_succ_i32(ptr %p, i32 %offset, i32 %base1, i64 ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cmplwi r6, 0 ; CHECK-NEXT: cmpwi cr1, r6, 0 +; CHECK-NEXT: stw r30, -8(r1) # 4-byte Folded Spill +; CHECK-NEXT: stw r31, -4(r1) # 4-byte Folded Spill ; CHECK-NEXT: crandc 4*cr5+lt, 4*cr1+lt, eq ; CHECK-NEXT: cmpwi cr1, r7, 0 -; CHECK-NEXT: bc 12, 4*cr5+lt, L..BB0_6 +; CHECK-NEXT: bc 12, 4*cr5+lt, L..BB0_5 ; CHECK-NEXT: # %bb.1: # %entry ; CHECK-NEXT: crand 4*cr5+lt, eq, 4*cr1+eq -; CHECK-NEXT: bc 12, 4*cr5+lt, L..BB0_6 +; CHECK-NEXT: bc 12, 4*cr5+lt, L..BB0_5 ; CHECK-NEXT: # %bb.2: # %for.body.preheader ; CHECK-NEXT: slwi r8, r4, 1 ; CHECK-NEXT: li r10, 0 ; CHECK-NEXT: li r11, 0 -; CHECK-NEXT: stw r30, -8(r1) # 4-byte Folded Spill ; CHECK-NEXT: add r8, r4, r8 -; CHECK-NEXT: stw r31, -4(r1) # 4-byte Folded Spill ; CHECK-NEXT: add r9, r5, r8 ; CHECK-NEXT: add r5, r5, r4 ; CHECK-NEXT: add r8, r3, r5 @@ -83,15 +83,15 @@ define i64 @two_chain_same_offset_succ_i32(ptr %p, i32 %offset, i32 %base1, i64 ; CHECK-NEXT: # ; CHECK-NEXT: crand 4*cr5+lt, eq, 4*cr1+lt ; CHECK-NEXT: bc 12, 4*cr5+lt, L..BB0_3 -; CHECK-NEXT: # %bb.5: +; CHECK-NEXT: b L..BB0_6 +; CHECK-NEXT: L..BB0_5: +; CHECK-NEXT: li r3, 0 +; CHECK-NEXT: li r5, 0 +; CHECK-NEXT: L..BB0_6: # %for.cond.cleanup ; CHECK-NEXT: lwz r31, -4(r1) # 4-byte Folded Reload ; CHECK-NEXT: lwz r30, -8(r1) # 4-byte Folded Reload ; CHECK-NEXT: mr r4, r5 ; CHECK-NEXT: blr -; CHECK-NEXT: L..BB0_6: -; CHECK-NEXT: li r3, 0 -; CHECK-NEXT: li r4, 0 -; CHECK-NEXT: blr entry: %add = add nsw i32 %base1, %offset %mul = shl nsw i32 %offset, 1 diff --git a/llvm/test/CodeGen/PowerPC/common-chain.ll b/llvm/test/CodeGen/PowerPC/common-chain.ll index 5f8c21e30f8fd..ea8a72e7d11e1 100644 --- a/llvm/test/CodeGen/PowerPC/common-chain.ll +++ b/llvm/test/CodeGen/PowerPC/common-chain.ll @@ -137,14 +137,14 @@ define i64 @not_perfect_chain_all_same_offset_fail(ptr %p, i64 %offset, i64 %bas ; CHECK-LABEL: not_perfect_chain_all_same_offset_fail: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cmpdi r6, 0 +; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill ; CHECK-NEXT: ble cr0, .LBB1_4 ; CHECK-NEXT: # %bb.1: # %for.body.preheader -; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill ; CHECK-NEXT: sldi r7, r4, 1 +; CHECK-NEXT: sldi r9, r4, 2 ; CHECK-NEXT: add r5, r3, r5 ; CHECK-NEXT: li r3, 0 ; CHECK-NEXT: add r8, r4, r7 -; CHECK-NEXT: sldi r9, r4, 2 ; CHECK-NEXT: mtctr r6 ; CHECK-NEXT: add r10, r4, r9 ; CHECK-NEXT: .p2align 4 @@ -161,11 +161,12 @@ define i64 @not_perfect_chain_all_same_offset_fail(ptr %p, i64 %offset, i64 %bas ; CHECK-NEXT: mulld r6, r6, r0 ; CHECK-NEXT: maddld r3, r6, r30, r3 ; CHECK-NEXT: bdnz .LBB1_2 -; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: # %bb.3: # %for.cond.cleanup ; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload ; CHECK-NEXT: blr ; CHECK-NEXT: .LBB1_4: ; CHECK-NEXT: li r3, 0 +; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload ; CHECK-NEXT: blr entry: %mul = shl nsw i64 %offset, 1 @@ -424,20 +425,20 @@ define i64 @not_same_offset_fail(ptr %p, i64 %offset, i64 %base1, i64 %n) { ; CHECK-LABEL: not_same_offset_fail: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cmpdi r6, 0 -; CHECK-NEXT: ble cr0, .LBB4_4 -; CHECK-NEXT: # %bb.1: # %for.body.preheader ; CHECK-NEXT: std r28, -32(r1) # 8-byte Folded Spill ; CHECK-NEXT: std r29, -24(r1) # 8-byte Folded Spill -; CHECK-NEXT: add r5, r3, r5 -; CHECK-NEXT: li r3, 0 ; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill -; CHECK-NEXT: mtctr r6 +; CHECK-NEXT: ble cr0, .LBB4_3 +; CHECK-NEXT: # %bb.1: # %for.body.preheader ; CHECK-NEXT: mulli r11, r4, 10 ; CHECK-NEXT: sldi r8, r4, 2 +; CHECK-NEXT: add r5, r3, r5 +; CHECK-NEXT: li r3, 0 ; CHECK-NEXT: add r8, r4, r8 ; CHECK-NEXT: sldi r9, r4, 3 -; CHECK-NEXT: sub r10, r9, r4 +; CHECK-NEXT: mtctr r6 ; CHECK-NEXT: sldi r7, r4, 1 +; CHECK-NEXT: sub r10, r9, r4 ; CHECK-NEXT: .p2align 4 ; CHECK-NEXT: .LBB4_2: # %for.body ; CHECK-NEXT: # @@ -454,14 +455,14 @@ define i64 @not_same_offset_fail(ptr %p, i64 %offset, i64 %base1, i64 %n) { ; CHECK-NEXT: mulld r6, r6, r29 ; CHECK-NEXT: maddld r3, r6, r28, r3 ; CHECK-NEXT: bdnz .LBB4_2 -; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: b .LBB4_4 +; CHECK-NEXT: .LBB4_3: +; CHECK-NEXT: li r3, 0 +; CHECK-NEXT: .LBB4_4: # %for.cond.cleanup ; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload ; CHECK-NEXT: ld r29, -24(r1) # 8-byte Folded Reload ; CHECK-NEXT: ld r28, -32(r1) # 8-byte Folded Reload ; CHECK-NEXT: blr -; CHECK-NEXT: .LBB4_4: -; CHECK-NEXT: li r3, 0 -; CHECK-NEXT: blr entry: %mul = shl nsw i64 %offset, 1 %mul2 = mul nsw i64 %offset, 5 diff --git a/llvm/test/CodeGen/PowerPC/loop-instr-form-prepare.ll b/llvm/test/CodeGen/PowerPC/loop-instr-form-prepare.ll index 37baef6043884..769b358131e9a 100644 --- a/llvm/test/CodeGen/PowerPC/loop-instr-form-prepare.ll +++ b/llvm/test/CodeGen/PowerPC/loop-instr-form-prepare.ll @@ -192,21 +192,21 @@ define i64 @test_max_number_reminder(ptr %arg, i32 signext %arg1) { ; CHECK-LABEL: test_max_number_reminder: ; CHECK: # %bb.0: # %bb ; CHECK-NEXT: cmplwi r4, 0 -; CHECK-NEXT: beq cr0, .LBB2_4 +; CHECK-NEXT: std r25, -56(r1) # 8-byte Folded Spill +; CHECK-NEXT: std r26, -48(r1) # 8-byte Folded Spill +; CHECK-NEXT: std r27, -40(r1) # 8-byte Folded Spill +; CHECK-NEXT: std r28, -32(r1) # 8-byte Folded Spill +; CHECK-NEXT: std r29, -24(r1) # 8-byte Folded Spill +; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill +; CHECK-NEXT: beq cr0, .LBB2_3 ; CHECK-NEXT: # %bb.1: # %bb3.preheader ; CHECK-NEXT: cmpldi r4, 1 ; CHECK-NEXT: li r5, 1 ; CHECK-NEXT: addi r9, r3, 4002 -; CHECK-NEXT: std r25, -56(r1) # 8-byte Folded Spill ; CHECK-NEXT: li r6, -1 -; CHECK-NEXT: std r26, -48(r1) # 8-byte Folded Spill ; CHECK-NEXT: li r7, 3 ; CHECK-NEXT: li r8, 5 ; CHECK-NEXT: li r10, 9 -; CHECK-NEXT: std r27, -40(r1) # 8-byte Folded Spill -; CHECK-NEXT: std r28, -32(r1) # 8-byte Folded Spill -; CHECK-NEXT: std r29, -24(r1) # 8-byte Folded Spill -; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill ; CHECK-NEXT: iselgt r3, r4, r5 ; CHECK-NEXT: mtctr r3 ; CHECK-NEXT: li r3, 0 @@ -232,7 +232,10 @@ define i64 @test_max_number_reminder(ptr %arg, i32 signext %arg1) { ; CHECK-NEXT: mulld r11, r11, r26 ; CHECK-NEXT: maddld r3, r11, r25, r3 ; CHECK-NEXT: bdnz .LBB2_2 -; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: b .LBB2_4 +; CHECK-NEXT: .LBB2_3: +; CHECK-NEXT: li r3, 0 +; CHECK-NEXT: .LBB2_4: # %bb45 ; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload ; CHECK-NEXT: ld r29, -24(r1) # 8-byte Folded Reload ; CHECK-NEXT: ld r28, -32(r1) # 8-byte Folded Reload @@ -241,9 +244,6 @@ define i64 @test_max_number_reminder(ptr %arg, i32 signext %arg1) { ; CHECK-NEXT: ld r26, -48(r1) # 8-byte Folded Reload ; CHECK-NEXT: ld r25, -56(r1) # 8-byte Folded Reload ; CHECK-NEXT: blr -; CHECK-NEXT: .LBB2_4: -; CHECK-NEXT: addi r3, r4, 0 -; CHECK-NEXT: blr bb: %i = sext i32 %arg1 to i64 %i2 = icmp eq i32 %arg1, 0 @@ -475,11 +475,11 @@ define dso_local i64 @test_ds_multiple_chains(ptr %arg, ptr %arg1, i32 signext % ; CHECK-LABEL: test_ds_multiple_chains: ; CHECK: # %bb.0: # %bb ; CHECK-NEXT: cmplwi r5, 0 -; CHECK-NEXT: beq cr0, .LBB5_4 +; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill +; CHECK-NEXT: beq cr0, .LBB5_3 ; CHECK-NEXT: # %bb.1: # %bb4.preheader ; CHECK-NEXT: cmpldi r5, 1 ; CHECK-NEXT: li r6, 1 -; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill ; CHECK-NEXT: addi r3, r3, 4001 ; CHECK-NEXT: addi r4, r4, 4001 ; CHECK-NEXT: li r7, 9 @@ -507,13 +507,13 @@ define dso_local i64 @test_ds_multiple_chains(ptr %arg, ptr %arg1, i32 signext % ; CHECK-NEXT: mulld r8, r8, r30 ; CHECK-NEXT: maddld r6, r8, r9, r6 ; CHECK-NEXT: bdnz .LBB5_2 -; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: b .LBB5_4 +; CHECK-NEXT: .LBB5_3: +; CHECK-NEXT: li r6, 0 +; CHECK-NEXT: .LBB5_4: # %bb43 ; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload ; CHECK-NEXT: add r3, r6, r5 ; CHECK-NEXT: blr -; CHECK-NEXT: .LBB5_4: -; CHECK-NEXT: addi r3, r5, 0 -; CHECK-NEXT: blr bb: %i = sext i32 %arg2 to i64 %i3 = icmp eq i32 %arg2, 0 @@ -595,17 +595,17 @@ define i64 @test_ds_cross_basic_blocks(ptr %arg, i32 signext %arg1) { ; CHECK-LABEL: test_ds_cross_basic_blocks: ; CHECK: # %bb.0: # %bb ; CHECK-NEXT: cmplwi r4, 0 -; CHECK-NEXT: beq cr0, .LBB6_9 +; CHECK-NEXT: std r28, -32(r1) # 8-byte Folded Spill +; CHECK-NEXT: std r29, -24(r1) # 8-byte Folded Spill +; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill +; CHECK-NEXT: beq cr0, .LBB6_8 ; CHECK-NEXT: # %bb.1: # %bb3 ; CHECK-NEXT: addis r5, r2, .LC0@toc@ha ; CHECK-NEXT: cmpldi r4, 1 ; CHECK-NEXT: li r7, 1 ; CHECK-NEXT: addi r6, r3, 4009 -; CHECK-NEXT: std r28, -32(r1) # 8-byte Folded Spill ; CHECK-NEXT: ld r5, .LC0@toc@l(r5) ; CHECK-NEXT: iselgt r3, r4, r7 -; CHECK-NEXT: std r29, -24(r1) # 8-byte Folded Spill -; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill ; CHECK-NEXT: li r4, -7 ; CHECK-NEXT: li r8, -6 ; CHECK-NEXT: li r9, 1 @@ -634,7 +634,7 @@ define i64 @test_ds_cross_basic_blocks(ptr %arg, i32 signext %arg1) { ; CHECK-NEXT: mulld r0, r0, r10 ; CHECK-NEXT: mulld r0, r0, r9 ; CHECK-NEXT: maddld r3, r0, r7, r3 -; CHECK-NEXT: bdz .LBB6_8 +; CHECK-NEXT: bdz .LBB6_9 ; CHECK-NEXT: .LBB6_4: # %bb5 ; CHECK-NEXT: # ; CHECK-NEXT: lbzu r0, 1(r5) @@ -666,13 +666,12 @@ define i64 @test_ds_cross_basic_blocks(ptr %arg, i32 signext %arg1) { ; CHECK-NEXT: add r7, r0, r7 ; CHECK-NEXT: b .LBB6_3 ; CHECK-NEXT: .LBB6_8: +; CHECK-NEXT: li r3, 0 +; CHECK-NEXT: .LBB6_9: # %bb64 ; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload ; CHECK-NEXT: ld r29, -24(r1) # 8-byte Folded Reload ; CHECK-NEXT: ld r28, -32(r1) # 8-byte Folded Reload ; CHECK-NEXT: blr -; CHECK-NEXT: .LBB6_9: -; CHECK-NEXT: li r3, 0 -; CHECK-NEXT: blr bb: %i = sext i32 %arg1 to i64 %i2 = icmp eq i32 %arg1, 0 diff --git a/llvm/test/CodeGen/PowerPC/lsr-profitable-chain.ll b/llvm/test/CodeGen/PowerPC/lsr-profitable-chain.ll index 79f2ef3e3746a..b91f20b710a2d 100644 --- a/llvm/test/CodeGen/PowerPC/lsr-profitable-chain.ll +++ b/llvm/test/CodeGen/PowerPC/lsr-profitable-chain.ll @@ -6,24 +6,24 @@ define void @foo(ptr readonly %0, ptr %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6 ; CHECK-LABEL: foo: ; CHECK: # %bb.0: ; CHECK-NEXT: cmpd 5, 7 -; CHECK-NEXT: bgelr 0 -; CHECK-NEXT: # %bb.1: # %.preheader +; CHECK-NEXT: std 22, -80(1) # 8-byte Folded Spill +; CHECK-NEXT: std 23, -72(1) # 8-byte Folded Spill +; CHECK-NEXT: std 24, -64(1) # 8-byte Folded Spill +; CHECK-NEXT: std 25, -56(1) # 8-byte Folded Spill +; CHECK-NEXT: std 26, -48(1) # 8-byte Folded Spill ; CHECK-NEXT: std 27, -40(1) # 8-byte Folded Spill -; CHECK-NEXT: addi 27, 5, 2 ; CHECK-NEXT: std 28, -32(1) # 8-byte Folded Spill -; CHECK-NEXT: addi 28, 5, 3 +; CHECK-NEXT: std 29, -24(1) # 8-byte Folded Spill ; CHECK-NEXT: std 30, -16(1) # 8-byte Folded Spill +; CHECK-NEXT: bge 0, .LBB0_6 +; CHECK-NEXT: # %bb.1: # %.preheader ; CHECK-NEXT: addi 30, 5, 1 +; CHECK-NEXT: addi 28, 5, 3 +; CHECK-NEXT: addi 27, 5, 2 ; CHECK-NEXT: mulld 12, 8, 5 -; CHECK-NEXT: mulld 0, 9, 8 -; CHECK-NEXT: std 29, -24(1) # 8-byte Folded Spill ; CHECK-NEXT: addi 29, 3, 16 +; CHECK-NEXT: mulld 0, 9, 8 ; CHECK-NEXT: sldi 11, 10, 3 -; CHECK-NEXT: std 22, -80(1) # 8-byte Folded Spill -; CHECK-NEXT: std 23, -72(1) # 8-byte Folded Spill -; CHECK-NEXT: std 24, -64(1) # 8-byte Folded Spill -; CHECK-NEXT: std 25, -56(1) # 8-byte Folded Spill -; CHECK-NEXT: std 26, -48(1) # 8-byte Folded Spill ; CHECK-NEXT: mulld 30, 8, 30 ; CHECK-NEXT: mulld 28, 8, 28 ; CHECK-NEXT: mulld 8, 8, 27 diff --git a/llvm/test/CodeGen/PowerPC/shrink-wrap.ll b/llvm/test/CodeGen/PowerPC/shrink-wrap.ll index 12d0b056ca886..08c391e34c6f4 100644 --- a/llvm/test/CodeGen/PowerPC/shrink-wrap.ll +++ b/llvm/test/CodeGen/PowerPC/shrink-wrap.ll @@ -7,9 +7,6 @@ define signext i32 @shrinkwrapme(i32 signext %a, i32 signext %lim) { ; POWERPC64-LABEL: shrinkwrapme: ; POWERPC64: # %bb.0: # %entry ; POWERPC64-NEXT: cmpwi 4, 0 -; POWERPC64-NEXT: ble 0, .LBB0_4 -; POWERPC64-NEXT: # %bb.1: # %for.body.preheader -; POWERPC64-NEXT: addi 4, 4, -1 ; POWERPC64-NEXT: std 14, -144(1) # 8-byte Folded Spill ; POWERPC64-NEXT: std 15, -136(1) # 8-byte Folded Spill ; POWERPC64-NEXT: std 16, -128(1) # 8-byte Folded Spill @@ -25,11 +22,14 @@ define signext i32 @shrinkwrapme(i32 signext %a, i32 signext %lim) { ; POWERPC64-NEXT: std 26, -48(1) # 8-byte Folded Spill ; POWERPC64-NEXT: std 27, -40(1) # 8-byte Folded Spill ; POWERPC64-NEXT: std 28, -32(1) # 8-byte Folded Spill -; POWERPC64-NEXT: clrldi 4, 4, 32 -; POWERPC64-NEXT: addi 4, 4, 1 ; POWERPC64-NEXT: std 29, -24(1) # 8-byte Folded Spill ; POWERPC64-NEXT: std 30, -16(1) # 8-byte Folded Spill ; POWERPC64-NEXT: std 31, -8(1) # 8-byte Folded Spill +; POWERPC64-NEXT: ble 0, .LBB0_3 +; POWERPC64-NEXT: # %bb.1: # %for.body.preheader +; POWERPC64-NEXT: addi 4, 4, -1 +; POWERPC64-NEXT: clrldi 4, 4, 32 +; POWERPC64-NEXT: addi 4, 4, 1 ; POWERPC64-NEXT: mtctr 4 ; POWERPC64-NEXT: li 4, 0 ; POWERPC64-NEXT: .p2align 4 @@ -39,7 +39,10 @@ define signext i32 @shrinkwrapme(i32 signext %a, i32 signext %lim) { ; POWERPC64-NEXT: add 4, 3, 4 ; POWERPC64-NEXT: #NO_APP ; POWERPC64-NEXT: bdnz .LBB0_2 -; POWERPC64-NEXT: # %bb.3: +; POWERPC64-NEXT: b .LBB0_4 +; POWERPC64-NEXT: .LBB0_3: +; POWERPC64-NEXT: li 4, 0 +; POWERPC64-NEXT: .LBB0_4: # %for.cond.cleanup ; POWERPC64-NEXT: ld 31, -8(1) # 8-byte Folded Reload ; POWERPC64-NEXT: ld 30, -16(1) # 8-byte Folded Reload ; POWERPC64-NEXT: ld 29, -24(1) # 8-byte Folded Reload @@ -60,16 +63,10 @@ define signext i32 @shrinkwrapme(i32 signext %a, i32 signext %lim) { ; POWERPC64-NEXT: ld 15, -136(1) # 8-byte Folded Reload ; POWERPC64-NEXT: ld 14, -144(1) # 8-byte Folded Reload ; POWERPC64-NEXT: blr -; POWERPC64-NEXT: .LBB0_4: -; POWERPC64-NEXT: li 4, 0 -; POWERPC64-NEXT: extsw 3, 4 -; POWERPC64-NEXT: blr ; ; POWERPC32-AIX-LABEL: shrinkwrapme: ; POWERPC32-AIX: # %bb.0: # %entry ; POWERPC32-AIX-NEXT: cmpwi 4, 0 -; POWERPC32-AIX-NEXT: ble 0, L..BB0_4 -; POWERPC32-AIX-NEXT: # %bb.1: # %for.body.preheader ; POWERPC32-AIX-NEXT: stw 14, -72(1) # 4-byte Folded Spill ; POWERPC32-AIX-NEXT: stw 15, -68(1) # 4-byte Folded Spill ; POWERPC32-AIX-NEXT: stw 16, -64(1) # 4-byte Folded Spill @@ -88,6 +85,8 @@ define signext i32 @shrinkwrapme(i32 signext %a, i32 signext %lim) { ; POWERPC32-AIX-NEXT: stw 29, -12(1) # 4-byte Folded Spill ; POWERPC32-AIX-NEXT: stw 30, -8(1) # 4-byte Folded Spill ; POWERPC32-AIX-NEXT: stw 31, -4(1) # 4-byte Folded Spill +; POWERPC32-AIX-NEXT: ble 0, L..BB0_3 +; POWERPC32-AIX-NEXT: # %bb.1: # %for.body.preheader ; POWERPC32-AIX-NEXT: mtctr 4 ; POWERPC32-AIX-NEXT: li 4, 0 ; POWERPC32-AIX-NEXT: .align 4 @@ -97,7 +96,10 @@ define signext i32 @shrinkwrapme(i32 signext %a, i32 signext %lim) { ; POWERPC32-AIX-NEXT: add 4, 3, 4 ; POWERPC32-AIX-NEXT: #NO_APP ; POWERPC32-AIX-NEXT: bdnz L..BB0_2 -; POWERPC32-AIX-NEXT: # %bb.3: +; POWERPC32-AIX-NEXT: b L..BB0_4 +; POWERPC32-AIX-NEXT: L..BB0_3: +; POWERPC32-AIX-NEXT: li 4, 0 +; POWERPC32-AIX-NEXT: L..BB0_4: # %for.cond.cleanup ; POWERPC32-AIX-NEXT: lwz 31, -4(1) # 4-byte Folded Reload ; POWERPC32-AIX-NEXT: lwz 30, -8(1) # 4-byte Folded Reload ; POWERPC32-AIX-NEXT: lwz 29, -12(1) # 4-byte Folded Reload @@ -118,16 +120,10 @@ define signext i32 @shrinkwrapme(i32 signext %a, i32 signext %lim) { ; POWERPC32-AIX-NEXT: lwz 15, -68(1) # 4-byte Folded Reload ; POWERPC32-AIX-NEXT: lwz 14, -72(1) # 4-byte Folded Reload ; POWERPC32-AIX-NEXT: blr -; POWERPC32-AIX-NEXT: L..BB0_4: -; POWERPC32-AIX-NEXT: li 3, 0 -; POWERPC32-AIX-NEXT: blr ; ; POWERPC64-AIX-LABEL: shrinkwrapme: ; POWERPC64-AIX: # %bb.0: # %entry ; POWERPC64-AIX-NEXT: cmpwi 4, 1 -; POWERPC64-AIX-NEXT: blt 0, L..BB0_4 -; POWERPC64-AIX-NEXT: # %bb.1: # %for.body.preheader -; POWERPC64-AIX-NEXT: addi 4, 4, -1 ; POWERPC64-AIX-NEXT: std 14, -144(1) # 8-byte Folded Spill ; POWERPC64-AIX-NEXT: std 15, -136(1) # 8-byte Folded Spill ; POWERPC64-AIX-NEXT: std 16, -128(1) # 8-byte Folded Spill @@ -143,11 +139,14 @@ define signext i32 @shrinkwrapme(i32 signext %a, i32 signext %lim) { ; POWERPC64-AIX-NEXT: std 26, -48(1) # 8-byte Folded Spill ; POWERPC64-AIX-NEXT: std 27, -40(1) # 8-byte Folded Spill ; POWERPC64-AIX-NEXT: std 28, -32(1) # 8-byte Folded Spill -; POWERPC64-AIX-NEXT: clrldi 4, 4, 32 -; POWERPC64-AIX-NEXT: addi 4, 4, 1 ; POWERPC64-AIX-NEXT: std 29, -24(1) # 8-byte Folded Spill ; POWERPC64-AIX-NEXT: std 30, -16(1) # 8-byte Folded Spill ; POWERPC64-AIX-NEXT: std 31, -8(1) # 8-byte Folded Spill +; POWERPC64-AIX-NEXT: blt 0, L..BB0_3 +; POWERPC64-AIX-NEXT: # %bb.1: # %for.body.preheader +; POWERPC64-AIX-NEXT: addi 4, 4, -1 +; POWERPC64-AIX-NEXT: clrldi 4, 4, 32 +; POWERPC64-AIX-NEXT: addi 4, 4, 1 ; POWERPC64-AIX-NEXT: mtctr 4 ; POWERPC64-AIX-NEXT: li 4, 0 ; POWERPC64-AIX-NEXT: .align 4 @@ -157,7 +156,10 @@ define signext i32 @shrinkwrapme(i32 signext %a, i32 signext %lim) { ; POWERPC64-AIX-NEXT: add 4, 3, 4 ; POWERPC64-AIX-NEXT: #NO_APP ; POWERPC64-AIX-NEXT: bdnz L..BB0_2 -; POWERPC64-AIX-NEXT: # %bb.3: +; POWERPC64-AIX-NEXT: b L..BB0_4 +; POWERPC64-AIX-NEXT: L..BB0_3: +; POWERPC64-AIX-NEXT: li 4, 0 +; POWERPC64-AIX-NEXT: L..BB0_4: # %for.cond.cleanup ; POWERPC64-AIX-NEXT: ld 31, -8(1) # 8-byte Folded Reload ; POWERPC64-AIX-NEXT: ld 30, -16(1) # 8-byte Folded Reload ; POWERPC64-AIX-NEXT: ld 29, -24(1) # 8-byte Folded Reload @@ -178,10 +180,6 @@ define signext i32 @shrinkwrapme(i32 signext %a, i32 signext %lim) { ; POWERPC64-AIX-NEXT: ld 15, -136(1) # 8-byte Folded Reload ; POWERPC64-AIX-NEXT: ld 14, -144(1) # 8-byte Folded Reload ; POWERPC64-AIX-NEXT: blr -; POWERPC64-AIX-NEXT: L..BB0_4: -; POWERPC64-AIX-NEXT: li 4, 0 -; POWERPC64-AIX-NEXT: extsw 3, 4 -; POWERPC64-AIX-NEXT: blr entry: %cmp5 = icmp sgt i32 %lim, 0 br i1 %cmp5, label %for.body.preheader, label %for.cond.cleanup diff --git a/llvm/test/CodeGen/PowerPC/shrink-wrap.mir b/llvm/test/CodeGen/PowerPC/shrink-wrap.mir index 561b193086bf5..1b6ccb92527e7 100644 --- a/llvm/test/CodeGen/PowerPC/shrink-wrap.mir +++ b/llvm/test/CodeGen/PowerPC/shrink-wrap.mir @@ -48,7 +48,42 @@ ... --- name: shrinkwrapme +alignment: 16 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false tracksRegLiveness: true +hasWinCFI: false +registers: [] +liveins: + - { reg: '$x3', virtual-reg: '' } + - { reg: '$x4', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: [] +callSites: [] +constants: [] +machineFunctionInfo: {} body: | ; CHECK-LABEL: name: shrinkwrapme ; CHECK: bb.0.entry: @@ -82,17 +117,11 @@ body: | ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $x3 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.4.for.body: - ; CHECK-NEXT: successors: %bb.4(0x7c000000), %bb.5(0x04000000) + ; CHECK-NEXT: successors: %bb.4(0x7c000000), %bb.3(0x04000000) ; CHECK-NEXT: liveins: $r4, $x3 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: INLINEASM &"add $0, $1, $2", 0 /* attdialect */, 131082 /* regdef:GPRC */, def renamable $r4, 131081 /* reguse:GPRC */, renamable $r3, 131081 /* reguse:GPRC */, killed renamable $r4, 12 /* clobber */, implicit-def dead early-clobber $r14, 12 /* clobber */, implicit-def dead early-clobber $r15, 12 /* clobber */, implicit-def dead early-clobber $r16, 12 /* clobber */, implicit-def dead early-clobber $r17, 12 /* clobber */, implicit-def dead early-clobber $r18, 12 /* clobber */, implicit-def dead early-clobber $r19, 12 /* clobber */, implicit-def dead early-clobber $r20, 12 /* clobber */, implicit-def dead early-clobber $r21, 12 /* clobber */, implicit-def dead early-clobber $r22, 12 /* clobber */, implicit-def dead early-clobber $r23, 12 /* clobber */, implicit-def dead early-clobber $r24, 12 /* clobber */, implicit-def dead early-clobber $r25, 12 /* clobber */, implicit-def dead early-clobber $r26, 12 /* clobber */, implicit-def dead early-clobber $r27, 12 /* clobber */, implicit-def dead early-clobber $r28, 12 /* clobber */, implicit-def dead early-clobber $r29, 12 /* clobber */, implicit-def dead early-clobber $r30, 12 /* clobber */, implicit-def dead early-clobber $r31 ; CHECK-NEXT: BDNZ8 %bb.4, implicit-def dead $ctr8, implicit $ctr8 - ; CHECK-NEXT: B %bb.5 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.5: - ; CHECK-NEXT: successors: %bb.3(0x80000000) - ; CHECK-NEXT: liveins: $r4 - ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: B %bb.3 bb.0.entry: successors: %bb.2(0x50000000), %bb.1(0x30000000) diff --git a/llvm/test/CodeGen/RISCV/aext-to-sext.ll b/llvm/test/CodeGen/RISCV/aext-to-sext.ll index 0aa04f40f6a52..806c495fa6777 100644 --- a/llvm/test/CodeGen/RISCV/aext-to-sext.ll +++ b/llvm/test/CodeGen/RISCV/aext-to-sext.ll @@ -11,22 +11,21 @@ define void @quux(i32 signext %arg, i32 signext %arg1) nounwind { ; RV64I-LABEL: quux: ; RV64I: # %bb.0: # %bb -; RV64I-NEXT: beq a0, a1, .LBB0_4 -; RV64I-NEXT: # %bb.1: # %bb2.preheader ; RV64I-NEXT: addi sp, sp, -16 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill +; RV64I-NEXT: beq a0, a1, .LBB0_3 +; RV64I-NEXT: # %bb.1: # %bb2.preheader ; RV64I-NEXT: subw s0, a1, a0 ; RV64I-NEXT: .LBB0_2: # %bb2 ; RV64I-NEXT: # =>This Inner Loop Header: Depth=1 ; RV64I-NEXT: call hoge@plt ; RV64I-NEXT: addiw s0, s0, -1 ; RV64I-NEXT: bnez s0, .LBB0_2 -; RV64I-NEXT: # %bb.3: +; RV64I-NEXT: .LBB0_3: # %bb6 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload ; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload ; RV64I-NEXT: addi sp, sp, 16 -; RV64I-NEXT: .LBB0_4: # %bb6 ; RV64I-NEXT: ret bb: %tmp = icmp eq i32 %arg, %arg1 diff --git a/llvm/test/CodeGen/RISCV/fli-licm.ll b/llvm/test/CodeGen/RISCV/fli-licm.ll index f37ace801b159..93bb934c1cb0d 100644 --- a/llvm/test/CodeGen/RISCV/fli-licm.ll +++ b/llvm/test/CodeGen/RISCV/fli-licm.ll @@ -12,11 +12,11 @@ define void @process_nodes(ptr %0) nounwind { ; RV32-LABEL: process_nodes: ; RV32: # %bb.0: # %entry -; RV32-NEXT: beqz a0, .LBB0_4 -; RV32-NEXT: # %bb.1: # %loop.preheader ; RV32-NEXT: addi sp, sp, -16 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-NEXT: beqz a0, .LBB0_3 +; RV32-NEXT: # %bb.1: # %loop.preheader ; RV32-NEXT: mv s0, a0 ; RV32-NEXT: .LBB0_2: # %loop ; RV32-NEXT: # =>This Inner Loop Header: Depth=1 @@ -25,20 +25,19 @@ define void @process_nodes(ptr %0) nounwind { ; RV32-NEXT: call do_it@plt ; RV32-NEXT: lw s0, 0(s0) ; RV32-NEXT: bnez s0, .LBB0_2 -; RV32-NEXT: # %bb.3: +; RV32-NEXT: .LBB0_3: # %exit ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload ; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload ; RV32-NEXT: addi sp, sp, 16 -; RV32-NEXT: .LBB0_4: # %exit ; RV32-NEXT: ret ; ; RV64-LABEL: process_nodes: ; RV64: # %bb.0: # %entry -; RV64-NEXT: beqz a0, .LBB0_4 -; RV64-NEXT: # %bb.1: # %loop.preheader ; RV64-NEXT: addi sp, sp, -16 ; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill ; RV64-NEXT: sd s0, 0(sp) # 8-byte Folded Spill +; RV64-NEXT: beqz a0, .LBB0_3 +; RV64-NEXT: # %bb.1: # %loop.preheader ; RV64-NEXT: mv s0, a0 ; RV64-NEXT: .LBB0_2: # %loop ; RV64-NEXT: # =>This Inner Loop Header: Depth=1 @@ -47,11 +46,10 @@ define void @process_nodes(ptr %0) nounwind { ; RV64-NEXT: call do_it@plt ; RV64-NEXT: ld s0, 0(s0) ; RV64-NEXT: bnez s0, .LBB0_2 -; RV64-NEXT: # %bb.3: +; RV64-NEXT: .LBB0_3: # %exit ; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload ; RV64-NEXT: ld s0, 0(sp) # 8-byte Folded Reload ; RV64-NEXT: addi sp, sp, 16 -; RV64-NEXT: .LBB0_4: # %exit ; RV64-NEXT: ret entry: %1 = icmp eq ptr %0, null diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/inlineasm.ll b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/inlineasm.ll index 421b5b5364d35..d67e66d7a7131 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/inlineasm.ll +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/inlineasm.ll @@ -4,13 +4,11 @@ define i32 @test(ptr nocapture readonly %x, ptr nocapture readonly %y, i32 %n) { ; CHECK-LABEL: test: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r2, #1 -; CHECK-NEXT: itt lt -; CHECK-NEXT: movlt r0, #0 -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB0_1: @ %for.body.preheader ; CHECK-NEXT: .save {r7, lr} ; CHECK-NEXT: push {r7, lr} +; CHECK-NEXT: cmp r2, #1 +; CHECK-NEXT: blt .LBB0_4 +; CHECK-NEXT: @ %bb.1: @ %for.body.preheader ; CHECK-NEXT: mov lr, r0 ; CHECK-NEXT: movs r0, #0 ; CHECK-NEXT: .LBB0_2: @ %for.body @@ -23,7 +21,10 @@ define i32 @test(ptr nocapture readonly %x, ptr nocapture readonly %y, i32 %n) { ; CHECK-NEXT: @NO_APP ; CHECK-NEXT: add r0, r3 ; CHECK-NEXT: bne .LBB0_2 -; CHECK-NEXT: @ %bb.3: +; CHECK-NEXT: @ %bb.3: @ %for.cond.cleanup +; CHECK-NEXT: pop {r7, pc} +; CHECK-NEXT: .LBB0_4: +; CHECK-NEXT: movs r0, #0 ; CHECK-NEXT: pop {r7, pc} entry: %cmp9 = icmp sgt i32 %n, 0 @@ -50,13 +51,11 @@ for.body: ; preds = %entry, %for.body define i32 @testlr(ptr nocapture readonly %x, ptr nocapture readonly %y, i32 %n) { ; CHECK-LABEL: testlr: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r2, #1 -; CHECK-NEXT: itt lt -; CHECK-NEXT: movlt r0, #0 -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB1_1: @ %for.body.preheader ; CHECK-NEXT: .save {r4, lr} ; CHECK-NEXT: push {r4, lr} +; CHECK-NEXT: cmp r2, #1 +; CHECK-NEXT: blt .LBB1_4 +; CHECK-NEXT: @ %bb.1: @ %for.body.preheader ; CHECK-NEXT: mov r3, r0 ; CHECK-NEXT: movs r0, #0 ; CHECK-NEXT: .LBB1_2: @ %for.body @@ -69,7 +68,10 @@ define i32 @testlr(ptr nocapture readonly %x, ptr nocapture readonly %y, i32 %n) ; CHECK-NEXT: @NO_APP ; CHECK-NEXT: add r0, r4 ; CHECK-NEXT: bne .LBB1_2 -; CHECK-NEXT: @ %bb.3: +; CHECK-NEXT: @ %bb.3: @ %for.cond.cleanup +; CHECK-NEXT: pop {r4, pc} +; CHECK-NEXT: .LBB1_4: +; CHECK-NEXT: movs r0, #0 ; CHECK-NEXT: pop {r4, pc} entry: %cmp9 = icmp sgt i32 %n, 0 diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/memcall.ll b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/memcall.ll index 59b32a3f441c1..99d169e63e5a5 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/memcall.ll +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/memcall.ll @@ -4,12 +4,11 @@ define void @test_memcpy(ptr nocapture %x, ptr nocapture readonly %y, i32 %n, i32 %m) { ; CHECK-LABEL: test_memcpy: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r2, #1 -; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB0_1: @ %for.body.preheader ; CHECK-NEXT: .save {r4, r5, r6, r7, lr} ; CHECK-NEXT: push {r4, r5, r6, r7, lr} +; CHECK-NEXT: cmp r2, #1 +; CHECK-NEXT: blt .LBB0_5 +; CHECK-NEXT: @ %bb.1: @ %for.body.preheader ; CHECK-NEXT: lsl.w r12, r3, #2 ; CHECK-NEXT: movs r7, #0 ; CHECK-NEXT: b .LBB0_2 @@ -32,9 +31,8 @@ define void @test_memcpy(ptr nocapture %x, ptr nocapture readonly %y, i32 %n, i3 ; CHECK-NEXT: vstrb.8 q0, [r5], #16 ; CHECK-NEXT: letp lr, .LBB0_4 ; CHECK-NEXT: b .LBB0_3 -; CHECK-NEXT: .LBB0_5: -; CHECK-NEXT: pop.w {r4, r5, r6, r7, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB0_5: @ %for.cond.cleanup +; CHECK-NEXT: pop {r4, r5, r6, r7, pc} entry: %cmp8 = icmp sgt i32 %n, 0 br i1 %cmp8, label %for.body, label %for.cond.cleanup @@ -57,12 +55,12 @@ for.body: ; preds = %entry, %for.body define void @test_memset(ptr nocapture %x, i32 %n, i32 %m) { ; CHECK-LABEL: test_memset: ; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: .save {r7, lr} +; CHECK-NEXT: push {r7, lr} ; CHECK-NEXT: cmp r1, #1 ; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr +; CHECK-NEXT: poplt {r7, pc} ; CHECK-NEXT: .LBB1_1: -; CHECK-NEXT: .save {r7, lr} -; CHECK-NEXT: push {r7, lr} ; CHECK-NEXT: vmov.i32 q0, #0x0 ; CHECK-NEXT: b .LBB1_2 ; CHECK-NEXT: .LBB1_2: @ %for.body @@ -82,9 +80,8 @@ define void @test_memset(ptr nocapture %x, i32 %n, i32 %m) { ; CHECK-NEXT: vstrb.8 q0, [r12], #16 ; CHECK-NEXT: letp lr, .LBB1_4 ; CHECK-NEXT: b .LBB1_3 -; CHECK-NEXT: .LBB1_5: -; CHECK-NEXT: pop.w {r7, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB1_5: @ %for.cond.cleanup +; CHECK-NEXT: pop {r7, pc} entry: %cmp5 = icmp sgt i32 %n, 0 br i1 %cmp5, label %for.body, label %for.cond.cleanup @@ -105,14 +102,13 @@ for.body: ; preds = %entry, %for.body define void @test_memmove(ptr nocapture %x, ptr nocapture readonly %y, i32 %n, i32 %m) { ; CHECK-LABEL: test_memmove: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r2, #1 -; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB2_1: @ %for.body.preheader ; CHECK-NEXT: .save {r4, r5, r6, r7, r8, r9, lr} ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9, lr} ; CHECK-NEXT: .pad #4 ; CHECK-NEXT: sub sp, #4 +; CHECK-NEXT: cmp r2, #1 +; CHECK-NEXT: blt .LBB2_3 +; CHECK-NEXT: @ %bb.1: @ %for.body.preheader ; CHECK-NEXT: mov r8, r3 ; CHECK-NEXT: mov r5, r2 ; CHECK-NEXT: mov r9, r1 @@ -128,10 +124,9 @@ define void @test_memmove(ptr nocapture %x, ptr nocapture readonly %y, i32 %n, i ; CHECK-NEXT: add r6, r4 ; CHECK-NEXT: subs r5, #1 ; CHECK-NEXT: bne .LBB2_2 -; CHECK-NEXT: @ %bb.3: +; CHECK-NEXT: .LBB2_3: @ %for.cond.cleanup ; CHECK-NEXT: add sp, #4 -; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9, pc} entry: %cmp8 = icmp sgt i32 %n, 0 br i1 %cmp8, label %for.body, label %for.cond.cleanup diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/mve-float-loops.ll b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/mve-float-loops.ll index 23eb5900bb7d1..13e39a8f16e33 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/mve-float-loops.ll +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/mve-float-loops.ll @@ -4,11 +4,10 @@ define arm_aapcs_vfpcc void @float_float_mul(ptr nocapture readonly %a, ptr nocapture readonly %b, ptr nocapture %c, i32 %N) { ; CHECK-LABEL: float_float_mul: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #0 -; CHECK-NEXT: it eq -; CHECK-NEXT: bxeq lr -; CHECK-NEXT: .LBB0_1: @ %for.body.preheader ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, lr} +; CHECK-NEXT: cmp r3, #0 +; CHECK-NEXT: beq .LBB0_10 +; CHECK-NEXT: @ %bb.1: @ %for.body.preheader ; CHECK-NEXT: cmp r3, #3 ; CHECK-NEXT: bhi .LBB0_3 ; CHECK-NEXT: @ %bb.2: @@ -81,9 +80,8 @@ define arm_aapcs_vfpcc void @float_float_mul(ptr nocapture readonly %a, ptr noca ; CHECK-NEXT: vmul.f32 s0, s2, s0 ; CHECK-NEXT: vstr s0, [r5, #12] ; CHECK-NEXT: bne .LBB0_9 -; CHECK-NEXT: .LBB0_10: -; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB0_10: @ %for.cond.cleanup +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, pc} ; CHECK-NEXT: .LBB0_11: @ %vector.ph ; CHECK-NEXT: bic r12, r3, #3 ; CHECK-NEXT: movs r6, #1 @@ -217,11 +215,10 @@ for.body: ; preds = %for.body.prol.loope define arm_aapcs_vfpcc void @float_float_add(ptr nocapture readonly %a, ptr nocapture readonly %b, ptr nocapture %c, i32 %N) { ; CHECK-LABEL: float_float_add: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #0 -; CHECK-NEXT: it eq -; CHECK-NEXT: bxeq lr -; CHECK-NEXT: .LBB1_1: @ %for.body.preheader ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, lr} +; CHECK-NEXT: cmp r3, #0 +; CHECK-NEXT: beq .LBB1_10 +; CHECK-NEXT: @ %bb.1: @ %for.body.preheader ; CHECK-NEXT: cmp r3, #3 ; CHECK-NEXT: bhi .LBB1_3 ; CHECK-NEXT: @ %bb.2: @@ -294,9 +291,8 @@ define arm_aapcs_vfpcc void @float_float_add(ptr nocapture readonly %a, ptr noca ; CHECK-NEXT: vadd.f32 s0, s2, s0 ; CHECK-NEXT: vstr s0, [r5, #12] ; CHECK-NEXT: bne .LBB1_9 -; CHECK-NEXT: .LBB1_10: -; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB1_10: @ %for.cond.cleanup +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, pc} ; CHECK-NEXT: .LBB1_11: @ %vector.ph ; CHECK-NEXT: bic r12, r3, #3 ; CHECK-NEXT: movs r6, #1 @@ -430,11 +426,10 @@ for.body: ; preds = %for.body.prol.loope define arm_aapcs_vfpcc void @float_float_sub(ptr nocapture readonly %a, ptr nocapture readonly %b, ptr nocapture %c, i32 %N) { ; CHECK-LABEL: float_float_sub: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #0 -; CHECK-NEXT: it eq -; CHECK-NEXT: bxeq lr -; CHECK-NEXT: .LBB2_1: @ %for.body.preheader ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, lr} +; CHECK-NEXT: cmp r3, #0 +; CHECK-NEXT: beq .LBB2_10 +; CHECK-NEXT: @ %bb.1: @ %for.body.preheader ; CHECK-NEXT: cmp r3, #3 ; CHECK-NEXT: bhi .LBB2_3 ; CHECK-NEXT: @ %bb.2: @@ -507,9 +502,8 @@ define arm_aapcs_vfpcc void @float_float_sub(ptr nocapture readonly %a, ptr noca ; CHECK-NEXT: vsub.f32 s0, s2, s0 ; CHECK-NEXT: vstr s0, [r5, #12] ; CHECK-NEXT: bne .LBB2_9 -; CHECK-NEXT: .LBB2_10: -; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB2_10: @ %for.cond.cleanup +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, pc} ; CHECK-NEXT: .LBB2_11: @ %vector.ph ; CHECK-NEXT: bic r12, r3, #3 ; CHECK-NEXT: movs r6, #1 @@ -643,11 +637,10 @@ for.body: ; preds = %for.body.prol.loope define arm_aapcs_vfpcc void @float_int_mul(ptr nocapture readonly %a, ptr nocapture readonly %b, ptr nocapture %c, i32 %N) { ; CHECK-LABEL: float_int_mul: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #0 -; CHECK-NEXT: it eq -; CHECK-NEXT: bxeq lr -; CHECK-NEXT: .LBB3_1: @ %for.body.preheader ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, lr} +; CHECK-NEXT: cmp r3, #0 +; CHECK-NEXT: beq.w .LBB3_13 +; CHECK-NEXT: @ %bb.1: @ %for.body.preheader ; CHECK-NEXT: cmp r3, #3 ; CHECK-NEXT: bls .LBB3_6 ; CHECK-NEXT: @ %bb.2: @ %vector.memcheck @@ -736,9 +729,8 @@ define arm_aapcs_vfpcc void @float_int_mul(ptr nocapture readonly %a, ptr nocapt ; CHECK-NEXT: vmul.f32 s0, s2, s0 ; CHECK-NEXT: vstr s0, [r6, #12] ; CHECK-NEXT: bne .LBB3_12 -; CHECK-NEXT: .LBB3_13: -; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB3_13: @ %for.cond.cleanup +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, pc} entry: %cmp8 = icmp eq i32 %N, 0 br i1 %cmp8, label %for.cond.cleanup, label %for.body.preheader diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/reductions.ll b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/reductions.ll index 93119eac2d564..eb98b85eafc90 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/reductions.ll +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/reductions.ll @@ -411,12 +411,10 @@ for.cond.cleanup: ; preds = %middle.block, %entr define dso_local arm_aapcs_vfpcc i32 @two_loops_mul_add_v4i32(i8* nocapture readonly %a, i8* nocapture readonly %b, i32 %N) local_unnamed_addr { ; CHECK-LABEL: two_loops_mul_add_v4i32: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r2, #0 -; CHECK-NEXT: itt eq -; CHECK-NEXT: moveq r0, #0 -; CHECK-NEXT: bxeq lr -; CHECK-NEXT: .LBB6_1: @ %vector.ph ; CHECK-NEXT: push {r4, r5, r6, r7, lr} +; CHECK-NEXT: cmp r2, #0 +; CHECK-NEXT: beq .LBB6_8 +; CHECK-NEXT: @ %bb.1: @ %vector.ph ; CHECK-NEXT: adds r3, r2, #3 ; CHECK-NEXT: vmov.i32 q1, #0x0 ; CHECK-NEXT: bic r3, r3, #3 @@ -463,10 +461,12 @@ define dso_local arm_aapcs_vfpcc i32 @two_loops_mul_add_v4i32(i8* nocapture read ; CHECK-NEXT: @ %bb.6: @ %middle.block44 ; CHECK-NEXT: vpsel q0, q0, q1 ; CHECK-NEXT: vaddv.u32 r12, q0 -; CHECK-NEXT: .LBB6_7: -; CHECK-NEXT: pop.w {r4, r5, r6, r7, lr} +; CHECK-NEXT: .LBB6_7: @ %for.cond.cleanup7 ; CHECK-NEXT: mov r0, r12 -; CHECK-NEXT: bx lr +; CHECK-NEXT: pop {r4, r5, r6, r7, pc} +; CHECK-NEXT: .LBB6_8: +; CHECK-NEXT: movs r0, #0 +; CHECK-NEXT: pop {r4, r5, r6, r7, pc} entry: %cmp35 = icmp eq i32 %N, 0 br i1 %cmp35, label %for.cond.cleanup7, label %vector.ph diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/sibling-loops.ll b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/sibling-loops.ll index 1f3a43923db61..caf7a339805fc 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/sibling-loops.ll +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/sibling-loops.ll @@ -4,11 +4,10 @@ define arm_aapcs_vfpcc void @test(ptr noalias nocapture readonly %off, ptr noalias nocapture %data, ptr noalias nocapture %dst, i32 %n) { ; CHECK-LABEL: test: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #1 -; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB0_1: @ %for.cond1.preheader.us.preheader ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, lr} +; CHECK-NEXT: cmp r3, #1 +; CHECK-NEXT: blt .LBB0_7 +; CHECK-NEXT: @ %bb.1: @ %for.cond1.preheader.us.preheader ; CHECK-NEXT: mov r8, r3 ; CHECK-NEXT: lsl.w r12, r3, #1 ; CHECK-NEXT: movs r3, #0 @@ -48,9 +47,8 @@ define arm_aapcs_vfpcc void @test(ptr noalias nocapture readonly %off, ptr noali ; CHECK-NEXT: add r4, r12 ; CHECK-NEXT: cmp r3, r8 ; CHECK-NEXT: bne .LBB0_2 -; CHECK-NEXT: @ %bb.7: -; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB0_7: @ %for.cond.cleanup +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, pc} entry: %cmp252 = icmp sgt i32 %n, 0 br i1 %cmp252, label %for.cond1.preheader.us, label %for.cond.cleanup diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/spillingmove.ll b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/spillingmove.ll index be1f1de71be3d..9ef5a46edf934 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/spillingmove.ll +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/spillingmove.ll @@ -5,19 +5,17 @@ define void @__arm_2d_impl_rgb16_colour_filling_with_alpha(ptr noalias nocapture %phwTargetBase, i16 signext %iTargetStride, ptr noalias nocapture readonly %ptCopySize, i16 zeroext %hwColour, i32 %chRatio) { ; CHECK-LABEL: __arm_2d_impl_rgb16_colour_filling_with_alpha: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: ldrsh.w r12, [r2, #2] -; CHECK-NEXT: cmp.w r12, #1 -; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB0_1: @ %for.cond3.preheader.lr.ph ; CHECK-NEXT: push {r4, r5, r6, r7, lr} ; CHECK-NEXT: sub sp, #4 ; CHECK-NEXT: vpush {d8, d9, d10, d11, d12, d13, d14, d15} ; CHECK-NEXT: sub sp, #64 -; CHECK-NEXT: ldrsh.w r7, [r2] -; CHECK-NEXT: cmp r7, #1 -; CHECK-NEXT: blt.w .LBB0_6 -; CHECK-NEXT: @ %bb.2: @ %for.cond3.preheader.us.preheader +; CHECK-NEXT: ldrsh.w r12, [r2, #2] +; CHECK-NEXT: cmp.w r12, #1 +; CHECK-NEXT: itt ge +; CHECK-NEXT: ldrshge.w r7, [r2] +; CHECK-NEXT: cmpge r7, #1 +; CHECK-NEXT: blt.w .LBB0_5 +; CHECK-NEXT: @ %bb.1: @ %for.cond3.preheader.us.preheader ; CHECK-NEXT: movs r2, #252 ; CHECK-NEXT: ldr r4, [sp, #152] ; CHECK-NEXT: and.w r6, r2, r3, lsr #3 @@ -48,14 +46,14 @@ define void @__arm_2d_impl_rgb16_colour_filling_with_alpha(ptr noalias nocapture ; CHECK-NEXT: vstrw.32 q0, [sp] @ 16-byte Spill ; CHECK-NEXT: vstrw.32 q2, [sp, #32] @ 16-byte Spill ; CHECK-NEXT: vstrw.32 q3, [sp, #16] @ 16-byte Spill -; CHECK-NEXT: .LBB0_3: @ %vector.ph +; CHECK-NEXT: .LBB0_2: @ %vector.ph ; CHECK-NEXT: @ =>This Loop Header: Depth=1 -; CHECK-NEXT: @ Child Loop BB0_4 Depth 2 +; CHECK-NEXT: @ Child Loop BB0_3 Depth 2 ; CHECK-NEXT: mov r5, r0 ; CHECK-NEXT: mov r6, r7 ; CHECK-NEXT: dls lr, r3 -; CHECK-NEXT: .LBB0_4: @ %vector.body -; CHECK-NEXT: @ Parent Loop BB0_3 Depth=1 +; CHECK-NEXT: .LBB0_3: @ %vector.body +; CHECK-NEXT: @ Parent Loop BB0_2 Depth=1 ; CHECK-NEXT: @ => This Inner Loop Header: Depth=2 ; CHECK-NEXT: vctp.16 r6 ; CHECK-NEXT: subs r6, #8 @@ -91,19 +89,18 @@ define void @__arm_2d_impl_rgb16_colour_filling_with_alpha(ptr noalias nocapture ; CHECK-NEXT: vorr q0, q1, q0 ; CHECK-NEXT: vpst ; CHECK-NEXT: vstrht.16 q0, [r5], #16 -; CHECK-NEXT: le lr, .LBB0_4 -; CHECK-NEXT: @ %bb.5: @ %for.cond3.for.cond.cleanup7_crit_edge.us -; CHECK-NEXT: @ in Loop: Header=BB0_3 Depth=1 +; CHECK-NEXT: le lr, .LBB0_3 +; CHECK-NEXT: @ %bb.4: @ %for.cond3.for.cond.cleanup7_crit_edge.us +; CHECK-NEXT: @ in Loop: Header=BB0_2 Depth=1 ; CHECK-NEXT: adds r4, #1 ; CHECK-NEXT: add.w r0, r0, r1, lsl #1 ; CHECK-NEXT: cmp r4, r12 -; CHECK-NEXT: bne .LBB0_3 -; CHECK-NEXT: .LBB0_6: +; CHECK-NEXT: bne .LBB0_2 +; CHECK-NEXT: .LBB0_5: @ %for.cond.cleanup ; CHECK-NEXT: add sp, #64 ; CHECK-NEXT: vpop {d8, d9, d10, d11, d12, d13, d14, d15} ; CHECK-NEXT: add sp, #4 -; CHECK-NEXT: pop.w {r4, r5, r6, r7, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: pop {r4, r5, r6, r7, pc} entry: %iHeight = getelementptr inbounds %struct.arm_2d_size_t, ptr %ptCopySize, i32 0, i32 1 %0 = load i16, ptr %iHeight, align 2 @@ -187,19 +184,18 @@ for.cond.cleanup: ; preds = %for.cond3.for.cond. define void @__arm_2d_impl_rgb16_colour_filling_with_alpha_sched(ptr noalias nocapture %phwTargetBase, i16 signext %iTargetStride, ptr noalias nocapture readonly %ptCopySize, i16 zeroext %hwColour, i32 %chRatio) "target-cpu"="cortex-m55" { ; CHECK-LABEL: __arm_2d_impl_rgb16_colour_filling_with_alpha_sched: ; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: push {r4, r5, r6, r7, lr} +; CHECK-NEXT: sub sp, #4 +; CHECK-NEXT: vpush {d8, d9, d10, d11, d12, d13, d14, d15} +; CHECK-NEXT: sub sp, #80 ; CHECK-NEXT: ldrsh.w r12, [r2, #2] ; CHECK-NEXT: cmp.w r12, #1 -; CHECK-NEXT: blt.w .LBB1_7 +; CHECK-NEXT: blt.w .LBB1_6 ; CHECK-NEXT: @ %bb.1: @ %for.cond3.preheader.lr.ph ; CHECK-NEXT: ldrsh.w r2, [r2] ; CHECK-NEXT: cmp r2, #1 -; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB1_2: @ %for.cond3.preheader.us.preheader -; CHECK-NEXT: push {r4, r5, r6, r7, lr} -; CHECK-NEXT: sub sp, #4 -; CHECK-NEXT: vpush {d8, d9, d10, d11, d12, d13, d14, d15} -; CHECK-NEXT: sub sp, #80 +; CHECK-NEXT: blt .LBB1_6 +; CHECK-NEXT: @ %bb.2: @ %for.cond3.preheader.us.preheader ; CHECK-NEXT: ldr r7, [sp, #168] ; CHECK-NEXT: movs r5, #120 ; CHECK-NEXT: lsls r6, r3, #3 @@ -269,13 +265,11 @@ define void @__arm_2d_impl_rgb16_colour_filling_with_alpha_sched(ptr noalias noc ; CHECK-NEXT: adds r4, #1 ; CHECK-NEXT: cmp r4, r12 ; CHECK-NEXT: bne .LBB1_3 -; CHECK-NEXT: @ %bb.6: +; CHECK-NEXT: .LBB1_6: @ %for.cond.cleanup ; CHECK-NEXT: add sp, #80 ; CHECK-NEXT: vpop {d8, d9, d10, d11, d12, d13, d14, d15} ; CHECK-NEXT: add sp, #4 -; CHECK-NEXT: pop.w {r4, r5, r6, r7, lr} -; CHECK-NEXT: .LBB1_7: @ %for.cond.cleanup -; CHECK-NEXT: bx lr +; CHECK-NEXT: pop {r4, r5, r6, r7, pc} entry: %iHeight = getelementptr inbounds %struct.arm_2d_size_t, ptr %ptCopySize, i32 0, i32 1 %0 = load i16, ptr %iHeight, align 2 diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while-loops.ll b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while-loops.ll index 3b42ee36e7c2e..fc58873f9857b 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while-loops.ll +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while-loops.ll @@ -53,12 +53,10 @@ if.end: ; preds = %do.body, %entry define void @nested(ptr nocapture readonly %x, ptr nocapture readnone %y, ptr nocapture %z, i32 %m, i32 %n) { ; CHECK-LABEL: nested: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #0 -; CHECK-NEXT: it eq -; CHECK-NEXT: bxeq lr -; CHECK-NEXT: .LBB1_1: @ %for.body.preheader ; CHECK-NEXT: .save {r4, r5, r6, r7, r8, lr} ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, lr} +; CHECK-NEXT: cbz r3, .LBB1_8 +; CHECK-NEXT: @ %bb.1: @ %for.body.preheader ; CHECK-NEXT: ldr.w r12, [sp, #24] ; CHECK-NEXT: movs r1, #0 ; CHECK-NEXT: b .LBB1_4 @@ -93,9 +91,8 @@ define void @nested(ptr nocapture readonly %x, ptr nocapture readnone %y, ptr no ; CHECK-NEXT: sub.w r12, r12, r5 ; CHECK-NEXT: mov r0, r8 ; CHECK-NEXT: b .LBB1_3 -; CHECK-NEXT: .LBB1_8: -; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB1_8: @ %for.cond.cleanup +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, pc} entry: %cmp20.not = icmp eq i32 %m, 0 br i1 %cmp20.not, label %for.cond.cleanup, label %for.body diff --git a/llvm/test/CodeGen/Thumb2/mve-float32regloops.ll b/llvm/test/CodeGen/Thumb2/mve-float32regloops.ll index b7b19a477ab0f..6228d616b5842 100644 --- a/llvm/test/CodeGen/Thumb2/mve-float32regloops.ll +++ b/llvm/test/CodeGen/Thumb2/mve-float32regloops.ll @@ -981,13 +981,6 @@ if.end61: ; preds = %if.then59, %while.e define void @fir(ptr nocapture readonly %S, ptr nocapture readonly %pSrc, ptr nocapture %pDst, i32 %blockSize) { ; CHECK-LABEL: fir: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #8 -; CHECK-NEXT: blo.w .LBB16_13 -; CHECK-NEXT: @ %bb.1: @ %if.then -; CHECK-NEXT: lsrs.w r12, r3, #2 -; CHECK-NEXT: it eq -; CHECK-NEXT: bxeq lr -; CHECK-NEXT: .LBB16_2: @ %while.body.lr.ph ; CHECK-NEXT: .save {r4, r5, r6, r7, r8, r9, r10, r11, lr} ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11, lr} ; CHECK-NEXT: .pad #4 @@ -996,6 +989,12 @@ define void @fir(ptr nocapture readonly %S, ptr nocapture readonly %pSrc, ptr no ; CHECK-NEXT: vpush {d8, d9, d10, d11, d12, d13} ; CHECK-NEXT: .pad #32 ; CHECK-NEXT: sub sp, #32 +; CHECK-NEXT: cmp r3, #8 +; CHECK-NEXT: blo.w .LBB16_12 +; CHECK-NEXT: @ %bb.1: @ %if.then +; CHECK-NEXT: lsrs.w r12, r3, #2 +; CHECK-NEXT: beq.w .LBB16_12 +; CHECK-NEXT: @ %bb.2: @ %while.body.lr.ph ; CHECK-NEXT: ldrh r6, [r0] ; CHECK-NEXT: movs r5, #1 ; CHECK-NEXT: ldrd r4, r10, [r0, #4] @@ -1107,13 +1106,11 @@ define void @fir(ptr nocapture readonly %S, ptr nocapture readonly %pSrc, ptr no ; CHECK-NEXT: ldr r0, [sp, #20] @ 4-byte Reload ; CHECK-NEXT: add.w r4, r4, r0, lsl #2 ; CHECK-NEXT: b .LBB16_4 -; CHECK-NEXT: .LBB16_12: +; CHECK-NEXT: .LBB16_12: @ %if.end ; CHECK-NEXT: add sp, #32 ; CHECK-NEXT: vpop {d8, d9, d10, d11, d12, d13} ; CHECK-NEXT: add sp, #4 -; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11, lr} -; CHECK-NEXT: .LBB16_13: @ %if.end -; CHECK-NEXT: bx lr +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11, pc} entry: %pState1 = getelementptr inbounds %struct.arm_fir_instance_f32, ptr %S, i32 0, i32 1 %i = load ptr, ptr %pState1, align 4 diff --git a/llvm/test/CodeGen/Thumb2/mve-gather-increment.ll b/llvm/test/CodeGen/Thumb2/mve-gather-increment.ll index 0335d24c0a782..24f1831a3f07c 100644 --- a/llvm/test/CodeGen/Thumb2/mve-gather-increment.ll +++ b/llvm/test/CodeGen/Thumb2/mve-gather-increment.ll @@ -290,12 +290,12 @@ end: define arm_aapcs_vfpcc void @gather_inc_v4i32_simple(ptr noalias nocapture readonly %data, ptr noalias nocapture %dst, i32 %n) { ; CHECK-LABEL: gather_inc_v4i32_simple: ; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: .save {r4, lr} +; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: cmp r2, #1 ; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr +; CHECK-NEXT: poplt {r4, pc} ; CHECK-NEXT: .LBB8_1: @ %vector.ph.preheader -; CHECK-NEXT: .save {r4, lr} -; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: bic r12, r2, #3 ; CHECK-NEXT: movs r3, #1 ; CHECK-NEXT: sub.w lr, r12, #4 @@ -319,9 +319,8 @@ define arm_aapcs_vfpcc void @gather_inc_v4i32_simple(ptr noalias nocapture reado ; CHECK-NEXT: @ in Loop: Header=BB8_2 Depth=1 ; CHECK-NEXT: cmp r12, r2 ; CHECK-NEXT: bne .LBB8_2 -; CHECK-NEXT: @ %bb.5: -; CHECK-NEXT: pop.w {r4, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: @ %bb.5: @ %for.cond.cleanup +; CHECK-NEXT: pop {r4, pc} ; CHECK-NEXT: .p2align 4 ; CHECK-NEXT: @ %bb.6: ; CHECK-NEXT: .LCPI8_0: @@ -360,14 +359,13 @@ for.cond.cleanup: ; preds = %for.body, %middle.b define arm_aapcs_vfpcc void @gather_inc_v4i32_complex(ptr noalias nocapture readonly %data, ptr noalias nocapture %dst, i32 %n) { ; CHECK-LABEL: gather_inc_v4i32_complex: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r2, #1 -; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB9_1: @ %vector.ph.preheader ; CHECK-NEXT: .save {r4, r5, r7, lr} ; CHECK-NEXT: push {r4, r5, r7, lr} ; CHECK-NEXT: .vsave {d8, d9, d10, d11, d12, d13, d14, d15} ; CHECK-NEXT: vpush {d8, d9, d10, d11, d12, d13, d14, d15} +; CHECK-NEXT: cmp r2, #1 +; CHECK-NEXT: blt .LBB9_5 +; CHECK-NEXT: @ %bb.1: @ %vector.ph.preheader ; CHECK-NEXT: bic r12, r2, #3 ; CHECK-NEXT: movs r3, #1 ; CHECK-NEXT: sub.w lr, r12, #4 @@ -403,10 +401,9 @@ define arm_aapcs_vfpcc void @gather_inc_v4i32_complex(ptr noalias nocapture read ; CHECK-NEXT: @ in Loop: Header=BB9_2 Depth=1 ; CHECK-NEXT: cmp r12, r2 ; CHECK-NEXT: bne .LBB9_2 -; CHECK-NEXT: @ %bb.5: +; CHECK-NEXT: .LBB9_5: @ %for.cond.cleanup ; CHECK-NEXT: vpop {d8, d9, d10, d11, d12, d13, d14, d15} -; CHECK-NEXT: pop.w {r4, r5, r7, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: pop {r4, r5, r7, pc} ; CHECK-NEXT: .p2align 4 ; CHECK-NEXT: @ %bb.6: ; CHECK-NEXT: .LCPI9_0: @@ -464,12 +461,12 @@ for.cond.cleanup: ; preds = %for.body, %middle.b define arm_aapcs_vfpcc void @gather_inc_v4i32_large(ptr noalias nocapture readonly %data, ptr noalias nocapture %dst, i32 %n) { ; CHECK-LABEL: gather_inc_v4i32_large: ; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: .save {r4, lr} +; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: cmp r2, #1 ; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr +; CHECK-NEXT: poplt {r4, pc} ; CHECK-NEXT: .LBB10_1: @ %vector.ph.preheader -; CHECK-NEXT: .save {r4, lr} -; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: bic r12, r2, #3 ; CHECK-NEXT: movs r3, #1 ; CHECK-NEXT: sub.w lr, r12, #4 @@ -493,9 +490,8 @@ define arm_aapcs_vfpcc void @gather_inc_v4i32_large(ptr noalias nocapture readon ; CHECK-NEXT: @ in Loop: Header=BB10_2 Depth=1 ; CHECK-NEXT: cmp r12, r2 ; CHECK-NEXT: bne .LBB10_2 -; CHECK-NEXT: @ %bb.5: -; CHECK-NEXT: pop.w {r4, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: @ %bb.5: @ %for.cond.cleanup +; CHECK-NEXT: pop {r4, pc} ; CHECK-NEXT: .p2align 4 ; CHECK-NEXT: @ %bb.6: ; CHECK-NEXT: .LCPI10_0: diff --git a/llvm/test/CodeGen/Thumb2/mve-gather-tailpred.ll b/llvm/test/CodeGen/Thumb2/mve-gather-tailpred.ll index ea186cd6ed2d4..9093b9af00656 100644 --- a/llvm/test/CodeGen/Thumb2/mve-gather-tailpred.ll +++ b/llvm/test/CodeGen/Thumb2/mve-gather-tailpred.ll @@ -4,12 +4,12 @@ define arm_aapcs_vfpcc void @gather_inc_v4i32_simple(ptr noalias nocapture readonly %data, ptr noalias nocapture %dst, i32 %n) { ; CHECK-LABEL: gather_inc_v4i32_simple: ; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: .save {r4, lr} +; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: cmp r2, #1 ; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr +; CHECK-NEXT: poplt {r4, pc} ; CHECK-NEXT: .LBB0_1: @ %vector.ph.preheader -; CHECK-NEXT: .save {r4, lr} -; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: bic r12, r2, #3 ; CHECK-NEXT: movs r3, #1 ; CHECK-NEXT: sub.w lr, r12, #4 @@ -33,9 +33,8 @@ define arm_aapcs_vfpcc void @gather_inc_v4i32_simple(ptr noalias nocapture reado ; CHECK-NEXT: @ in Loop: Header=BB0_2 Depth=1 ; CHECK-NEXT: cmp r12, r2 ; CHECK-NEXT: bne .LBB0_2 -; CHECK-NEXT: @ %bb.5: -; CHECK-NEXT: pop.w {r4, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: @ %bb.5: @ %for.cond.cleanup +; CHECK-NEXT: pop {r4, pc} ; CHECK-NEXT: .p2align 4 ; CHECK-NEXT: @ %bb.6: ; CHECK-NEXT: .LCPI0_0: diff --git a/llvm/test/CodeGen/Thumb2/mve-memtp-loop.ll b/llvm/test/CodeGen/Thumb2/mve-memtp-loop.ll index da59cb259db61..5f3a12711dc0f 100644 --- a/llvm/test/CodeGen/Thumb2/mve-memtp-loop.ll +++ b/llvm/test/CodeGen/Thumb2/mve-memtp-loop.ll @@ -211,12 +211,12 @@ entry: define void @test11(ptr nocapture %x, ptr nocapture %y, i32 %n) { ; CHECK-LABEL: test11: ; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: .save {r4, lr} +; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: cmp.w r2, #-1 ; CHECK-NEXT: it gt -; CHECK-NEXT: bxgt lr +; CHECK-NEXT: popgt {r4, pc} ; CHECK-NEXT: .LBB10_1: @ %prehead -; CHECK-NEXT: .save {r4, lr} -; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: mov r12, r1 ; CHECK-NEXT: mov r4, r0 ; CHECK-NEXT: wlstp.8 lr, r2, .LBB10_3 @@ -230,9 +230,8 @@ define void @test11(ptr nocapture %x, ptr nocapture %y, i32 %n) { ; CHECK-NEXT: subs r2, #2 ; CHECK-NEXT: strb r3, [r1], #1 ; CHECK-NEXT: bne .LBB10_3 -; CHECK-NEXT: @ %bb.4: -; CHECK-NEXT: pop.w {r4, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: @ %bb.4: @ %for.cond.cleanup +; CHECK-NEXT: pop {r4, pc} entry: %cmp6 = icmp slt i32 %n, 0 br i1 %cmp6, label %prehead, label %for.cond.cleanup @@ -441,12 +440,12 @@ declare void @other() define void @multilooped_exit(i32 %b) { ; CHECK-LABEL: multilooped_exit: ; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: .save {r4, lr} +; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: cmp r0, #1 ; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr +; CHECK-NEXT: poplt {r4, pc} ; CHECK-NEXT: .LBB18_1: @ %loop.preheader -; CHECK-NEXT: .save {r4, lr} -; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: mov.w r4, #-1 ; CHECK-NEXT: vmov.i32 q0, #0x0 ; CHECK-NEXT: b .LBB18_3 @@ -499,9 +498,8 @@ define void @multilooped_exit(i32 %b) { ; CHECK-NEXT: vstrb.8 q0, [r3], #16 ; CHECK-NEXT: letp lr, .LBB18_11 ; CHECK-NEXT: b .LBB18_2 -; CHECK-NEXT: .LBB18_12: -; CHECK-NEXT: pop.w {r4, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB18_12: @ %exit +; CHECK-NEXT: pop {r4, pc} entry: %cmp8 = icmp sgt i32 %b, 0 br i1 %cmp8, label %loop, label %exit diff --git a/llvm/test/CodeGen/Thumb2/mve-postinc-dct.ll b/llvm/test/CodeGen/Thumb2/mve-postinc-dct.ll index 45bb70ec44b73..7e059ae726fc6 100644 --- a/llvm/test/CodeGen/Thumb2/mve-postinc-dct.ll +++ b/llvm/test/CodeGen/Thumb2/mve-postinc-dct.ll @@ -6,14 +6,13 @@ define void @DCT_mve1(ptr nocapture readonly %S, ptr nocapture readonly %pIn, ptr nocapture %pOut) { ; CHECK-LABEL: DCT_mve1: ; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: .save {r4, r5, r6, r7, r8, r9, lr} +; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9, lr} ; CHECK-NEXT: ldr r3, [r0, #4] ; CHECK-NEXT: sub.w r12, r3, #1 ; CHECK-NEXT: cmp.w r12, #2 -; CHECK-NEXT: it lo -; CHECK-NEXT: bxlo lr -; CHECK-NEXT: .LBB0_1: @ %for.body.preheader -; CHECK-NEXT: .save {r4, r5, r6, r7, r8, r9, lr} -; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9, lr} +; CHECK-NEXT: blo .LBB0_5 +; CHECK-NEXT: @ %bb.1: @ %for.body.preheader ; CHECK-NEXT: ldr r5, [r0, #8] ; CHECK-NEXT: ldr r3, [r0] ; CHECK-NEXT: add.w r3, r3, r5, lsl #2 @@ -44,9 +43,8 @@ define void @DCT_mve1(ptr nocapture readonly %S, ptr nocapture readonly %pIn, pt ; CHECK-NEXT: vadd.f32 s0, s0, s2 ; CHECK-NEXT: vstr s0, [r7] ; CHECK-NEXT: bne .LBB0_2 -; CHECK-NEXT: @ %bb.5: -; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB0_5: @ %for.cond.cleanup +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9, pc} entry: %NumInputs = getelementptr inbounds %struct.DCT_InstanceTypeDef, ptr %S, i32 0, i32 2 %i = load i32, ptr %NumInputs, align 4 diff --git a/llvm/test/CodeGen/Thumb2/mve-scatter-increment.ll b/llvm/test/CodeGen/Thumb2/mve-scatter-increment.ll index 3a14e650bd53a..94397f0ae587b 100644 --- a/llvm/test/CodeGen/Thumb2/mve-scatter-increment.ll +++ b/llvm/test/CodeGen/Thumb2/mve-scatter-increment.ll @@ -127,16 +127,15 @@ define arm_aapcs_vfpcc void @scatter_inc_mini_16i8(<16 x i8> %data, ptr %dst, <1 define arm_aapcs_vfpcc void @scatter_inc_v4i32_complex(<4 x i32> %data1, <4 x i32> %data2, <4 x i32> %data3, ptr %dst, i32 %n) { ; CHECK-LABEL: scatter_inc_v4i32_complex: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r1, #1 -; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB3_1: @ %vector.ph.preheader ; CHECK-NEXT: .save {r4, lr} ; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: .vsave {d8, d9, d10, d11, d12, d13, d14, d15} ; CHECK-NEXT: vpush {d8, d9, d10, d11, d12, d13, d14, d15} ; CHECK-NEXT: .pad #16 ; CHECK-NEXT: sub sp, #16 +; CHECK-NEXT: cmp r1, #1 +; CHECK-NEXT: blt .LBB3_5 +; CHECK-NEXT: @ %bb.1: @ %vector.ph.preheader ; CHECK-NEXT: adr r4, .LCPI3_2 ; CHECK-NEXT: bic r2, r1, #3 ; CHECK-NEXT: vldrw.u32 q3, [r4] @@ -169,11 +168,10 @@ define arm_aapcs_vfpcc void @scatter_inc_v4i32_complex(<4 x i32> %data1, <4 x i3 ; CHECK-NEXT: @ in Loop: Header=BB3_2 Depth=1 ; CHECK-NEXT: cmp r2, r1 ; CHECK-NEXT: bne .LBB3_2 -; CHECK-NEXT: @ %bb.5: +; CHECK-NEXT: .LBB3_5: @ %for.cond.cleanup ; CHECK-NEXT: add sp, #16 ; CHECK-NEXT: vpop {d8, d9, d10, d11, d12, d13, d14, d15} -; CHECK-NEXT: pop.w {r4, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: pop {r4, pc} ; CHECK-NEXT: .p2align 4 ; CHECK-NEXT: @ %bb.6: ; CHECK-NEXT: .LCPI3_0: diff --git a/llvm/test/CodeGen/Thumb2/mve-tailpred-nonzerostart.ll b/llvm/test/CodeGen/Thumb2/mve-tailpred-nonzerostart.ll index 42a00b61b4183..85425db1eb6c8 100644 --- a/llvm/test/CodeGen/Thumb2/mve-tailpred-nonzerostart.ll +++ b/llvm/test/CodeGen/Thumb2/mve-tailpred-nonzerostart.ll @@ -58,12 +58,11 @@ for.cond.cleanup: ; preds = %vector.body, %entry define arm_aapcs_vfpcc void @start11(ptr nocapture readonly %x, ptr nocapture readonly %y, ptr noalias nocapture %z, float %a, i32 %n) { ; CHECK-LABEL: start11: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #1 -; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB1_1: @ %vector.ph ; CHECK-NEXT: .save {r4, r5, r7, lr} ; CHECK-NEXT: push {r4, r5, r7, lr} +; CHECK-NEXT: cmp r3, #1 +; CHECK-NEXT: blt .LBB1_3 +; CHECK-NEXT: @ %bb.1: @ %vector.ph ; CHECK-NEXT: vmov r12, s0 ; CHECK-NEXT: adds r4, r3, #3 ; CHECK-NEXT: adr r5, .LCPI1_0 @@ -86,9 +85,8 @@ define arm_aapcs_vfpcc void @start11(ptr nocapture readonly %x, ptr nocapture re ; CHECK-NEXT: vpst ; CHECK-NEXT: vstrwt.32 q3, [r2], #16 ; CHECK-NEXT: bne .LBB1_2 -; CHECK-NEXT: @ %bb.3: -; CHECK-NEXT: pop.w {r4, r5, r7, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: .LBB1_3: @ %for.cond.cleanup +; CHECK-NEXT: pop {r4, r5, r7, pc} ; CHECK-NEXT: .p2align 4 ; CHECK-NEXT: @ %bb.4: ; CHECK-NEXT: .LCPI1_0: diff --git a/llvm/test/CodeGen/Thumb2/mve-vmull-loop.ll b/llvm/test/CodeGen/Thumb2/mve-vmull-loop.ll index 0a26d9920981b..da0cd57d86dbb 100644 --- a/llvm/test/CodeGen/Thumb2/mve-vmull-loop.ll +++ b/llvm/test/CodeGen/Thumb2/mve-vmull-loop.ll @@ -4,13 +4,11 @@ define arm_aapcs_vfpcc void @test32(ptr noalias nocapture readonly %x, ptr noalias nocapture readonly %y, ptr nocapture %z, i32 %n) { ; CHECK-LABEL: test32: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: cmp r3, #1 -; CHECK-NEXT: it lt -; CHECK-NEXT: bxlt lr -; CHECK-NEXT: .LBB0_1: @ %vector.body.preheader ; CHECK-NEXT: .save {r4, r5, r7, lr} ; CHECK-NEXT: push {r4, r5, r7, lr} -; CHECK-NEXT: .LBB0_2: @ %vector.body +; CHECK-NEXT: cmp r3, #1 +; CHECK-NEXT: blt .LBB0_2 +; CHECK-NEXT: .LBB0_1: @ %vector.body ; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: vldrw.u32 q0, [r0], #16 ; CHECK-NEXT: vldrw.u32 q1, [r1], #16 @@ -28,10 +26,9 @@ define arm_aapcs_vfpcc void @test32(ptr noalias nocapture readonly %x, ptr noali ; CHECK-NEXT: lsrl r4, r5, #31 ; CHECK-NEXT: vmov q2[3], q2[1], r4, r12 ; CHECK-NEXT: vstrb.8 q2, [r2], #16 -; CHECK-NEXT: bne .LBB0_2 -; CHECK-NEXT: @ %bb.3: -; CHECK-NEXT: pop.w {r4, r5, r7, lr} -; CHECK-NEXT: bx lr +; CHECK-NEXT: bne .LBB0_1 +; CHECK-NEXT: .LBB0_2: @ %for.cond.cleanup +; CHECK-NEXT: pop {r4, r5, r7, pc} entry: %0 = and i32 %n, 3 %cmp = icmp eq i32 %0, 0 diff --git a/llvm/test/CodeGen/X86/fold-call-3.ll b/llvm/test/CodeGen/X86/fold-call-3.ll index 691f46b9eeb0e..9c9a50d3e9ce1 100644 --- a/llvm/test/CodeGen/X86/fold-call-3.ll +++ b/llvm/test/CodeGen/X86/fold-call-3.ll @@ -13,12 +13,12 @@ define void @_Z25RawPointerPerformanceTestPvRN5clang6ActionE(ptr %Val, ptr %Actions) nounwind { ; CHECK-LABEL: _Z25RawPointerPerformanceTestPvRN5clang6ActionE: ; CHECK: ## %bb.0: ## %entry -; CHECK-NEXT: cmpl $0, _NumTrials(%rip) -; CHECK-NEXT: je LBB0_4 -; CHECK-NEXT: ## %bb.1: ## %bb.nph ; CHECK-NEXT: pushq %rbp ; CHECK-NEXT: pushq %rbx ; CHECK-NEXT: subq $24, %rsp +; CHECK-NEXT: cmpl $0, _NumTrials(%rip) +; CHECK-NEXT: je LBB0_3 +; CHECK-NEXT: ## %bb.1: ## %bb.nph ; CHECK-NEXT: movq %rsi, %rbx ; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: xorl %ebp, %ebp @@ -34,21 +34,20 @@ define void @_Z25RawPointerPerformanceTestPvRN5clang6ActionE(ptr %Val, ptr %Acti ; CHECK-NEXT: incl %ebp ; CHECK-NEXT: cmpl _NumTrials(%rip), %ebp ; CHECK-NEXT: jb LBB0_2 -; CHECK-NEXT: ## %bb.3: +; CHECK-NEXT: LBB0_3: ## %return ; CHECK-NEXT: addq $24, %rsp ; CHECK-NEXT: popq %rbx ; CHECK-NEXT: popq %rbp -; CHECK-NEXT: LBB0_4: ## %return ; CHECK-NEXT: retq ; ; pre-RA-LABEL: _Z25RawPointerPerformanceTestPvRN5clang6ActionE: ; pre-RA: ## %bb.0: ## %entry -; pre-RA-NEXT: cmpl $0, _NumTrials(%rip) -; pre-RA-NEXT: je LBB0_4 -; pre-RA-NEXT: ## %bb.1: ## %bb.nph ; pre-RA-NEXT: pushq %rbp ; pre-RA-NEXT: pushq %rbx ; pre-RA-NEXT: subq $24, %rsp +; pre-RA-NEXT: cmpl $0, _NumTrials(%rip) +; pre-RA-NEXT: je LBB0_3 +; pre-RA-NEXT: ## %bb.1: ## %bb.nph ; pre-RA-NEXT: movq %rsi, %rbx ; pre-RA-NEXT: movq %rdi, %rax ; pre-RA-NEXT: xorl %ebp, %ebp @@ -64,11 +63,10 @@ define void @_Z25RawPointerPerformanceTestPvRN5clang6ActionE(ptr %Val, ptr %Acti ; pre-RA-NEXT: movq %rdx, {{[0-9]+}}(%rsp) ; pre-RA-NEXT: cmpl _NumTrials(%rip), %ebp ; pre-RA-NEXT: jb LBB0_2 -; pre-RA-NEXT: ## %bb.3: +; pre-RA-NEXT: LBB0_3: ## %return ; pre-RA-NEXT: addq $24, %rsp ; pre-RA-NEXT: popq %rbx ; pre-RA-NEXT: popq %rbp -; pre-RA-NEXT: LBB0_4: ## %return ; pre-RA-NEXT: retq entry: %i = alloca %"struct.clang::ActionBase::ActionResult<0u>", align 8 diff --git a/llvm/test/CodeGen/X86/negative-stride-fptosi-user.ll b/llvm/test/CodeGen/X86/negative-stride-fptosi-user.ll index d0d46b5f11836..e21d4de178719 100644 --- a/llvm/test/CodeGen/X86/negative-stride-fptosi-user.ll +++ b/llvm/test/CodeGen/X86/negative-stride-fptosi-user.ll @@ -9,14 +9,12 @@ define void @foo(i32 %N) nounwind { ; CHECK-LABEL: foo: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: js .LBB0_1 -; CHECK-NEXT: # %bb.4: # %return -; CHECK-NEXT: retq -; CHECK-NEXT: .LBB0_1: # %bb.preheader ; CHECK-NEXT: pushq %rbp ; CHECK-NEXT: pushq %rbx ; CHECK-NEXT: pushq %rax +; CHECK-NEXT: testl %edi, %edi +; CHECK-NEXT: jns .LBB0_3 +; CHECK-NEXT: # %bb.1: # %bb.preheader ; CHECK-NEXT: movl %edi, %ebx ; CHECK-NEXT: xorl %ebp, %ebp ; CHECK-NEXT: .p2align 4, 0x90 @@ -28,7 +26,7 @@ define void @foo(i32 %N) nounwind { ; CHECK-NEXT: decl %ebp ; CHECK-NEXT: cmpl %ebp, %ebx ; CHECK-NEXT: jne .LBB0_2 -; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: .LBB0_3: # %return ; CHECK-NEXT: addq $8, %rsp ; CHECK-NEXT: popq %rbx ; CHECK-NEXT: popq %rbp diff --git a/llvm/test/CodeGen/X86/pr44412.ll b/llvm/test/CodeGen/X86/pr44412.ll index 67579a5bb7c52..6c33666fb5c3a 100644 --- a/llvm/test/CodeGen/X86/pr44412.ll +++ b/llvm/test/CodeGen/X86/pr44412.ll @@ -4,10 +4,10 @@ define void @bar(i32 %0, i32 %1) nounwind { ; CHECK-LABEL: bar: ; CHECK: # %bb.0: +; CHECK-NEXT: pushq %rbx ; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: je .LBB0_4 +; CHECK-NEXT: je .LBB0_3 ; CHECK-NEXT: # %bb.1: # %.preheader -; CHECK-NEXT: pushq %rbx ; CHECK-NEXT: movl %edi, %ebx ; CHECK-NEXT: decl %ebx ; CHECK-NEXT: .p2align 4, 0x90 @@ -16,9 +16,8 @@ define void @bar(i32 %0, i32 %1) nounwind { ; CHECK-NEXT: callq foo@PLT ; CHECK-NEXT: addl $-1, %ebx ; CHECK-NEXT: jb .LBB0_2 -; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: .LBB0_3: ; CHECK-NEXT: popq %rbx -; CHECK-NEXT: .LBB0_4: ; CHECK-NEXT: retq %3 = icmp eq i32 %0, 0 br i1 %3, label %8, label %4 @@ -37,10 +36,10 @@ define void @bar(i32 %0, i32 %1) nounwind { define void @baz(i32 %0, i32 %1) nounwind { ; CHECK-LABEL: baz: ; CHECK: # %bb.0: +; CHECK-NEXT: pushq %rbx ; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: je .LBB1_4 +; CHECK-NEXT: je .LBB1_3 ; CHECK-NEXT: # %bb.1: # %.preheader -; CHECK-NEXT: pushq %rbx ; CHECK-NEXT: movl %edi, %ebx ; CHECK-NEXT: decl %ebx ; CHECK-NEXT: .p2align 4, 0x90 @@ -49,9 +48,8 @@ define void @baz(i32 %0, i32 %1) nounwind { ; CHECK-NEXT: callq foo@PLT ; CHECK-NEXT: addl $-1, %ebx ; CHECK-NEXT: jae .LBB1_2 -; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: .LBB1_3: ; CHECK-NEXT: popq %rbx -; CHECK-NEXT: .LBB1_4: ; CHECK-NEXT: retq %3 = icmp eq i32 %0, 0 br i1 %3, label %8, label %4 diff --git a/llvm/test/CodeGen/X86/x86-shrink-wrapping.ll b/llvm/test/CodeGen/X86/x86-shrink-wrapping.ll index f22ea739092f6..ec4a12eadb94e 100644 --- a/llvm/test/CodeGen/X86/x86-shrink-wrapping.ll +++ b/llvm/test/CodeGen/X86/x86-shrink-wrapping.ll @@ -639,40 +639,40 @@ declare hidden fastcc ptr @find_temp_slot_from_address(ptr readonly) define void @useLEA(ptr readonly %x) { ; ENABLE-LABEL: useLEA: ; ENABLE: ## %bb.0: ## %entry +; ENABLE-NEXT: pushq %rax +; ENABLE-NEXT: .cfi_def_cfa_offset 16 ; ENABLE-NEXT: testq %rdi, %rdi -; ENABLE-NEXT: je LBB8_9 +; ENABLE-NEXT: je LBB8_7 ; ENABLE-NEXT: ## %bb.1: ## %if.end ; ENABLE-NEXT: cmpw $66, (%rdi) -; ENABLE-NEXT: jne LBB8_9 +; ENABLE-NEXT: jne LBB8_7 ; ENABLE-NEXT: ## %bb.2: ## %lor.lhs.false -; ENABLE-NEXT: pushq %rax -; ENABLE-NEXT: .cfi_def_cfa_offset 16 ; ENABLE-NEXT: movq 8(%rdi), %rdi ; ENABLE-NEXT: movzwl (%rdi), %eax ; ENABLE-NEXT: leal -54(%rax), %ecx ; ENABLE-NEXT: cmpl $14, %ecx ; ENABLE-NEXT: ja LBB8_3 -; ENABLE-NEXT: ## %bb.7: ## %lor.lhs.false +; ENABLE-NEXT: ## %bb.8: ## %lor.lhs.false ; ENABLE-NEXT: movl $24599, %edx ## imm = 0x6017 ; ENABLE-NEXT: btl %ecx, %edx ; ENABLE-NEXT: jae LBB8_3 -; ENABLE-NEXT: LBB8_8: -; ENABLE-NEXT: addq $8, %rsp -; ENABLE-NEXT: LBB8_9: ## %cleanup +; ENABLE-NEXT: LBB8_7: ## %cleanup +; ENABLE-NEXT: popq %rax ; ENABLE-NEXT: retq ; ENABLE-NEXT: LBB8_3: ## %lor.lhs.false ; ENABLE-NEXT: cmpl $134, %eax -; ENABLE-NEXT: je LBB8_8 +; ENABLE-NEXT: je LBB8_7 ; ENABLE-NEXT: ## %bb.4: ## %lor.lhs.false ; ENABLE-NEXT: cmpl $140, %eax -; ENABLE-NEXT: je LBB8_8 +; ENABLE-NEXT: je LBB8_7 ; ENABLE-NEXT: ## %bb.5: ## %if.end.55 ; ENABLE-NEXT: callq _find_temp_slot_from_address ; ENABLE-NEXT: testq %rax, %rax -; ENABLE-NEXT: je LBB8_8 +; ENABLE-NEXT: je LBB8_7 ; ENABLE-NEXT: ## %bb.6: ## %if.then.60 ; ENABLE-NEXT: movb $1, 57(%rax) -; ENABLE-NEXT: jmp LBB8_8 +; ENABLE-NEXT: popq %rax +; ENABLE-NEXT: retq ; ; DISABLE-LABEL: useLEA: ; DISABLE: ## %bb.0: ## %entry diff --git a/llvm/test/Transforms/LoopStrengthReduce/AArch64/pr53625.ll b/llvm/test/Transforms/LoopStrengthReduce/AArch64/pr53625.ll index 536f9912f1b6f..2069e974c6905 100644 --- a/llvm/test/Transforms/LoopStrengthReduce/AArch64/pr53625.ll +++ b/llvm/test/Transforms/LoopStrengthReduce/AArch64/pr53625.ll @@ -23,7 +23,7 @@ define i32 @test(i32 %c, ptr %a, ptr %b) { ; CHECK-NEXT: mov w0, wzr ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB0_5: -; CHECK-NEXT: mov w0, #1 // =0x1 +; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: ret entry: %cmp13 = icmp sgt i32 %c, 0 @@ -62,7 +62,7 @@ define i64 @IVIncHoist_not_all_user_in_header(i32 %c, ptr %a, ptr %b) { ; CHECK-NEXT: mov w9, w0 ; CHECK-NEXT: add x10, x1, #4 ; CHECK-NEXT: add x11, x2, #8 -; CHECK-NEXT: mov w0, #1 // =0x1 +; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: .LBB1_2: // %for.body ; CHECK-NEXT: // =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ldr w12, [x10, x8, lsl #2] @@ -142,7 +142,7 @@ define i32 @negative_test_type_is_struct(i32 %c, ptr %a, ptr %b) { ; CHECK-NEXT: mov w0, wzr ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB2_5: -; CHECK-NEXT: mov w0, #1 // =0x1 +; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: ret entry: %cmp13 = icmp sgt i32 %c, 0 diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll index 63a3c725ae89e..fa1c208ffbd77 100644 --- a/llvm/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll +++ b/llvm/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll @@ -182,12 +182,12 @@ exit: define void @extrastride(i8* nocapture %main, i32 %main_stride, i32* nocapture %res, i32 %x, i32 %y, i32 %z) nounwind { ; X64-LABEL: extrastride: ; X64: # %bb.0: # %entry +; X64-NEXT: pushq %rbx ; X64-NEXT: # kill: def $ecx killed $ecx def $rcx ; X64-NEXT: # kill: def $esi killed $esi def $rsi ; X64-NEXT: testl %r9d, %r9d -; X64-NEXT: je .LBB2_4 +; X64-NEXT: je .LBB2_3 ; X64-NEXT: # %bb.1: # %for.body.lr.ph -; X64-NEXT: pushq %rbx ; X64-NEXT: leal (%rsi,%rsi), %r10d ; X64-NEXT: leal (%rsi,%rsi,2), %r11d ; X64-NEXT: addl %esi, %ecx @@ -213,9 +213,8 @@ define void @extrastride(i8* nocapture %main, i32 %main_stride, i32* nocapture % ; X64-NEXT: addq %r8, %rdx ; X64-NEXT: decl %r9d ; X64-NEXT: jne .LBB2_2 -; X64-NEXT: # %bb.3: +; X64-NEXT: .LBB2_3: # %for.end ; X64-NEXT: popq %rbx -; X64-NEXT: .LBB2_4: # %for.end ; X64-NEXT: retq ; ; X32-LABEL: extrastride: From 15593613769f767e78310b08e57b0a93dda6643e Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 8 May 2023 11:03:40 -0700 Subject: [PATCH 015/608] [NFC][ASAN] Hide placeholder buffer --- compiler-rt/lib/asan/asan_thread.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp index 8d4b5c80f76ec..a1734a6f896da 100644 --- a/compiler-rt/lib/asan/asan_thread.cpp +++ b/compiler-rt/lib/asan/asan_thread.cpp @@ -40,11 +40,7 @@ void AsanThreadContext::OnFinished() { thread = nullptr; } -// MIPS requires aligned address -static ALIGNED(alignof( - ThreadRegistry)) char thread_registry_placeholder[sizeof(ThreadRegistry)]; static ThreadRegistry *asan_thread_registry; - static Mutex mu_for_thread_context; static LowLevelAllocator allocator_for_thread_context; @@ -63,6 +59,11 @@ static void InitThreads() { // in TSD and can't reliably tell when no more TSD destructors will // be called. It would be wrong to reuse AsanThreadContext for another // thread before all TSD destructors will be called for it. + + // MIPS requires aligned address + static ALIGNED(alignof( + ThreadRegistry)) char thread_registry_placeholder[sizeof(ThreadRegistry)]; + asan_thread_registry = new (thread_registry_placeholder) ThreadRegistry(GetAsanThreadContext); initialized = true; From 6fe46219631fda60e2dc25ca285f30957ba6d3c7 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 8 May 2023 15:24:33 -0700 Subject: [PATCH 016/608] [NFC][HWASAN] Use InternalAlloc for ThreadStartArg --- compiler-rt/lib/hwasan/hwasan_interceptors.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp index 3854ad62f41a2..096bfe5b1864f 100644 --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp @@ -53,7 +53,7 @@ static void *HwasanThreadStartFunc(void *arg) { __hwasan_thread_enter(); ThreadStartArg A = *reinterpret_cast(arg); SetSigProcMask(&A.starting_sigset_, nullptr); - UnmapOrDie(arg, GetPageSizeCached()); + InternalFree(arg); return A.callback(A.param); } @@ -61,8 +61,7 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void *), void *param) { EnsureMainThreadIDIsCorrect(); ScopedTaggingDisabler tagging_disabler; - ThreadStartArg *A = reinterpret_cast( - MmapOrDie(GetPageSizeCached(), "pthread_create")); + ThreadStartArg *A = (ThreadStartArg *)InternalAlloc(sizeof(ThreadStartArg)); A->callback = callback; A->param = param; ScopedBlockSignals block(&A->starting_sigset_); @@ -70,7 +69,10 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, # if CAN_SANITIZE_LEAKS __lsan::ScopedInterceptorDisabler lsan_disabler; # endif - return REAL(pthread_create)(th, attr, &HwasanThreadStartFunc, A); + int result = REAL(pthread_create)(th, attr, &HwasanThreadStartFunc, A); + if (result != 0) + InternalFree(A); + return result; } INTERCEPTOR(int, pthread_join, void *t, void **arg) { From c8b50b860068bb9116c17ad3d8b616285eb68c71 Mon Sep 17 00:00:00 2001 From: Slava Zakharin Date: Mon, 8 May 2023 16:21:14 -0700 Subject: [PATCH 017/608] [flang] Prevent character length setting with dangling ac-do-variable. This fixes LEN inquiry on array constructors where the length expression includes references to the ac-do-variable. Reviewed By: klausler Differential Revision: https://reviews.llvm.org/D150149 --- flang/lib/Semantics/expression.cpp | 15 ++++++++++++++- flang/test/Evaluate/rewrite01.f90 | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 1440147feecdf..6047f8da441b1 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -1475,7 +1475,20 @@ class ArrayConstructorContext { ArrayConstructor result{MakeSpecific(std::move(values_))}; if constexpr (T::category == TypeCategory::Character) { if (auto len{type_->LEN()}) { - if (IsConstantExpr(*len)) { + // The ac-do-variables may be treated as constant expressions, + // if some conditions on ac-implied-do-control hold (10.1.12 (12)). + // At the same time, they may be treated as constant expressions + // only in the context of the ac-implied-do, but setting + // the character length here may result in complete elimination + // of the ac-implied-do. For example: + // character(10) :: c + // ... len([(c(i:i), integer(8)::i = 1,4)]) + // would be evaulated into: + // ... int(max(0_8,i-i+1_8),kind=4) + // with a dangling reference to the ac-do-variable. + // Prevent this by checking for the ac-do-variable references + // in the 'len' expression. + if (!ContainsAnyImpliedDoIndex(*len) && IsConstantExpr(*len)) { result.set_LEN(std::move(*len)); } } diff --git a/flang/test/Evaluate/rewrite01.f90 b/flang/test/Evaluate/rewrite01.f90 index cbcbfb97189c7..0fa3581a3799f 100644 --- a/flang/test/Evaluate/rewrite01.f90 +++ b/flang/test/Evaluate/rewrite01.f90 @@ -234,10 +234,13 @@ function return_allocatable() subroutine array_ctor_implied_do_index(x, j) integer :: x(:) integer(8) :: j + character(10) :: c !CHECK: PRINT *, size([INTEGER(4)::(x(1_8:i:1_8),INTEGER(8)::i=1_8,2_8,1_8)]) print *, size([(x(1:i), integer(8)::i=1,2)]) !CHECK: PRINT *, int(0_8+2_8*(0_8+max((j-1_8+1_8)/1_8,0_8)),kind=4) print *, size([(x(1:j), integer(8)::i=1,2)]) + !CHECK: PRINT *, len([(c(i:i),INTEGER(8)::i=1_8,4_8,1_8)]) + print *, len([(c(i:i), integer(8)::i = 1,4)]) end subroutine end module From 971d982bd45c3c3544dcf8d1e67df39e8c063877 Mon Sep 17 00:00:00 2001 From: Pierre Calixte Date: Tue, 9 May 2023 00:03:35 +0000 Subject: [PATCH 018/608] Do not optimize debug locations across section boundaries Prevent optimization of DebugLoc across section boundaries, such optimization will yield incorrect source location if memory layout of sections does not strictly match the Asm file. Reviewed By: #debug-info, dblaikie, MaskRay Differential Revision: https://reviews.llvm.org/D149294 --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 5 ++- ...ions-debug-lineinfo-at-section-boundary.ll | 45 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 llvm/test/DebugInfo/X86/basic-block-sections-debug-lineinfo-at-section-boundary.ll diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 98f24599970da..1bbe7ecc9ff89 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2039,7 +2039,10 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) { unsigned LastAsmLine = Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine(); - if (DL == PrevInstLoc) { + bool PrevInstInSameSection = + (!PrevInstBB || + PrevInstBB->getSectionIDNum() == MI->getParent()->getSectionIDNum()); + if (DL == PrevInstLoc && PrevInstInSameSection) { // If we have an ongoing unspecified location, nothing to do here. if (!DL) return; diff --git a/llvm/test/DebugInfo/X86/basic-block-sections-debug-lineinfo-at-section-boundary.ll b/llvm/test/DebugInfo/X86/basic-block-sections-debug-lineinfo-at-section-boundary.ll new file mode 100644 index 0000000000000..63eadef089507 --- /dev/null +++ b/llvm/test/DebugInfo/X86/basic-block-sections-debug-lineinfo-at-section-boundary.ll @@ -0,0 +1,45 @@ +; RUN: llc -mtriple=x86_64-unknown-linux-gnu --basic-block-sections=all < %s | FileCheck %s +; +; Verify that AsmPrinter does not optimize debug line directives +; across two distinct sections. Such optimization will lead +; to incorrect debug line number if the memory layout of those +; sections does not strictly mirror the order in the Asm file. +; +; int G; +; void func(int x) { +; if (x) G=0; +; } +; +; Reduced from the above example, the IR has been modified so that +; the store and return instructions have the same DebugLoc; in this +; context, we should see 2 different directives for line #4 +; +; CHECK-COUNT-2: .loc 0 4 1 + +define void @func(i1 %0) !dbg !8 { + br i1 %0, label %3, label %2 + +2: ; preds = %1 + store i32 0, ptr null, align 4, !dbg !12 + br label %3 + +3: ; preds = %2, %1 + ret void, !dbg !12 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 16.0.2", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "fd2935e6157b382ad81da17a61f24bb1") +!2 = !{!3} +!3 = !DIGlobalVariableExpression(var: !4, expr: !DIExpression()) +!4 = distinct !DIGlobalVariable(name: "G", scope: !0, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !{i32 7, !"Dwarf Version", i32 5} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 2, type: !9, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!9 = !DISubroutineType(types: !10) +!10 = !{null} +!11 = !{} +!12 = !DILocation(line: 4, column: 1, scope: !8) From a8b0c6fa28acced71db33e80bd0b51d00422035b Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Tue, 25 Apr 2023 20:01:43 +0000 Subject: [PATCH 019/608] Remove -Wpacked false positive for non-pod types where the layout isn't directly changed The packed attribute can still be useful in this case if the struct is then placed inside another packed struct - the non-pod element type's packed attribute declares that it's OK to misalign this element inside the packed structure. (otherwise the non-pod element is not packed/its alignment is preserved, as per D117616/2771233) Fixes PR62353 Differential Revision: https://reviews.llvm.org/D149182 --- clang/docs/ReleaseNotes.rst | 6 ++++++ clang/lib/AST/RecordLayoutBuilder.cpp | 10 +++++++++- clang/test/CodeGenCXX/warn-padded-packed.cpp | 15 +++++++++++++-- .../Layout/aix-Wpacked-expecting-diagnostics.cpp | 4 +++- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4f8165bbc8ee5..aa9a8a60e586d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -111,6 +111,12 @@ Resolutions to C++ Defect Reports - Implemented `DR2397 `_ which allows ``auto`` specifier for pointers and reference to arrays. +Warnings +^^^^^^^^ +- Address a false positive in ``-Wpacked`` when applied to a non-pod type using + Clang ABI >= 15 (fixes `#62353`_, + fallout from the non-POD packing ABI fix in LLVM 15) + C Language Changes ------------------ - Support for outputs from asm goto statements along indirect edges has been diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 641e9d62149e9..aca50912dceac 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2198,11 +2198,19 @@ void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) { << (InBits ? 1 : 0); // (byte|bit) } + const auto *CXXRD = dyn_cast(RD); + // Warn if we packed it unnecessarily, when the unpacked alignment is not // greater than the one after packing, the size in bits doesn't change and // the offset of each field is identical. + // Unless the type is non-POD (for Clang ABI > 15), where the packed + // attribute on such a type does allow the type to be packed into other + // structures that use the packed attribute. if (Packed && UnpackedAlignment <= Alignment && - UnpackedSizeInBits == getSizeInBits() && !HasPackedField) + UnpackedSizeInBits == getSizeInBits() && !HasPackedField && + (!CXXRD || CXXRD->isPOD() || + Context.getLangOpts().getClangABICompat() <= + LangOptions::ClangABI::Ver15)) Diag(D->getLocation(), diag::warn_unnecessary_packed) << Context.getTypeDeclType(RD); } diff --git a/clang/test/CodeGenCXX/warn-padded-packed.cpp b/clang/test/CodeGenCXX/warn-padded-packed.cpp index cf4890e40005d..c51a6c9443f6e 100644 --- a/clang/test/CodeGenCXX/warn-padded-packed.cpp +++ b/clang/test/CodeGenCXX/warn-padded-packed.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple=x86_64-none-none -Wpadded -Wpacked -verify %s -emit-llvm-only +// RUN: %clang_cc1 -triple=x86_64-none-none -Wpadded -Wpacked -verify=expected,top %s -emit-llvm-only +// RUN: %clang_cc1 -triple=x86_64-none-none -Wpadded -Wpacked -verify=expected,abi15 -fclang-abi-compat=15 %s -emit-llvm-only struct S1 { char c; @@ -154,7 +155,7 @@ struct S28 { char c1; short s1; char c2; - S28_non_pod p1; // expected-warning {{not packing field 'p1' as it is non-POD for the purposes of layout}} + S28_non_pod p1; // top-warning {{not packing field 'p1' as it is non-POD for the purposes of layout}} } __attribute__((packed)); struct S29_non_pod_align_1 { @@ -167,6 +168,16 @@ struct S29 { } __attribute__((packed)); // no warning static_assert(alignof(S29) == 1, ""); +struct S30 { +protected: + short s; +} __attribute__((packed)); // no warning +struct S30_use { // abi15-warning {{packed attribute is unnecessary for 'S30_use'}} + char c; + S30 u; +} __attribute__((packed)); +static_assert(sizeof(S30_use) == 3, ""); + // The warnings are emitted when the layout of the structs is computed, so we have to use them. void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*, S14*, S15*, S16*, S17*, S18*, S19*, S20*, S21*, S22*, S23*, S24*, S25*, diff --git a/clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp b/clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp index 37982fcb74b96..1576b8561cb56 100644 --- a/clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp +++ b/clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp @@ -6,6 +6,8 @@ // RUN: -fdump-record-layouts -fsyntax-only -verify -x c++ < %s | \ // RUN: FileCheck %s +// expected-no-diagnostics + struct A { double d; }; @@ -14,7 +16,7 @@ struct B { char x[8]; }; -struct [[gnu::packed]] C : B, A { // expected-warning{{packed attribute is unnecessary for 'C'}} +struct [[gnu::packed]] C : B, A { char x alignas(4)[8]; }; From 793c5b12b9a70e363be40c5da2e26d7151fbbf41 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Tue, 9 May 2023 00:40:11 +0000 Subject: [PATCH 020/608] Fix for release notes (follow-up to D149182/a8b0c6fa) --- clang/docs/ReleaseNotes.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index aa9a8a60e586d..fcc6fb7df0c87 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -111,12 +111,6 @@ Resolutions to C++ Defect Reports - Implemented `DR2397 `_ which allows ``auto`` specifier for pointers and reference to arrays. -Warnings -^^^^^^^^ -- Address a false positive in ``-Wpacked`` when applied to a non-pod type using - Clang ABI >= 15 (fixes `#62353`_, - fallout from the non-POD packing ABI fix in LLVM 15) - C Language Changes ------------------ - Support for outputs from asm goto statements along indirect edges has been @@ -267,6 +261,11 @@ Improvements to Clang's diagnostics (`#62247: `_). - Clang now diagnoses shadowing of lambda's template parameter by a capture. (`#61105: `_). +- Address a false positive in ``-Wpacked`` when applied to a non-pod type using + Clang ABI >= 15. + (`#62353: `_, + fallout from the non-POD packing ABI fix in LLVM 15). + Bug Fixes in This Version ------------------------- From 19941b0468c746a8d7ea543600fb491fe9808b04 Mon Sep 17 00:00:00 2001 From: Amir Ayupov Date: Mon, 8 May 2023 18:48:40 -0700 Subject: [PATCH 021/608] [BOLT] Use MCInstPrinter in createRetpolineFunctionTag Make retpoline functions invariant of X86 register numbers. retpoline-synthetic.test is known to fail NFC testing due to shifting register numbers. Use canonical register names instead of tablegen numbers. Before: ``` __retpoline_r51_ __retpoline_mem_r58+DATAat0x200fe8 __retpoline_mem_r51+0 __retpoline_mem_r132+0+8*53 ``` After: ``` __retpoline_%rax_ __retpoline_mem_%rip+DATAat0x200fe8 __retpoline_mem_%rax+0 __retpoline_mem_%r12+0+8*%rbx ``` Test Plan: - Revert 67bd3c58c0c7389e39c5a2f4d3b1a30459ccf5b7 that touches X86RegisterInfo.td. - retpoline-synthetic.test passes in NFC mode with this diff, fails without it. Reviewed By: #bolt, rafauler Differential Revision: https://reviews.llvm.org/D150138 --- bolt/lib/Passes/RetpolineInsertion.cpp | 49 +++++++++++-------- bolt/test/CMakeLists.txt | 1 + bolt/test/lit.cfg.py | 1 + .../test/runtime/X86/retpoline-synthetic.test | 7 +++ 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/bolt/lib/Passes/RetpolineInsertion.cpp b/bolt/lib/Passes/RetpolineInsertion.cpp index 4d83fb3903a70..c8a42725c9745 100644 --- a/bolt/lib/Passes/RetpolineInsertion.cpp +++ b/bolt/lib/Passes/RetpolineInsertion.cpp @@ -22,6 +22,7 @@ //===----------------------------------------------------------------------===// #include "bolt/Passes/RetpolineInsertion.h" +#include "llvm/MC/MCInstPrinter.h" #include "llvm/Support/raw_ostream.h" #define DEBUG_TYPE "bolt-retpoline" @@ -173,39 +174,45 @@ BinaryFunction *createNewRetpoline(BinaryContext &BC, std::string createRetpolineFunctionTag(BinaryContext &BC, const IndirectBranchInfo &BrInfo, bool R11Available) { - if (BrInfo.isReg()) - return "__retpoline_r" + to_string(BrInfo.BranchReg) + "_"; + std::string Tag; + llvm::raw_string_ostream TagOS(Tag); + TagOS << "__retpoline_"; + + if (BrInfo.isReg()) { + BC.InstPrinter->printRegName(TagOS, BrInfo.BranchReg); + TagOS << "_"; + TagOS.flush(); + return Tag; + } // Memory Branch if (R11Available) return "__retpoline_r11"; - std::string Tag = "__retpoline_mem_"; - const IndirectBranchInfo::MemOpInfo &MemRef = BrInfo.Memory; - std::string DispExprStr; - if (MemRef.DispExpr) { - llvm::raw_string_ostream Ostream(DispExprStr); - MemRef.DispExpr->print(Ostream, BC.AsmInfo.get()); - Ostream.flush(); - } + TagOS << "mem_"; - Tag += MemRef.BaseRegNum != BC.MIB->getNoRegister() - ? "r" + to_string(MemRef.BaseRegNum) - : ""; + if (MemRef.BaseRegNum != BC.MIB->getNoRegister()) + BC.InstPrinter->printRegName(TagOS, MemRef.BaseRegNum); - Tag += MemRef.DispExpr ? "+" + DispExprStr : "+" + to_string(MemRef.DispImm); + TagOS << "+"; + if (MemRef.DispExpr) + MemRef.DispExpr->print(TagOS, BC.AsmInfo.get()); + else + TagOS << MemRef.DispImm; - Tag += MemRef.IndexRegNum != BC.MIB->getNoRegister() - ? "+" + to_string(MemRef.ScaleImm) + "*" + - to_string(MemRef.IndexRegNum) - : ""; + if (MemRef.IndexRegNum != BC.MIB->getNoRegister()) { + TagOS << "+" << MemRef.ScaleImm << "*"; + BC.InstPrinter->printRegName(TagOS, MemRef.IndexRegNum); + } - Tag += MemRef.SegRegNum != BC.MIB->getNoRegister() - ? "_seg_" + to_string(MemRef.SegRegNum) - : ""; + if (MemRef.SegRegNum != BC.MIB->getNoRegister()) { + TagOS << "_seg_"; + BC.InstPrinter->printRegName(TagOS, MemRef.SegRegNum); + } + TagOS.flush(); return Tag; } diff --git a/bolt/test/CMakeLists.txt b/bolt/test/CMakeLists.txt index 1c7814155bdae..216a785b7d69f 100644 --- a/bolt/test/CMakeLists.txt +++ b/bolt/test/CMakeLists.txt @@ -47,6 +47,7 @@ list(APPEND BOLT_TEST_DEPS llvm-objdump llvm-readelf llvm-readobj + llvm-strings llvm-strip llvm-objcopy merge-fdata diff --git a/bolt/test/lit.cfg.py b/bolt/test/lit.cfg.py index 5838699157db7..f28afd5912279 100644 --- a/bolt/test/lit.cfg.py +++ b/bolt/test/lit.cfg.py @@ -87,6 +87,7 @@ ToolSubst('llvm-nm', unresolved='fatal'), ToolSubst('llvm-objdump', unresolved='fatal'), ToolSubst('llvm-objcopy', unresolved='fatal'), + ToolSubst('llvm-strings', unresolved='fatal'), ToolSubst('llvm-strip', unresolved='fatal'), ToolSubst('llvm-readelf', unresolved='fatal'), ToolSubst('link_fdata', command=sys.executable, unresolved='fatal', extra_args=[link_fdata_cmd]), diff --git a/bolt/test/runtime/X86/retpoline-synthetic.test b/bolt/test/runtime/X86/retpoline-synthetic.test index 6cae6a85fbe78..46daf3fdacde1 100644 --- a/bolt/test/runtime/X86/retpoline-synthetic.test +++ b/bolt/test/runtime/X86/retpoline-synthetic.test @@ -20,5 +20,12 @@ CHECK-CALL-NOT: callq * RUN: llvm-objdump -d -j ".text" %t | FileCheck %s -check-prefix=CHECK-JUMP CHECK-JUMP-NOT: jmpq * +# Check generated retpoline stub names +RUN: llvm-strings %t | FileCheck %s -check-prefix=CHECK-STRINGS +CHECK-STRINGS-DAG: __retpoline_%rax_ +CHECK-STRINGS-DAG: __retpoline_mem_%rip+DATAat0x[[#]] +CHECK-STRINGS-DAG: __retpoline_mem_%rax+0 +CHECK-STRINGS-DAG: __retpoline_mem_%r[[#]]+0+8*%rbx + RUN: %t 1000 3 | FileCheck %s CHECK: 30000000 From 6fcb91b2f756857f1295a28990738b5b6f924226 Mon Sep 17 00:00:00 2001 From: Amir Ayupov Date: Mon, 8 May 2023 18:53:48 -0700 Subject: [PATCH 022/608] [BOLT] Use opcode name in hashBlock Use MCInst opcode name instead of opcode value in hashing. Opcode values are unstable wrt changes to target tablegen definitions, and we notice that as output mismatches in NFC testing. This makes BOLT YAML profile tied to a particular LLVM revision which is less portable than offset-based fdata profile. Switch to using opcode names which have 1:1 mapping with opcode values for any given LLVM revision, and are stable wrt modifications to .td files (except of course modifications to names themselves). Test Plan: D150154 is a test commit adding new X86 instruction which shifts opcode values. With current change, pre-aggregated-perf.test passes in nfc check mode. Without current change, pre-aggregated-perf.test expectedly fails. Reviewed By: #bolt, rafauler Differential Revision: https://reviews.llvm.org/D150005 --- bolt/lib/Core/HashUtilities.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/bolt/lib/Core/HashUtilities.cpp b/bolt/lib/Core/HashUtilities.cpp index 1c980e003f884..0752eaeabef85 100644 --- a/bolt/lib/Core/HashUtilities.cpp +++ b/bolt/lib/Core/HashUtilities.cpp @@ -13,6 +13,7 @@ #include "bolt/Core/HashUtilities.h" #include "bolt/Core/BinaryContext.h" #include "bolt/Core/BinaryFunction.h" +#include "llvm/MC/MCInstPrinter.h" namespace llvm { namespace bolt { @@ -116,13 +117,11 @@ std::string hashBlock(BinaryContext &BC, const BinaryBasicBlock &BB, if (IsX86 && BC.MIB->isConditionalBranch(Inst)) Opcode = BC.MIB->getShortBranchOpcode(Opcode); - if (Opcode == 0) + if (Opcode == 0) { HashString.push_back(0); - - while (Opcode) { - uint8_t LSB = Opcode & 0xff; - HashString.push_back(LSB); - Opcode = Opcode >> 8; + } else { + StringRef OpcodeName = BC.InstPrinter->getOpcodeName(Opcode); + HashString.append(OpcodeName.str()); } for (const MCOperand &Op : MCPlus::primeOperands(Inst)) From e494ebf9d09b1112dcf4f22984bdb51bbf5d8cd7 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Mon, 8 May 2023 18:37:55 -0500 Subject: [PATCH 023/608] [OpenMP] Fix incorrect interop type for number of dependencies The interop types use the number of dependencies in the function interface. Every other function uses an `i32` to count the number of dependencies except for the initialization function. This leads to codegen issues when the rest of the compiler passes in an `i32` that then creates an invalid call. Fix this to be consistent with the other uses. Reviewed By: tianshilei1992 Differential Revision: https://reviews.llvm.org/D150156 --- clang/test/OpenMP/interop_irbuilder.cpp | 52 +++++++------------ .../include/llvm/Frontend/OpenMP/OMPKinds.def | 2 +- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 2 +- llvm/test/Transforms/OpenMP/add_attributes.ll | 8 +-- openmp/libomptarget/src/interop.cpp | 2 +- 5 files changed, 27 insertions(+), 39 deletions(-) diff --git a/clang/test/OpenMP/interop_irbuilder.cpp b/clang/test/OpenMP/interop_irbuilder.cpp index 337af16c5c90a..a0e666955ab11 100644 --- a/clang/test/OpenMP/interop_irbuilder.cpp +++ b/clang/test/OpenMP/interop_irbuilder.cpp @@ -10,23 +10,17 @@ void test1() { int D0, D1; omp_interop_t interop; -#pragma omp interop init(target \ - : interop) +#pragma omp interop init(target : interop) -#pragma omp interop init(targetsync \ - : interop) +#pragma omp interop init(targetsync : interop) -#pragma omp interop init(target \ - : interop) device(device_id) +#pragma omp interop init(target : interop) device(device_id) -#pragma omp interop init(targetsync \ - : interop) device(device_id) +#pragma omp interop init(targetsync : interop) device(device_id) -#pragma omp interop use(interop) depend(in \ - : D0, D1) nowait +#pragma omp interop use(interop) depend(in : D0, D1) nowait -#pragma omp interop destroy(interop) depend(in \ - : D0, D1) +#pragma omp interop destroy(interop) depend(in : D0, D1) } struct S { @@ -39,23 +33,17 @@ void S::member_test() { int device_id = 4; int D0, D1; -#pragma omp interop init(target \ - : interop) +#pragma omp interop init(target : interop) -#pragma omp interop init(targetsync \ - : interop) +#pragma omp interop init(targetsync : interop) -#pragma omp interop init(target \ - : interop) device(device_id) +#pragma omp interop init(target : interop) device(device_id) -#pragma omp interop init(targetsync \ - : interop) device(device_id) +#pragma omp interop init(targetsync : interop) device(device_id) -#pragma omp interop use(interop) depend(in \ - : D0, D1) nowait +#pragma omp interop use(interop) depend(in : D0, D1) nowait -#pragma omp interop destroy(interop) depend(in \ - : D0, D1) +#pragma omp interop destroy(interop) depend(in : D0, D1) } // CHECK-LABEL: @_Z5test1v( // CHECK-NEXT: entry: @@ -69,15 +57,15 @@ void S::member_test() { // CHECK-NEXT: [[DEP_COUNTER_ADDR6:%.*]] = alloca i64, align 8 // CHECK-NEXT: store i32 4, ptr [[DEVICE_ID]], align 4 // CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) -// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]], ptr [[INTEROP]], i32 1, i32 -1, i64 0, ptr null, i32 0) +// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]], ptr [[INTEROP]], i32 1, i32 -1, i32 0, ptr null, i32 0) // CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM1]], ptr [[INTEROP]], i32 2, i32 -1, i64 0, ptr null, i32 0) +// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM1]], ptr [[INTEROP]], i32 2, i32 -1, i32 0, ptr null, i32 0) // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[DEVICE_ID]], align 4 // CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM2]], ptr [[INTEROP]], i32 1, i32 [[TMP0]], i64 0, ptr null, i32 0) +// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM2]], ptr [[INTEROP]], i32 1, i32 [[TMP0]], i32 0, ptr null, i32 0) // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DEVICE_ID]], align 4 // CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]], ptr [[INTEROP]], i32 2, i32 [[TMP1]], i64 0, ptr null, i32 0) +// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]], ptr [[INTEROP]], i32 2, i32 [[TMP1]], i32 0, ptr null, i32 0) // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x %struct.kmp_depend_info], ptr [[DOTDEP_ARR_ADDR]], i64 0, i64 0 // CHECK-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[D0]] to i64 // CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_KMP_DEPEND_INFO:%.*]], ptr [[TMP2]], i64 0 @@ -136,18 +124,18 @@ void S::member_test() { // CHECK-NEXT: store i32 4, ptr [[DEVICE_ID]], align 4 // CHECK-NEXT: [[INTEROP:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 // CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]], ptr [[INTEROP]], i32 1, i32 -1, i64 0, ptr null, i32 0) +// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]], ptr [[INTEROP]], i32 1, i32 -1, i32 0, ptr null, i32 0) // CHECK-NEXT: [[INTEROP2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 // CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]], ptr [[INTEROP2]], i32 2, i32 -1, i64 0, ptr null, i32 0) +// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]], ptr [[INTEROP2]], i32 2, i32 -1, i32 0, ptr null, i32 0) // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[DEVICE_ID]], align 4 // CHECK-NEXT: [[INTEROP4:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 // CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM5:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM5]], ptr [[INTEROP4]], i32 1, i32 [[TMP0]], i64 0, ptr null, i32 0) +// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM5]], ptr [[INTEROP4]], i32 1, i32 [[TMP0]], i32 0, ptr null, i32 0) // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DEVICE_ID]], align 4 // CHECK-NEXT: [[INTEROP6:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 // CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM7:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) -// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM7]], ptr [[INTEROP6]], i32 2, i32 [[TMP1]], i64 0, ptr null, i32 0) +// CHECK-NEXT: call void @__tgt_interop_init(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM7]], ptr [[INTEROP6]], i32 2, i32 [[TMP1]], i32 0, ptr null, i32 0) // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x %struct.kmp_depend_info], ptr [[DOTDEP_ARR_ADDR]], i64 0, i64 0 // CHECK-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[D0]] to i64 // CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_KMP_DEPEND_INFO:%.*]], ptr [[TMP2]], i64 0 diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index 8a09fb7cb7a6f..58482873cdca1 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -402,7 +402,7 @@ __OMP_RTL(__kmpc_aligned_alloc, false, VoidPtr, /* Int */ Int32, SizeTy, SizeTy, __OMP_RTL(__kmpc_free, false, Void, /* Int */ Int32, VoidPtr, VoidPtr) __OMP_RTL(__tgt_interop_init, false, Void, IdentPtr, Int32, VoidPtrPtr, Int32, - Int32, Int64, VoidPtr, Int32) + Int32, Int32, VoidPtr, Int32) __OMP_RTL(__tgt_interop_destroy, false, Void, IdentPtr, Int32, VoidPtrPtr, Int32, Int32, VoidPtr, Int32) __OMP_RTL(__tgt_interop_use, false, Void, IdentPtr, Int32, VoidPtrPtr, Int32, diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index 0c3d15dd66fad..0d7221852878d 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -3798,7 +3798,7 @@ CallInst *OpenMPIRBuilder::createOMPInteropInit( Device = ConstantInt::get(Int32, -1); Constant *InteropTypeVal = ConstantInt::get(Int32, (int)InteropType); if (NumDependences == nullptr) { - NumDependences = ConstantInt::get(Int64, 0); + NumDependences = ConstantInt::get(Int32, 0); PointerType *PointerTypeVar = Type::getInt8PtrTy(M.getContext()); DependenceAddress = ConstantPointerNull::get(PointerTypeVar); } diff --git a/llvm/test/Transforms/OpenMP/add_attributes.ll b/llvm/test/Transforms/OpenMP/add_attributes.ll index 73d434e2062e9..b2bad1192f189 100644 --- a/llvm/test/Transforms/OpenMP/add_attributes.ll +++ b/llvm/test/Transforms/OpenMP/add_attributes.ll @@ -742,7 +742,7 @@ declare i32 @__kmpc_target_init(ptr, i8, i1); declare void @__tgt_interop_destroy(ptr, i32, ptr, i32, i32, ptr, i32); -declare void @__tgt_interop_init(ptr, i32, ptr, i32, i32, i64, ptr, i32); +declare void @__tgt_interop_init(ptr, i32, ptr, i32, i32, i32, ptr, i32); declare void @__tgt_interop_use(ptr, i32, ptr, i32, i32, ptr, i32); @@ -1398,7 +1398,7 @@ declare i32 @__tgt_target_kernel_nowait(ptr, i64, i32, i32, ptr, ptr, i32, ptr, ; CHECK: declare void @__tgt_interop_destroy(ptr, i32, ptr, i32, i32, ptr, i32) ; CHECK-NOT: Function Attrs -; CHECK: declare void @__tgt_interop_init(ptr, i32, ptr, i32, i32, i64, ptr, i32) +; CHECK: declare void @__tgt_interop_init(ptr, i32, ptr, i32, i32, i32, ptr, i32) ; CHECK-NOT: Function Attrs ; CHECK: declare void @__tgt_interop_use(ptr, i32, ptr, i32, i32, ptr, i32) @@ -2046,7 +2046,7 @@ declare i32 @__tgt_target_kernel_nowait(ptr, i64, i32, i32, ptr, ptr, i32, ptr, ; OPTIMISTIC: declare void @__tgt_interop_destroy(ptr, i32, ptr, i32, i32, ptr, i32) ; OPTIMISTIC-NOT: Function Attrs -; OPTIMISTIC: declare void @__tgt_interop_init(ptr, i32, ptr, i32, i32, i64, ptr, i32) +; OPTIMISTIC: declare void @__tgt_interop_init(ptr, i32, ptr, i32, i32, i32, ptr, i32) ; OPTIMISTIC-NOT: Function Attrs ; OPTIMISTIC: declare void @__tgt_interop_use(ptr, i32, ptr, i32, i32, ptr, i32) @@ -2707,7 +2707,7 @@ declare i32 @__tgt_target_kernel_nowait(ptr, i64, i32, i32, ptr, ptr, i32, ptr, ; EXT: declare void @__tgt_interop_destroy(ptr, i32 signext, ptr, i32 signext, i32 signext, ptr, i32 signext) ; EXT-NOT: Function Attrs -; EXT: declare void @__tgt_interop_init(ptr, i32 signext, ptr, i32 signext, i32 signext, i64, ptr, i32 signext) +; EXT: declare void @__tgt_interop_init(ptr, i32 signext, ptr, i32 signext, i32 signext, i32, ptr, i32 signext) ; EXT-NOT: Function Attrs ; EXT: declare void @__tgt_interop_use(ptr, i32 signext, ptr, i32 signext, i32 signext, ptr, i32 signext) diff --git a/openmp/libomptarget/src/interop.cpp b/openmp/libomptarget/src/interop.cpp index 0f258825bf50f..0f6c887060ee5 100644 --- a/openmp/libomptarget/src/interop.cpp +++ b/openmp/libomptarget/src/interop.cpp @@ -184,7 +184,7 @@ extern "C" { void __tgt_interop_init(ident_t *LocRef, kmp_int32 Gtid, omp_interop_val_t *&InteropPtr, kmp_interop_type_t InteropType, kmp_int32 DeviceId, - kmp_int64 Ndeps, kmp_depend_info_t *DepList, + kmp_int32 Ndeps, kmp_depend_info_t *DepList, kmp_int32 HaveNowait) { kmp_int32 NdepsNoalias = 0; kmp_depend_info_t *NoaliasDepList = NULL; From a4c87f8ccaccc76fd7d1c6c2e639ca84b9ec7794 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sat, 6 May 2023 16:29:16 -0700 Subject: [PATCH 024/608] [clang-format] Fix consecutive alignments in #else blocks Since 3.8 or earlier, clang-format has been lumping all #else, #elif, etc blocks together when doing whitespace replacements and causing consecutive alignments across #else blocks. Commit c077975 partially addressed the problem but also triggered "regressions". This patch fixes the root cause of the problem and "reverts" c077975 (except for the unit tests). Fixes #36070. Fixes #55265. Fixes #60721. Fixes #61498. Differential Revision: https://reviews.llvm.org/D150057 --- clang/lib/Format/WhitespaceManager.cpp | 32 +++++-------- clang/unittests/Format/FormatTest.cpp | 45 +++++++++++++++++++ clang/unittests/Format/FormatTestComments.cpp | 4 +- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index d2be3b3a77df4..040b9536b6305 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -49,8 +49,16 @@ void WhitespaceManager::replaceWhitespace(FormatToken &Tok, unsigned Newlines, unsigned Spaces, unsigned StartOfTokenColumn, bool IsAligned, bool InPPDirective) { - if (Tok.Finalized || (Tok.MacroCtx && Tok.MacroCtx->Role == MR_ExpandedArg)) + auto PPBranchDirectiveStartsLine = [&Tok] { + return Tok.is(tok::hash) && !Tok.Previous && Tok.Next && + Tok.Next->isOneOf(tok::pp_if, tok::pp_ifdef, tok::pp_ifndef, + tok::pp_elif, tok::pp_elifdef, tok::pp_elifndef, + tok::pp_else, tok::pp_endif); + }; + if ((Tok.Finalized && !PPBranchDirectiveStartsLine()) || + (Tok.MacroCtx && Tok.MacroCtx->Role == MR_ExpandedArg)) { return; + } Tok.setDecision((Newlines > 0) ? FD_Break : FD_Continue); Changes.push_back(Change(Tok, /*CreateReplacement=*/true, Tok.WhitespaceRange, Spaces, StartOfTokenColumn, Newlines, "", "", @@ -522,13 +530,6 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches, ? Changes[StartAt].indentAndNestingLevel() : std::tuple(); - // Keep track if the first token has a non-zero indent and nesting level. - // This can happen when aligning the contents of "#else" preprocessor blocks, - // which is done separately. - bool HasInitialIndentAndNesting = - StartAt == 0 && - IndentAndNestingLevel > std::tuple(); - // Keep track of the number of commas before the matching tokens, we will only // align a sequence of matching tokens if they are preceded by the same number // of commas. @@ -563,19 +564,8 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches, unsigned i = StartAt; for (unsigned e = Changes.size(); i != e; ++i) { - if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel) { - if (!HasInitialIndentAndNesting) - break; - // The contents of preprocessor blocks are aligned separately. - // If the initial preprocessor block is indented or nested (e.g. it's in - // a function), do not align and exit after finishing this scope block. - // Instead, align, and then lower the baseline indent and nesting level - // in order to continue aligning subsequent blocks. - EndOfSequence = i; - AlignCurrentSequence(); - IndentAndNestingLevel = - Changes[i].indentAndNestingLevel(); // new baseline - } + if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel) + break; if (Changes[i].NewlinesBefore != 0) { CommasBeforeMatch = 0; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 099a5cb913643..dc673934a3f1b 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -6367,6 +6367,51 @@ TEST_F(FormatTest, FormatAlignInsidePreprocessorElseBlock) { "#endif\n" "}", Style); + + verifyFormat("#if FOO\n" + "int a = 1;\n" + "#else\n" + "int ab = 2;\n" + "#endif\n" + "#ifdef BAR\n" + "int abc = 3;\n" + "#elifdef BAZ\n" + "int abcd = 4;\n" + "#endif", + Style); + + verifyFormat("void f() {\n" + " if (foo) {\n" + "#if FOO\n" + " int a = 1;\n" + "#else\n" + " bool a = true;\n" + "#endif\n" + " int abc = 3;\n" + "#ifndef BAR\n" + " int abcd = 4;\n" + "#elif BAZ\n" + " bool abcd = true;\n" + "#endif\n" + " }\n" + "}", + Style); + + verifyFormat("void f() {\n" + "#if FOO\n" + " a = 1;\n" + "#else\n" + " ab = 2;\n" + "#endif\n" + "}\n" + "void g() {\n" + "#if BAR\n" + " abc = 3;\n" + "#elifndef BAZ\n" + " abcd = 4;\n" + "#endif\n" + "}", + Style); } TEST_F(FormatTest, FormatHashIfNotAtStartOfLine) { diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 60e045059be86..6e5b5b2d68d81 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -2759,7 +2759,7 @@ TEST_F(FormatTestComments, AlignTrailingComments) { // Checks an edge case in preprocessor handling. // These comments should *not* be aligned - EXPECT_NE( // change for EQ when fixed + EXPECT_EQ( "#if FOO\n" "#else\n" "long a; // Line about a\n" @@ -4316,7 +4316,7 @@ TEST_F(FormatTestComments, SplitCommentIntroducers) { )", format(R"(// /\ -/ +/ )", getLLVMStyleWithColumns(10))); } From 52e4f9e386ac1bf0e515a50a871231b89d3e28fc Mon Sep 17 00:00:00 2001 From: Amir Aupov Date: Mon, 8 May 2023 20:16:58 -0700 Subject: [PATCH 025/608] [BOLT][test] Fix retpoline-synthetic.test Fix test on BOLT's buildbot, e.g. https://lab.llvm.org/buildbot/#/builders/244/builds/10885 --- bolt/test/runtime/X86/retpoline-synthetic.test | 1 - 1 file changed, 1 deletion(-) diff --git a/bolt/test/runtime/X86/retpoline-synthetic.test b/bolt/test/runtime/X86/retpoline-synthetic.test index 46daf3fdacde1..394d0189207fb 100644 --- a/bolt/test/runtime/X86/retpoline-synthetic.test +++ b/bolt/test/runtime/X86/retpoline-synthetic.test @@ -25,7 +25,6 @@ RUN: llvm-strings %t | FileCheck %s -check-prefix=CHECK-STRINGS CHECK-STRINGS-DAG: __retpoline_%rax_ CHECK-STRINGS-DAG: __retpoline_mem_%rip+DATAat0x[[#]] CHECK-STRINGS-DAG: __retpoline_mem_%rax+0 -CHECK-STRINGS-DAG: __retpoline_mem_%r[[#]]+0+8*%rbx RUN: %t 1000 3 | FileCheck %s CHECK: 30000000 From f09b0e35b6d8f19385f37b213b029a7ca9cb6368 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Mon, 8 May 2023 20:23:31 -0700 Subject: [PATCH 026/608] [mlir] Replace None with std::nullopt in comments (NFC) This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716 --- mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h | 4 ++-- mlir/include/mlir/IR/OpImplementation.h | 2 +- mlir/include/mlir/Tools/PDLL/AST/Nodes.h | 2 +- mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp | 4 ++-- mlir/lib/Dialect/Affine/IR/AffineOps.cpp | 2 +- mlir/lib/Dialect/Utils/ReshapeOpsUtils.cpp | 2 +- mlir/test/lib/Analysis/DataFlow/TestDenseDataFlowAnalysis.cpp | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h index 311b81ae90104..035566fbc1575 100644 --- a/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h +++ b/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h @@ -219,8 +219,8 @@ class DeadCodeAnalysis : public DataFlowAnalysis { /// Mark the entry blocks of the operation as executable. void markEntryBlocksLive(Operation *op); - /// Get the constant values of the operands of the operation. Returns none if - /// any of the operand lattices are uninitialized. + /// Get the constant values of the operands of the operation. Returns + /// std::nullopt if any of the operand lattices are uninitialized. std::optional> getOperandValues(Operation *op); /// The top-level operation the analysis is running on. This is used to detect diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h index e770c7453129b..f4045b236a448 100644 --- a/mlir/include/mlir/IR/OpImplementation.h +++ b/mlir/include/mlir/IR/OpImplementation.h @@ -778,7 +778,7 @@ class AsmParser { /// The parsed keyword itself. StringRef keyword; - /// The result of the switch statement or none if currently unknown. + /// The result of the switch statement or std::nullopt if currently unknown. std::optional result; }; diff --git a/mlir/include/mlir/Tools/PDLL/AST/Nodes.h b/mlir/include/mlir/Tools/PDLL/AST/Nodes.h index 5e86cda27a5b7..3b29d48fb07bd 100644 --- a/mlir/include/mlir/Tools/PDLL/AST/Nodes.h +++ b/mlir/include/mlir/Tools/PDLL/AST/Nodes.h @@ -1009,7 +1009,7 @@ class OpNameDecl : public Node::NodeBase { static OpNameDecl *create(Context &ctx, const Name &name); static OpNameDecl *create(Context &ctx, SMRange loc); - /// Return the name of this operation, or none if the name is unknown. + /// Return the name of this operation, or std::nullopt if the name is unknown. std::optional getName() const { const Name *name = Decl::getName(); return name ? std::optional(name->getName()) : std::nullopt; diff --git a/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp index 2415ff48144bc..8ff71b59750a8 100644 --- a/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp +++ b/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp @@ -309,8 +309,8 @@ void DeadCodeAnalysis::visitCallOperation(CallOpInterface call) { } /// Get the constant values of the operands of an operation. If any of the -/// constant value lattices are uninitialized, return none to indicate the -/// analysis should bail out. +/// constant value lattices are uninitialized, return std::nullopt to indicate +/// the analysis should bail out. static std::optional> getOperandValuesImpl( Operation *op, function_ref *(Value)> getLattice) { diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp index 7a0f1e0983c7b..f3626afcd7059 100644 --- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp +++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp @@ -707,7 +707,7 @@ static std::optional getUpperBound(Value iv) { /// expressions (w.r.t constant coefficients) so as to not depend on anything /// heavyweight in `Analysis`. Expressions of the form: c0*d0 + c1*d1 + c2*s0 + /// ... + c_n are handled. Expressions involving floordiv, ceildiv, mod or -/// semi-affine ones will lead a none being returned. +/// semi-affine ones will lead std::nullopt being returned. static std::optional getBoundForExpr(AffineExpr expr, unsigned numDims, unsigned numSymbols, ArrayRef> constLowerBounds, diff --git a/mlir/lib/Dialect/Utils/ReshapeOpsUtils.cpp b/mlir/lib/Dialect/Utils/ReshapeOpsUtils.cpp index 18646f598bcee..94fa2d3de22fb 100644 --- a/mlir/lib/Dialect/Utils/ReshapeOpsUtils.cpp +++ b/mlir/lib/Dialect/Utils/ReshapeOpsUtils.cpp @@ -356,7 +356,7 @@ SliceFromCollapseHelper::getInsertSliceParams(MLIRContext *ctx, /// Returns the index of the only non-unit dimension among `indices` of `shape`, /// if such a dimension exists and `indices` has more than one element. -/// Otherwise, return none. +/// Otherwise, return std::nullopt. static std::optional getUniqueNonUnitDim(ArrayRef indices, ArrayRef shape) { // Return false if more than one of the dimensions in this group are not 1. diff --git a/mlir/test/lib/Analysis/DataFlow/TestDenseDataFlowAnalysis.cpp b/mlir/test/lib/Analysis/DataFlow/TestDenseDataFlowAnalysis.cpp index e9769c10e63fe..733a146469498 100644 --- a/mlir/test/lib/Analysis/DataFlow/TestDenseDataFlowAnalysis.cpp +++ b/mlir/test/lib/Analysis/DataFlow/TestDenseDataFlowAnalysis.cpp @@ -100,7 +100,7 @@ class LastModification : public AbstractDenseLattice { return result; } - /// Get the last modifications of a value. Returns none if the last + /// Get the last modifications of a value. Returns std::nullopt if the last /// modifications are not known. std::optional> getLastModifiers(Value value) const { auto it = lastMods.find(value); From a4a71df87fb74416fdebe0b756c2cc6ef160bea4 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Mon, 8 May 2023 20:23:32 -0700 Subject: [PATCH 027/608] [Hexagon] Remove unused struct AlignVectors::Segment --- llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp b/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp index 2629b54224f1d..3f4244e20f8e9 100644 --- a/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp @@ -168,12 +168,6 @@ class AlignVectors { private: using InstList = std::vector; - struct Segment { - void *Data; - int Start; - int Size; - }; - struct AddrInfo { AddrInfo(const AddrInfo &) = default; AddrInfo(const HexagonVectorCombine &HVC, Instruction *I, Value *A, Type *T, From 749b4ad315215534f0c6de2c9c732e1de750d8af Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Mon, 8 May 2023 20:23:33 -0700 Subject: [PATCH 028/608] [clang] Modernize LoopHint (NFC) --- clang/include/clang/Parse/LoopHint.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Parse/LoopHint.h b/clang/include/clang/Parse/LoopHint.h index 6e363f72b6587..75705fcd4c75c 100644 --- a/clang/include/clang/Parse/LoopHint.h +++ b/clang/include/clang/Parse/LoopHint.h @@ -23,20 +23,18 @@ struct LoopHint { // Identifier corresponding to the name of the pragma. "loop" for // "#pragma clang loop" directives and "unroll" for "#pragma unroll" // hints. - IdentifierLoc *PragmaNameLoc; + IdentifierLoc *PragmaNameLoc = nullptr; // Name of the loop hint. Examples: "unroll", "vectorize". In the // "#pragma unroll" and "#pragma nounroll" cases, this is identical to // PragmaNameLoc. - IdentifierLoc *OptionLoc; + IdentifierLoc *OptionLoc = nullptr; // Identifier for the hint state argument. If null, then the state is // default value such as for "#pragma unroll". - IdentifierLoc *StateLoc; + IdentifierLoc *StateLoc = nullptr; // Expression for the hint argument if it exists, null otherwise. - Expr *ValueExpr; + Expr *ValueExpr = nullptr; - LoopHint() - : PragmaNameLoc(nullptr), OptionLoc(nullptr), StateLoc(nullptr), - ValueExpr(nullptr) {} + LoopHint() = default; }; } // end namespace clang From 4e93f91148ae4698b31ee397fb60410441df8b6b Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 8 May 2023 20:28:52 -0700 Subject: [PATCH 029/608] Add a new report_load_commands option to jGetLoadedDynamicLibrariesInfos jGetLoadedDynamicLibrariesInfos has a mode where it will list every binary in the process - the load address and filepath from dyld SPI, and the mach-o header and load commands from a scan by debugserver for perf reasons. With a large enough number of libraries, creating that StructuredData representation of all of this, and formatting it into an ascii string to send up to lldb, can grow debugserver's heap size too large for some environments. This patch adds a new report_load_commands:false boolean to the jGetLoadedDynamicLibrariesInfos packet, where debugserver will now only report the dyld SPI load address and filepath for all of the binaries. lldb can then ask for the detailed information on the process binaries in smaller chunks, and avoid debugserver having ever growing heap use as the number of binaries inevitably increases. This patch also removes a version of jGetLoadedDynamicLibrariesInfos for pre-iOS 10 and pre-macOS 10.12 systems where we did not use dyld SPI. We can't back compile to those OS builds any longer with modern Xcode. Finally, it removes a requirement in DynamicLoaderMacOS that the JSON reply from jGetLoadedDynamicLibrariesInfos include the mod_date field for each binary. This has always been reported as 0 in modern dyld, and is another reason for packet growth in the reply. debugserver still puts the mod_date field in its replies for interop with existing lldb's, but we will be able to remove it the field from debugserver's output after the next release cycle when this patch has had time to circulate. I'll add lldb support for requesting the load addresses only and splitting the request up into chunks in a separate patch. Differential Revision: https://reviews.llvm.org/D150158 rdar://107848326 --- lldb/docs/lldb-gdb-remote.txt | 17 +- .../MacOSX-DYLD/DynamicLoaderDarwin.cpp | 11 +- .../MacOSX-DYLD/DynamicLoaderDarwin.h | 6 +- .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp | 2 +- lldb/tools/debugserver/source/DNB.cpp | 15 +- lldb/tools/debugserver/source/DNB.h | 5 +- .../debugserver/source/MacOSX/MachProcess.h | 12 +- .../debugserver/source/MacOSX/MachProcess.mm | 145 ++++-------------- lldb/tools/debugserver/source/RNBRemote.cpp | 35 ++--- 9 files changed, 65 insertions(+), 183 deletions(-) diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt index b426978a94907..28180df714e00 100644 --- a/lldb/docs/lldb-gdb-remote.txt +++ b/lldb/docs/lldb-gdb-remote.txt @@ -2001,19 +2001,16 @@ for this region. // This packet asks the remote debug stub to send the details about libraries // being added/removed from the process as a performance optimization. // -// There are three ways this packet can be used. All three return a dictionary of +// There are two ways this packet can be used. Both return a dictionary of // binary images formatted the same way. // -// On OS X 10.11, iOS 9, tvOS 9, watchOS 2 and earlier, the packet is used like -// jGetLoadedDynamicLibrariesInfos:{"image_count":1,"image_list_address":140734800075128} -// where the image_list_address is an array of {void* load_addr, void* mod_date, void* pathname} -// in the inferior process memory (and image_count is the number of elements in this array). -// lldb is using information from the dyld_all_image_infos structure to make these requests to -// debugserver. This use is not supported on macOS 10.12, iOS 10, tvOS 10, watchOS 3 or newer. -// -// On macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer, there are two calls. One requests information -// on all shared libraries: +// One requests information on all shared libraries: // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true} +// with an optional `"report_load_commands":false` which can be added, asking +// that only the dyld SPI information (load addresses, filenames) be returned. +// The default behavior is that debugserver scans the mach-o header and load +// commands of each binary, and returns it in the JSON reply. +// // And the second requests information about a list of shared libraries, given their load addresses: // jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]} // diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp index 6506d000668e9..8bcc93589ae8f 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -372,7 +372,6 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo( // clang-format off if (!image->HasKey("load_address") || !image->HasKey("pathname") || - !image->HasKey("mod_date") || !image->HasKey("mach_header") || image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr || !image->HasKey("segments") || @@ -383,8 +382,6 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo( // clang-format on image_infos[i].address = image->GetValueForKey("load_address")->GetAsInteger()->GetValue(); - image_infos[i].mod_date = - image->GetValueForKey("mod_date")->GetAsInteger()->GetValue(); image_infos[i].file_spec.SetFile( image->GetValueForKey("pathname")->GetAsString()->GetValue(), FileSpec::Style::native); @@ -811,11 +808,11 @@ void DynamicLoaderDarwin::ImageInfo::PutToLog(Log *log) const { if (!log) return; if (address == LLDB_INVALID_ADDRESS) { - LLDB_LOG(log, "modtime={0:x+8} uuid={1} path='{2}' (UNLOADED)", mod_date, - uuid.GetAsString(), file_spec.GetPath()); + LLDB_LOG(log, "uuid={1} path='{2}' (UNLOADED)", uuid.GetAsString(), + file_spec.GetPath()); } else { - LLDB_LOG(log, "address={0:x+16} modtime={1:x+8} uuid={2} path='{3}'", - address, mod_date, uuid.GetAsString(), file_spec.GetPath()); + LLDB_LOG(log, "address={0:x+16} uuid={2} path='{3}'", address, + uuid.GetAsString(), file_spec.GetPath()); for (uint32_t i = 0; i < segments.size(); ++i) segments[i].PutToLog(log, slide); } diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h index 0268505ef98aa..8f9a29c94173f 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h @@ -100,8 +100,6 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader { /// The amount to slide all segments by if there is a global /// slide. lldb::addr_t slide = 0; - /// Modification date for this dylib. - lldb::addr_t mod_date = 0; /// Resolved path for this dylib. lldb_private::FileSpec file_spec; /// UUID for this dylib if it has one, else all zeros. @@ -128,7 +126,6 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader { if (!load_cmd_data_only) { address = LLDB_INVALID_ADDRESS; slide = 0; - mod_date = 0; file_spec.Clear(); ::memset(&header, 0, sizeof(header)); } @@ -142,8 +139,7 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader { bool operator==(const ImageInfo &rhs) const { return address == rhs.address && slide == rhs.slide && - mod_date == rhs.mod_date && file_spec == rhs.file_spec && - uuid == rhs.uuid && + file_spec == rhs.file_spec && uuid == rhs.uuid && memcmp(&header, &rhs.header, sizeof(header)) == 0 && segments == rhs.segments && os_type == rhs.os_type && os_env == rhs.os_env; diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index 64b035c384c67..8df3e8e36c0db 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -693,7 +693,7 @@ bool DynamicLoaderMacOSXDYLD::ReadImageInfos( i++) { image_infos[i].address = info_data_ref.GetAddress(&info_data_offset); lldb::addr_t path_addr = info_data_ref.GetAddress(&info_data_offset); - image_infos[i].mod_date = info_data_ref.GetAddress(&info_data_offset); + info_data_ref.GetAddress(&info_data_offset); // mod_date, unused */ char raw_path[PATH_MAX]; m_process->ReadCStringFromMemory(path_addr, raw_path, sizeof(raw_path), diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp index bab5b4a813058..8a8b1eeb355bd 100644 --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -1023,20 +1023,11 @@ DNBGetTSDAddressForThread(nub_process_t pid, nub_thread_t tid, return INVALID_NUB_ADDRESS; } -JSONGenerator::ObjectSP DNBGetLoadedDynamicLibrariesInfos( - nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count) { - MachProcessSP procSP; - if (GetProcessSP(pid, procSP)) { - return procSP->GetLoadedDynamicLibrariesInfos(pid, image_list_address, - image_count); - } - return JSONGenerator::ObjectSP(); -} - -JSONGenerator::ObjectSP DNBGetAllLoadedLibrariesInfos(nub_process_t pid) { +JSONGenerator::ObjectSP +DNBGetAllLoadedLibrariesInfos(nub_process_t pid, bool report_load_commands) { MachProcessSP procSP; if (GetProcessSP(pid, procSP)) { - return procSP->GetAllLoadedLibrariesInfos(pid); + return procSP->GetAllLoadedLibrariesInfos(pid, report_load_commands); } return JSONGenerator::ObjectSP(); } diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h index 3108f1ae7a20e..d8ccdea20f692 100644 --- a/lldb/tools/debugserver/source/DNB.h +++ b/lldb/tools/debugserver/source/DNB.h @@ -210,9 +210,8 @@ DNBGetTSDAddressForThread(nub_process_t pid, nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size); -JSONGenerator::ObjectSP DNBGetLoadedDynamicLibrariesInfos( - nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count); -JSONGenerator::ObjectSP DNBGetAllLoadedLibrariesInfos(nub_process_t pid); +JSONGenerator::ObjectSP +DNBGetAllLoadedLibrariesInfos(nub_process_t pid, bool report_load_commands); JSONGenerator::ObjectSP DNBGetLibrariesInfoForAddresses(nub_process_t pid, std::vector &macho_addresses); diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h index bcdd0f6b238cd..a84bfb94d09c1 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h @@ -72,12 +72,11 @@ class MachProcess { struct binary_image_information { std::string filename; uint64_t load_address; - uint64_t mod_date; // may not be available - 0 if so struct mach_o_information macho_info; bool is_valid_mach_header; binary_image_information() - : filename(), load_address(INVALID_NUB_ADDRESS), mod_date(0), + : filename(), load_address(INVALID_NUB_ADDRESS), is_valid_mach_header(false) {} }; @@ -259,7 +258,8 @@ class MachProcess { int wordsize, struct mach_o_information &inf); JSONGenerator::ObjectSP FormatDynamicLibrariesIntoJSON( - const std::vector &image_infos); + const std::vector &image_infos, + bool report_load_commands); uint32_t GetPlatform(); /// Get the runtime platform from DYLD via SPI. uint32_t GetProcessPlatformViaDYLDSPI(); @@ -271,12 +271,12 @@ class MachProcess { /// command details. void GetAllLoadedBinariesViaDYLDSPI( std::vector &image_infos); - JSONGenerator::ObjectSP GetLoadedDynamicLibrariesInfos( - nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count); JSONGenerator::ObjectSP GetLibrariesInfoForAddresses(nub_process_t pid, std::vector &macho_addresses); - JSONGenerator::ObjectSP GetAllLoadedLibrariesInfos(nub_process_t pid); + JSONGenerator::ObjectSP + GetAllLoadedLibrariesInfos(nub_process_t pid, + bool fetch_report_load_commands); JSONGenerator::ObjectSP GetSharedCacheInfo(nub_process_t pid); nub_size_t GetNumThreads() const; diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm index b6e5e5738c901..dcc1579f70251 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm @@ -912,22 +912,34 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) { // create a JSONGenerator object // with all the details we want to send to lldb. JSONGenerator::ObjectSP MachProcess::FormatDynamicLibrariesIntoJSON( - const std::vector &image_infos) { + const std::vector &image_infos, + bool report_load_commands) { JSONGenerator::ArraySP image_infos_array_sp(new JSONGenerator::Array()); const size_t image_count = image_infos.size(); for (size_t i = 0; i < image_count; i++) { - if (!image_infos[i].is_valid_mach_header) + // If we should report the Mach-O header and load commands, + // and those were unreadable, don't report anything about this + // binary. + if (report_load_commands && !image_infos[i].is_valid_mach_header) continue; JSONGenerator::DictionarySP image_info_dict_sp( new JSONGenerator::Dictionary()); image_info_dict_sp->AddIntegerItem("load_address", image_infos[i].load_address); - image_info_dict_sp->AddIntegerItem("mod_date", image_infos[i].mod_date); + // TODO: lldb currently rejects a response without this, but it + // is always zero from dyld. It can be removed once we've had time + // for lldb's that require it to be present are obsolete. + image_info_dict_sp->AddIntegerItem("mod_date", 0); image_info_dict_sp->AddStringItem("pathname", image_infos[i].filename); + if (!report_load_commands) { + image_infos_array_sp->AddItem(image_info_dict_sp); + continue; + } + uuid_string_t uuidstr; uuid_unparse_upper(image_infos[i].macho_info.uuid, uuidstr); image_info_dict_sp->AddStringItem("uuid", uuidstr); @@ -1000,109 +1012,6 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) { return reply_sp; } -// Get the shared library information using the old (pre-macOS 10.12, pre-iOS -// 10, pre-tvOS 10, pre-watchOS 3) -// code path. We'll be given the address of an array of structures in the form -// {void* load_addr, void* mod_date, void* pathname} -// -// In macOS 10.12 etc and newer, we'll use SPI calls into dyld to gather this -// information. -JSONGenerator::ObjectSP MachProcess::GetLoadedDynamicLibrariesInfos( - nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count) { - - JSONGenerator::ObjectSP empty_reply_sp(new JSONGenerator::Dictionary()); - int pointer_size = GetInferiorAddrSize(pid); - - std::vector image_infos; - size_t image_infos_size = image_count * 3 * pointer_size; - - uint8_t *image_info_buf = (uint8_t *)malloc(image_infos_size); - if (image_info_buf == NULL) { - return empty_reply_sp; - } - if (ReadMemory(image_list_address, image_infos_size, image_info_buf) != - image_infos_size) { - return empty_reply_sp; - } - - /// First the image_infos array with (load addr, pathname, mod date) - /// tuples - - for (size_t i = 0; i < image_count; i++) { - struct binary_image_information info; - nub_addr_t pathname_address; - if (pointer_size == 4) { - uint32_t load_address_32; - uint32_t pathname_address_32; - uint32_t mod_date_32; - ::memcpy(&load_address_32, image_info_buf + (i * 3 * pointer_size), 4); - ::memcpy(&pathname_address_32, - image_info_buf + (i * 3 * pointer_size) + pointer_size, 4); - ::memcpy(&mod_date_32, - image_info_buf + (i * 3 * pointer_size) + pointer_size + - pointer_size, - 4); - info.load_address = load_address_32; - info.mod_date = mod_date_32; - pathname_address = pathname_address_32; - } else { - uint64_t load_address_64; - uint64_t pathname_address_64; - uint64_t mod_date_64; - ::memcpy(&load_address_64, image_info_buf + (i * 3 * pointer_size), 8); - ::memcpy(&pathname_address_64, - image_info_buf + (i * 3 * pointer_size) + pointer_size, 8); - ::memcpy(&mod_date_64, - image_info_buf + (i * 3 * pointer_size) + pointer_size + - pointer_size, - 8); - info.load_address = load_address_64; - info.mod_date = mod_date_64; - pathname_address = pathname_address_64; - } - char strbuf[17]; - info.filename = ""; - uint64_t pathname_ptr = pathname_address; - bool still_reading = true; - while (still_reading && ReadMemory(pathname_ptr, sizeof(strbuf) - 1, - strbuf) == sizeof(strbuf) - 1) { - strbuf[sizeof(strbuf) - 1] = '\0'; - info.filename += strbuf; - pathname_ptr += sizeof(strbuf) - 1; - // Stop if we found nul byte indicating the end of the string - for (size_t i = 0; i < sizeof(strbuf) - 1; i++) { - if (strbuf[i] == '\0') { - still_reading = false; - break; - } - } - } - uuid_clear(info.macho_info.uuid); - image_infos.push_back(info); - } - if (image_infos.size() == 0) { - return empty_reply_sp; - } - - free(image_info_buf); - - /// Second, read the mach header / load commands for all the dylibs - - for (size_t i = 0; i < image_count; i++) { - // The SPI to provide platform is not available on older systems. - uint32_t platform = 0; - if (GetMachOInformationFromMemory(platform, image_infos[i].load_address, - pointer_size, - image_infos[i].macho_info)) { - image_infos[i].is_valid_mach_header = true; - } - } - - /// Third, format all of the above in the JSONGenerator object. - - return FormatDynamicLibrariesIntoJSON(image_infos); -} - /// From dyld SPI header dyld_process_info.h typedef void *dyld_process_info; struct dyld_process_cache_info { @@ -1162,21 +1071,24 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) { // in // macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer. JSONGenerator::ObjectSP -MachProcess::GetAllLoadedLibrariesInfos(nub_process_t pid) { +MachProcess::GetAllLoadedLibrariesInfos(nub_process_t pid, + bool report_load_commands) { int pointer_size = GetInferiorAddrSize(pid); std::vector image_infos; GetAllLoadedBinariesViaDYLDSPI(image_infos); - uint32_t platform = GetPlatform(); - const size_t image_count = image_infos.size(); - for (size_t i = 0; i < image_count; i++) { - if (GetMachOInformationFromMemory(platform, image_infos[i].load_address, - pointer_size, - image_infos[i].macho_info)) { - image_infos[i].is_valid_mach_header = true; + if (report_load_commands) { + uint32_t platform = GetPlatform(); + const size_t image_count = image_infos.size(); + for (size_t i = 0; i < image_count; i++) { + if (GetMachOInformationFromMemory(platform, image_infos[i].load_address, + pointer_size, + image_infos[i].macho_info)) { + image_infos[i].is_valid_mach_header = true; + } } } - return FormatDynamicLibrariesIntoJSON(image_infos); + return FormatDynamicLibrariesIntoJSON(image_infos, report_load_commands); } // Fetch information about the shared libraries at the given load addresses @@ -1226,7 +1138,8 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) { image_infos[i].is_valid_mach_header = true; } } - return FormatDynamicLibrariesIntoJSON(image_infos); + return FormatDynamicLibrariesIntoJSON(image_infos, + /* report_load_commands = */ true); } // From dyld's internal podyld_process_info.h: diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index a9bda15607ea8..db0dc5fc4d166 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -5927,21 +5927,17 @@ rnb_err_t RNBRemote::HandlePacket_jThreadExtendedInfo(const char *p) { return SendPacket("OK"); } -// This packet may be called in one of three ways: -// -// jGetLoadedDynamicLibrariesInfos:{"image_count":40,"image_list_address":4295244704} -// Look for an array of the old dyld_all_image_infos style of binary infos -// at the image_list_address. -// This an array of {void* load_addr, void* mod_date, void* pathname} +// This packet may be called in one of two ways: // // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true} -// Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to -// get a list of all the -// libraries loaded +// Use the new dyld SPI to get a list of all the libraries loaded. +// If "report_load_commands":false" is present, only the dyld SPI +// provided information (load address, filepath) is returned. +// lldb can ask for the mach-o header/load command details in a +// separate packet. // // jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]} -// Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to -// get the information +// Use the dyld SPI and Mach-O parsing in memory to get the information // about the libraries loaded at these addresses. // rnb_err_t @@ -5964,24 +5960,17 @@ RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p) { std::vector macho_addresses; bool fetch_all_solibs = false; + bool report_load_commands = true; + get_boolean_value_for_key_name_from_json("report_load_commands", p, + report_load_commands); + if (get_boolean_value_for_key_name_from_json("fetch_all_solibs", p, fetch_all_solibs) && fetch_all_solibs) { - json_sp = DNBGetAllLoadedLibrariesInfos(pid); + json_sp = DNBGetAllLoadedLibrariesInfos(pid, report_load_commands); } else if (get_array_of_ints_value_for_key_name_from_json( "solib_addresses", p, macho_addresses)) { json_sp = DNBGetLibrariesInfoForAddresses(pid, macho_addresses); - } else { - nub_addr_t image_list_address = - get_integer_value_for_key_name_from_json("image_list_address", p); - nub_addr_t image_count = - get_integer_value_for_key_name_from_json("image_count", p); - - if (image_list_address != INVALID_NUB_ADDRESS && - image_count != INVALID_NUB_ADDRESS) { - json_sp = DNBGetLoadedDynamicLibrariesInfos(pid, image_list_address, - image_count); - } } if (json_sp.get()) { From 776bb279d6429ae8a47f05a903aef34dcd7f7657 Mon Sep 17 00:00:00 2001 From: William Huang Date: Tue, 9 May 2023 04:37:08 +0000 Subject: [PATCH 030/608] [llvm-profdata] ProfileReader cleanup - preparation for MD5 refactoring - 2 Cleanup profile reader classes to prepare for complex refactoring as propsed in D147740, continuing D148868 This is patch 2/n. This patch refactors CSNameTable and related things The decision to move CSNameTable up to the base class is because a planned improvement (D147740) to use MD5 to lookup Functions/Context frames. In this case we want a unified data structure between contextless function or Context frames, so that it can be mapped by MD5 value. Since Context Frames can represent contextless functions, it is being used for MD5 lookup, therefore exposing it to the base class Reviewed By: snehasish, wenlei Differential Revision: https://reviews.llvm.org/D148872 --- .../llvm/ProfileData/SampleProfReader.h | 17 ++--- llvm/lib/ProfileData/SampleProfReader.cpp | 63 ++++++++----------- 2 files changed, 35 insertions(+), 45 deletions(-) diff --git a/llvm/include/llvm/ProfileData/SampleProfReader.h b/llvm/include/llvm/ProfileData/SampleProfReader.h index 1849417f31ee2..a490e9ca6e723 100644 --- a/llvm/include/llvm/ProfileData/SampleProfReader.h +++ b/llvm/include/llvm/ProfileData/SampleProfReader.h @@ -657,6 +657,13 @@ class SampleProfileReaderBinary : public SampleProfileReader { /// Read a string indirectly via the name table. ErrorOr readStringFromTable(); + /// Read a context indirectly via the CSNameTable. + ErrorOr readContextFromTable(); + + /// Read a context indirectly via the CSNameTable if the profile has context, + /// otherwise same as readStringFromTable. + ErrorOr readSampleContextFromTable(); + /// Points to the current location in the buffer. const uint8_t *Data = nullptr; @@ -678,7 +685,9 @@ class SampleProfileReaderBinary : public SampleProfileReader { /// The starting address of NameTable containing fixed length MD5. const uint8_t *MD5NameMemStart = nullptr; - virtual ErrorOr readSampleContextFromTable(); + /// CSNameTable is used to save full context vectors. It is the backing buffer + /// for SampleContextFrames. + std::vector CSNameTable; private: std::error_code readSummaryEntry(std::vector &Entries); @@ -746,8 +755,6 @@ class SampleProfileReaderExtBinaryBase : public SampleProfileReaderBinary { const SecHdrTableEntry &Entry); // placeholder for subclasses to dispatch their own section readers. virtual std::error_code readCustomSection(const SecHdrTableEntry &Entry) = 0; - ErrorOr readSampleContextFromTable() override; - ErrorOr readContextFromTable(); std::unique_ptr ProfSymList; @@ -762,10 +769,6 @@ class SampleProfileReaderExtBinaryBase : public SampleProfileReaderBinary { /// The set containing the functions to use when compiling a module. DenseSet FuncsToUse; - /// CSNameTable is used to save full context vectors. This serves as an - /// underlying immutable buffer for all clients. - std::unique_ptr> CSNameTable; - /// If SkipFlatProf is true, skip the sections with /// SecFlagFlat flag. bool SkipFlatProf = false; diff --git a/llvm/lib/ProfileData/SampleProfReader.cpp b/llvm/lib/ProfileData/SampleProfReader.cpp index 977ea90039b00..964f7606d0c13 100644 --- a/llvm/lib/ProfileData/SampleProfReader.cpp +++ b/llvm/lib/ProfileData/SampleProfReader.cpp @@ -546,11 +546,27 @@ ErrorOr SampleProfileReaderBinary::readStringFromTable() { return SR; } -ErrorOr SampleProfileReaderBinary::readSampleContextFromTable() { - auto FName(readStringFromTable()); - if (std::error_code EC = FName.getError()) +ErrorOr SampleProfileReaderBinary::readContextFromTable() { + auto ContextIdx = readNumber(); + if (std::error_code EC = ContextIdx.getError()) return EC; - return SampleContext(*FName); + if (*ContextIdx >= CSNameTable.size()) + return sampleprof_error::truncated_name_table; + return CSNameTable[*ContextIdx]; +} + +ErrorOr SampleProfileReaderBinary::readSampleContextFromTable() { + if (ProfileIsCS) { + auto FContext(readContextFromTable()); + if (std::error_code EC = FContext.getError()) + return EC; + return SampleContext(*FContext); + } else { + auto FName(readStringFromTable()); + if (std::error_code EC = FName.getError()) + return EC; + return SampleContext(*FName); + } } std::error_code @@ -671,31 +687,6 @@ std::error_code SampleProfileReaderBinary::readImpl() { return sampleprof_error::success; } -ErrorOr -SampleProfileReaderExtBinaryBase::readContextFromTable() { - auto ContextIdx = readNumber(); - if (std::error_code EC = ContextIdx.getError()) - return EC; - if (*ContextIdx >= CSNameTable->size()) - return sampleprof_error::truncated_name_table; - return (*CSNameTable)[*ContextIdx]; -} - -ErrorOr -SampleProfileReaderExtBinaryBase::readSampleContextFromTable() { - if (ProfileIsCS) { - auto FContext(readContextFromTable()); - if (std::error_code EC = FContext.getError()) - return EC; - return SampleContext(*FContext); - } else { - auto FName(readStringFromTable()); - if (std::error_code EC = FName.getError()) - return EC; - return SampleContext(*FName); - } -} - std::error_code SampleProfileReaderExtBinaryBase::readOneSection( const uint8_t *Start, uint64_t Size, const SecHdrTableEntry &Entry) { Data = Start; @@ -1035,7 +1026,7 @@ std::error_code SampleProfileReaderExtBinaryBase::readNameTableSec(bool IsMD5, bool FixedLengthMD5) { if (FixedLengthMD5) { - if (IsMD5) + if (!IsMD5) errs() << "If FixedLengthMD5 is true, UseMD5 has to be true"; auto Size = readNumber(); if (std::error_code EC = Size.getError()) @@ -1089,11 +1080,10 @@ std::error_code SampleProfileReaderExtBinaryBase::readCSNameTableSec() { if (std::error_code EC = Size.getError()) return EC; - std::vector *PNameVec = - new std::vector(); - PNameVec->reserve(*Size); + CSNameTable.clear(); + CSNameTable.reserve(*Size); for (size_t I = 0; I < *Size; ++I) { - PNameVec->emplace_back(SampleContextFrameVector()); + CSNameTable.emplace_back(SampleContextFrameVector()); auto ContextSize = readNumber(); if (std::error_code EC = ContextSize.getError()) return EC; @@ -1112,18 +1102,15 @@ std::error_code SampleProfileReaderExtBinaryBase::readCSNameTableSec() { if (std::error_code EC = Discriminator.getError()) return EC; - PNameVec->back().emplace_back( + CSNameTable.back().emplace_back( FName.get(), LineLocation(LineOffset.get(), Discriminator.get())); } } - // From this point the underlying object of CSNameTable should be immutable. - CSNameTable.reset(PNameVec); return sampleprof_error::success; } std::error_code - SampleProfileReaderExtBinaryBase::readFuncMetadata(bool ProfileHasAttribute, FunctionSamples *FProfile) { if (Data < End) { From 2ba4cfd56769ab50c9c6f432f93265d7793bd1f2 Mon Sep 17 00:00:00 2001 From: luxufan Date: Fri, 5 May 2023 15:53:16 +0800 Subject: [PATCH 031/608] [ValutTracking] Use isGuaranteedNotToBePoison in impliesPoison Differential Revision: https://reviews.llvm.org/D149934 --- llvm/lib/Analysis/ValueTracking.cpp | 2 +- llvm/test/Transforms/InstCombine/2012-03-10-InstCombine.ll | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 6f6a16c8ee4c0..a27063c3f9aae 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6689,7 +6689,7 @@ static bool directlyImpliesPoison(const Value *ValAssumedPoison, static bool impliesPoison(const Value *ValAssumedPoison, const Value *V, unsigned Depth) { - if (isGuaranteedNotToBeUndefOrPoison(ValAssumedPoison)) + if (isGuaranteedNotToBePoison(ValAssumedPoison)) return true; if (directlyImpliesPoison(ValAssumedPoison, V, /* Depth */ 0)) diff --git a/llvm/test/Transforms/InstCombine/2012-03-10-InstCombine.ll b/llvm/test/Transforms/InstCombine/2012-03-10-InstCombine.ll index 9a2d5e6aa2ea3..457889d7bd352 100644 --- a/llvm/test/Transforms/InstCombine/2012-03-10-InstCombine.ll +++ b/llvm/test/Transforms/InstCombine/2012-03-10-InstCombine.ll @@ -60,12 +60,12 @@ define i32 @func_logical(ptr %c, ptr %f) nounwind uwtable readnone noinline ssp ; CHECK: if.then: ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule ptr [[D]], [[F:%.*]] ; CHECK-NEXT: [[NOT_CMP1:%.*]] = icmp uge ptr [[C]], [[F]] -; CHECK-NEXT: [[DOTCMP2:%.*]] = select i1 [[CMP2]], i1 [[NOT_CMP1]], i1 false +; CHECK-NEXT: [[DOTCMP2:%.*]] = and i1 [[CMP2]], [[NOT_CMP1]] ; CHECK-NEXT: br label [[RETURN:%.*]] ; CHECK: if.else: ; CHECK-NEXT: [[CMP5:%.*]] = icmp uge ptr [[D]], [[F]] ; CHECK-NEXT: [[NOT_CMP3:%.*]] = icmp ule ptr [[C]], [[F]] -; CHECK-NEXT: [[DOTCMP5:%.*]] = select i1 [[CMP5]], i1 [[NOT_CMP3]], i1 false +; CHECK-NEXT: [[DOTCMP5:%.*]] = and i1 [[CMP5]], [[NOT_CMP3]] ; CHECK-NEXT: br label [[RETURN]] ; CHECK: return: ; CHECK-NEXT: [[RETVAL_0_IN:%.*]] = phi i1 [ [[DOTCMP2]], [[IF_THEN]] ], [ [[DOTCMP5]], [[IF_ELSE]] ] From bff9fe9839090181eb77e979967a121de8996ef5 Mon Sep 17 00:00:00 2001 From: Jon Roelofs Date: Mon, 8 May 2023 21:52:12 -0700 Subject: [PATCH 032/608] CMake: add missing dependency on intrinsics_gen --- llvm/lib/MC/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt index 90f66e2ac52f3..c5f7e02c7c52e 100644 --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -79,6 +79,9 @@ add_llvm_component_library(LLVMMC TargetParser BinaryFormat DebugInfoCodeView + + DEPENDS + intrinsics_gen ) add_subdirectory(MCParser) From e1472db58ef501264547ac8c97be2bf7c481ec04 Mon Sep 17 00:00:00 2001 From: Amara Emerson Date: Sun, 7 May 2023 22:09:27 -0700 Subject: [PATCH 033/608] [GlobalISel] Implement commuting shl (add/or x, c1), c2 -> add/or (shl x, c2), c1 << c2 There's a target hook that's called in DAGCombiner that we stub here, I'll implement the equivalent override for AArch64 in a subsequent patch since it's used by different shift combine. This change by itself has minor code size improvements on arm64 -Os CTMark: Program size.__text outputg181ppyy output8av1cxfn diff consumer-typeset/consumer-typeset 410648.00 410648.00 0.0% tramp3d-v4/tramp3d-v4 364176.00 364176.00 0.0% kimwitu++/kc 449216.00 449212.00 -0.0% 7zip/7zip-benchmark 576128.00 576120.00 -0.0% sqlite3/sqlite3 285108.00 285100.00 -0.0% SPASS/SPASS 411720.00 411688.00 -0.0% ClamAV/clamscan 379868.00 379764.00 -0.0% Bullet/bullet 452064.00 451928.00 -0.0% mafft/pairlocalalign 246184.00 246108.00 -0.0% lencod/lencod 428524.00 428152.00 -0.1% Geomean difference -0.0% Differential Revision: https://reviews.llvm.org/D150086 --- .../llvm/CodeGen/GlobalISel/CombinerHelper.h | 2 + llvm/include/llvm/CodeGen/TargetLowering.h | 13 ++ .../include/llvm/Target/GlobalISel/Combine.td | 10 +- .../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 35 +++++ .../prelegalizercombiner-commute-shift.mir | 128 ++++++++++++++++++ .../test/CodeGen/AMDGPU/GlobalISel/add_shl.ll | 15 +- 6 files changed, 195 insertions(+), 8 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-commute-shift.mir diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h index f6c0764a6426c..ec3762094eacb 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h @@ -302,6 +302,8 @@ class CombinerHelper { void applyShiftOfShiftedLogic(MachineInstr &MI, ShiftOfShiftedLogic &MatchInfo); + bool matchCommuteShift(MachineInstr &MI, BuildFnTy &MatchInfo); + /// Transform a multiply by a power-of-2 value to a left shift. bool matchCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal); void applyCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal); diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 355091146d240..c458c820c8a18 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -4034,6 +4034,19 @@ class TargetLowering : public TargetLoweringBase { return true; } + /// GlobalISel - return true if it is profitable to move this shift by a + /// constant amount through its operand, adjusting any immediate operands as + /// necessary to preserve semantics. This transformation may not be desirable + /// if it disrupts a particularly auspicious target-specific tree (e.g. + /// bitfield extraction in AArch64). By default, it returns true. + /// + /// @param MI the shift instruction + /// @param IsAfterLegal true if running after legalization. + virtual bool isDesirableToCommuteWithShift(const MachineInstr &MI, + bool IsAfterLegal) const { + return true; + } + // Return AndOrSETCCFoldKind::{AddAnd, ABS} if its desirable to try and // optimize LogicOp(SETCC0, SETCC1). An example (what is implemented as of // writing this) is: diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td index c2054a689bd88..0c7048312e908 100644 --- a/llvm/include/llvm/Target/GlobalISel/Combine.td +++ b/llvm/include/llvm/Target/GlobalISel/Combine.td @@ -243,6 +243,14 @@ def reduce_shl_of_extend : GICombineRule< [{ return Helper.matchCombineShlOfExtend(*${mi}, ${matchinfo}); }]), (apply [{ Helper.applyCombineShlOfExtend(*${mi}, ${matchinfo}); }])>; +// Combine (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2) +// Combine (shl (or x, c1), c2) -> (or (shl x, c2), c1 << c2) +def commute_shift : GICombineRule< + (defs root:$d, build_fn_matchinfo:$matchinfo), + (match (wip_match_opcode G_SHL):$d, + [{ return Helper.matchCommuteShift(*${d}, ${matchinfo}); }]), + (apply [{ Helper.applyBuildFn(*${d}, ${matchinfo}); }])>; + def narrow_binop_feeding_and : GICombineRule< (defs root:$root, build_fn_matchinfo:$matchinfo), (match (wip_match_opcode G_AND):$root, @@ -1097,7 +1105,7 @@ def all_combines : GICombineGroup<[trivial_combines, insert_vec_elt_combines, unmerge_zext_to_zext, merge_unmerge, trunc_ext_fold, trunc_shift, const_combines, xor_of_and_with_same_reg, ptr_add_with_zero, shift_immed_chain, shift_of_shifted_logic_chain, load_or_combine, - div_rem_to_divrem, funnel_shift_combines, + div_rem_to_divrem, funnel_shift_combines, commute_shift, form_bitfield_extract, constant_fold, fabs_fneg_fold, intdiv_combines, mulh_combines, redundant_neg_operands, and_or_disjoint_mask, fma_combines, fold_binop_into_select, diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 0ddec2599803c..c7636c1a6ea3a 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -1624,6 +1624,41 @@ void CombinerHelper::applyShiftOfShiftedLogic(MachineInstr &MI, MI.eraseFromParent(); } +bool CombinerHelper::matchCommuteShift(MachineInstr &MI, BuildFnTy &MatchInfo) { + assert(MI.getOpcode() == TargetOpcode::G_SHL && "Expected G_SHL"); + // Combine (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2) + // Combine (shl (or x, c1), c2) -> (or (shl x, c2), c1 << c2) + auto &Shl = cast(MI); + Register DstReg = Shl.getReg(0); + Register SrcReg = Shl.getReg(1); + Register ShiftReg = Shl.getReg(2); + Register X, C1; + + if (!getTargetLowering().isDesirableToCommuteWithShift(MI, !isPreLegalize())) + return false; + + if (!mi_match(SrcReg, MRI, + m_OneNonDBGUse(m_any_of(m_GAdd(m_Reg(X), m_Reg(C1)), + m_GOr(m_Reg(X), m_Reg(C1)))))) + return false; + + APInt C1Val, C2Val; + if (!mi_match(C1, MRI, m_ICstOrSplat(C1Val)) || + !mi_match(ShiftReg, MRI, m_ICstOrSplat(C2Val))) + return false; + + auto *SrcDef = MRI.getVRegDef(SrcReg); + assert(SrcDef->getOpcode() == TargetOpcode::G_ADD || + SrcDef->getOpcode() == TargetOpcode::G_OR && "Unexpected op"); + LLT SrcTy = MRI.getType(SrcReg); + MatchInfo = [=](MachineIRBuilder &B) { + auto S1 = B.buildShl(SrcTy, X, ShiftReg); + auto S2 = B.buildShl(SrcTy, C1, ShiftReg); + B.buildInstr(SrcDef->getOpcode(), {DstReg}, {S1, S2}); + }; + return true; +} + bool CombinerHelper::matchCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal) { assert(MI.getOpcode() == TargetOpcode::G_MUL && "Expected a G_MUL"); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-commute-shift.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-commute-shift.mir new file mode 100644 index 0000000000000..d4800748374e0 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-commute-shift.mir @@ -0,0 +1,128 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2 +# RUN: llc -mtriple aarch64 -mattr=+fullfp16 -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s +--- +name: shl_add_k +alignment: 4 +tracksRegLiveness: true +body: | + bb.1: + liveins: $w1, $x0 + + ; CHECK-LABEL: name: shl_add_k + ; CHECK: liveins: $w1, $x0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 + ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]](s32) + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 4 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[SHL]], [[C1]] + ; CHECK-NEXT: G_STORE [[ADD]](s32), [[COPY]](p0) :: (store (s32)) + ; CHECK-NEXT: RET_ReallyLR + %0:_(p0) = COPY $x0 + %1:_(s32) = COPY $w1 + %2:_(s32) = G_CONSTANT i32 1 + %4:_(s32) = G_CONSTANT i32 2 + %3:_(s32) = G_ADD %1, %2 + %5:_(s32) = G_SHL %3, %4(s32) + G_STORE %5(s32), %0(p0) :: (store (s32)) + RET_ReallyLR + +... +--- +name: shl_or_k +alignment: 4 +tracksRegLiveness: true +body: | + bb.1: + liveins: $w1, $x0 + + ; CHECK-LABEL: name: shl_or_k + ; CHECK: liveins: $w1, $x0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 + ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]](s32) + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 4 + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[SHL]], [[C1]] + ; CHECK-NEXT: G_STORE [[OR]](s32), [[COPY]](p0) :: (store (s32)) + ; CHECK-NEXT: RET_ReallyLR + %0:_(p0) = COPY $x0 + %1:_(s32) = COPY $w1 + %2:_(s32) = G_CONSTANT i32 1 + %4:_(s32) = G_CONSTANT i32 2 + %3:_(s32) = G_OR %1, %2 + %5:_(s32) = G_SHL %3, %4(s32) + G_STORE %5(s32), %0(p0) :: (store (s32)) + RET_ReallyLR + +... +--- +name: shl_or_k_multiuse +alignment: 4 +tracksRegLiveness: true +body: | + bb.1: + liveins: $w1, $x0 + + ; CHECK-LABEL: name: shl_or_k_multiuse + ; CHECK: liveins: $w1, $x0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 + ; CHECK-NEXT: %ptr:_(p0) = COPY $x1 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[COPY1]], [[C]] + ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[OR]], [[C1]](s32) + ; CHECK-NEXT: G_STORE [[SHL]](s32), [[COPY]](p0) :: (store (s32)) + ; CHECK-NEXT: G_STORE [[OR]](s32), %ptr(p0) :: (store (s32)) + ; CHECK-NEXT: RET_ReallyLR + %0:_(p0) = COPY $x0 + %ptr:_(p0) = COPY $x1 + %1:_(s32) = COPY $w1 + %2:_(s32) = G_CONSTANT i32 1 + %4:_(s32) = G_CONSTANT i32 2 + %3:_(s32) = G_OR %1, %2 + %5:_(s32) = G_SHL %3, %4(s32) + G_STORE %5(s32), %0(p0) :: (store (s32)) + G_STORE %3(s32), %ptr(p0) :: (store (s32)) + RET_ReallyLR + +... +--- +name: shl_add_k_vector +alignment: 4 +tracksRegLiveness: true +body: | + bb.1: + liveins: $w1, $x0 + + ; CHECK-LABEL: name: shl_add_k_vector + ; CHECK: liveins: $w1, $x0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: %xvec:_(<4 x s32>) = G_BUILD_VECTOR [[COPY1]](s32), [[COPY1]](s32), [[COPY1]](s32), [[COPY1]](s32) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 + ; CHECK-NEXT: %veccst2:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32) + ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(<4 x s32>) = G_SHL %xvec, %veccst2(<4 x s32>) + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8 + ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C1]](s32), [[C1]](s32), [[C1]](s32) + ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<4 x s32>) = G_ADD [[SHL]], [[BUILD_VECTOR]] + ; CHECK-NEXT: G_STORE [[ADD]](<4 x s32>), [[COPY]](p0) :: (store (<4 x s32>)) + ; CHECK-NEXT: RET_ReallyLR + %0:_(p0) = COPY $x0 + %1:_(s32) = COPY $w1 + %xvec:_(<4 x s32>) = G_BUILD_VECTOR %1, %1, %1, %1 + %2:_(s32) = G_CONSTANT i32 1 + %veccst:_(<4 x s32>) = G_BUILD_VECTOR %2, %2, %2, %2 + %4:_(s32) = G_CONSTANT i32 2 + %veccst2:_(<4 x s32>) = G_BUILD_VECTOR %4, %4, %4, %4 + %3:_(<4 x s32>) = G_ADD %xvec, %veccst2 + %5:_(<4 x s32>) = G_SHL %3, %veccst2 + G_STORE %5(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + RET_ReallyLR + +... diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/add_shl.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/add_shl.ll index 141a31cbe9e72..a727ed39c79c6 100644 --- a/llvm/test/CodeGen/AMDGPU/GlobalISel/add_shl.ll +++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/add_shl.ll @@ -101,19 +101,19 @@ define amdgpu_ps float @add_shl_vgpr_const(i32 %a, i32 %b) { define amdgpu_ps float @add_shl_vgpr_const_inline_const(i32 %a) { ; VI-LABEL: add_shl_vgpr_const_inline_const: ; VI: ; %bb.0: -; VI-NEXT: v_add_u32_e32 v0, vcc, 0x3f4, v0 ; VI-NEXT: v_lshlrev_b32_e32 v0, 9, v0 +; VI-NEXT: v_add_u32_e32 v0, vcc, 0x7e800, v0 ; VI-NEXT: ; return to shader part epilog ; ; GFX9-LABEL: add_shl_vgpr_const_inline_const: ; GFX9: ; %bb.0: -; GFX9-NEXT: v_mov_b32_e32 v1, 0x3f4 -; GFX9-NEXT: v_add_lshl_u32 v0, v0, v1, 9 +; GFX9-NEXT: v_mov_b32_e32 v1, 0x7e800 +; GFX9-NEXT: v_lshl_add_u32 v0, v0, 9, v1 ; GFX9-NEXT: ; return to shader part epilog ; ; GFX10-LABEL: add_shl_vgpr_const_inline_const: ; GFX10: ; %bb.0: -; GFX10-NEXT: v_add_lshl_u32 v0, 0x3f4, v0, 9 +; GFX10-NEXT: v_lshl_add_u32 v0, v0, 9, 0x7e800 ; GFX10-NEXT: ; return to shader part epilog %x = add i32 %a, 1012 %result = shl i32 %x, 9 @@ -124,18 +124,19 @@ define amdgpu_ps float @add_shl_vgpr_const_inline_const(i32 %a) { define amdgpu_ps float @add_shl_vgpr_inline_const_x2(i32 %a) { ; VI-LABEL: add_shl_vgpr_inline_const_x2: ; VI: ; %bb.0: -; VI-NEXT: v_add_u32_e32 v0, vcc, 3, v0 ; VI-NEXT: v_lshlrev_b32_e32 v0, 9, v0 +; VI-NEXT: v_add_u32_e32 v0, vcc, 0x600, v0 ; VI-NEXT: ; return to shader part epilog ; ; GFX9-LABEL: add_shl_vgpr_inline_const_x2: ; GFX9: ; %bb.0: -; GFX9-NEXT: v_add_lshl_u32 v0, v0, 3, 9 +; GFX9-NEXT: v_mov_b32_e32 v1, 0x600 +; GFX9-NEXT: v_lshl_add_u32 v0, v0, 9, v1 ; GFX9-NEXT: ; return to shader part epilog ; ; GFX10-LABEL: add_shl_vgpr_inline_const_x2: ; GFX10: ; %bb.0: -; GFX10-NEXT: v_add_lshl_u32 v0, v0, 3, 9 +; GFX10-NEXT: v_lshl_add_u32 v0, v0, 9, 0x600 ; GFX10-NEXT: ; return to shader part epilog %x = add i32 %a, 3 %result = shl i32 %x, 9 From c60461e3f8154ade8e542e64d1711f975adac8d0 Mon Sep 17 00:00:00 2001 From: Shengchen Kan Date: Tue, 9 May 2023 14:05:30 +0800 Subject: [PATCH 034/608] Set mayLoad = 1 for shift/rotate with a memory operand --- llvm/lib/Target/X86/X86InstrShiftRotate.td | 4 +- .../X86/AlderlakeP/resources-x86_64.s | 48 +++++++++---------- .../llvm-mca/X86/Atom/resources-x86_64.s | 48 +++++++++---------- .../llvm-mca/X86/Barcelona/resources-x86_64.s | 48 +++++++++---------- .../llvm-mca/X86/BdVer2/resources-x86_64.s | 48 +++++++++---------- .../llvm-mca/X86/Broadwell/resources-x86_64.s | 48 +++++++++---------- .../X86/BtVer2/clear-super-register-2.s | 1 + .../tools/llvm-mca/X86/BtVer2/pipes-fpu.s | 1 + .../llvm-mca/X86/BtVer2/resources-x86_64.s | 48 +++++++++---------- .../X86/Generic/no-duplicate-symbols.s | 2 +- .../llvm-mca/X86/Generic/resources-x86_64.s | 48 +++++++++---------- .../llvm-mca/X86/Haswell/resources-x86_64.s | 48 +++++++++---------- .../X86/IceLakeServer/resources-x86_64.s | 48 +++++++++---------- .../tools/llvm-mca/X86/SLM/resources-x86_64.s | 48 +++++++++---------- .../X86/SandyBridge/resources-x86_64.s | 48 +++++++++---------- .../X86/SkylakeClient/resources-x86_64.s | 48 +++++++++---------- .../X86/SkylakeServer/resources-x86_64.s | 48 +++++++++---------- .../llvm-mca/X86/Znver1/resources-x86_64.s | 48 +++++++++---------- .../llvm-mca/X86/Znver2/resources-x86_64.s | 48 +++++++++---------- .../llvm-mca/X86/Znver3/resources-x86_64.s | 48 +++++++++---------- .../llvm-mca/X86/Znver4/resources-x86_64.s | 48 +++++++++---------- 21 files changed, 413 insertions(+), 411 deletions(-) diff --git a/llvm/lib/Target/X86/X86InstrShiftRotate.td b/llvm/lib/Target/X86/X86InstrShiftRotate.td index a485aabf29a0d..6a57ed1a6ee0f 100644 --- a/llvm/lib/Target/X86/X86InstrShiftRotate.td +++ b/llvm/lib/Target/X86/X86InstrShiftRotate.td @@ -396,7 +396,7 @@ def RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$cnt), } // Constraints = "$src = $dst" -let mayStore = 1 in { +let mayLoad = 1, mayStore = 1 in { let Uses = [EFLAGS], SchedRW = [WriteRotateLd, WriteRMW] in { def RCL8m1 : I<0xD0, MRM2m, (outs), (ins i8mem:$dst), "rcl{b}\t$dst", []>; @@ -456,7 +456,7 @@ def RCR64mCL : RI<0xD3, MRM3m, (outs), (ins i64mem:$dst), "rcr{q}\t{%cl, $dst|$dst, cl}", []>, Requires<[In64BitMode]>; } // Uses = [CL, EFLAGS], SchedRW -} // mayStore +} // mayLoad, mayStore } // hasSideEffects = 0 let Constraints = "$src1 = $dst" in { diff --git a/llvm/test/tools/llvm-mca/X86/AlderlakeP/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/AlderlakeP/resources-x86_64.s index b502ab3bf321d..ec303b4d9f2df 100644 --- a/llvm/test/tools/llvm-mca/X86/AlderlakeP/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/AlderlakeP/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 2 4 1.00 * * U pause # CHECK-NEXT: 3 2 1.00 rclb %dil # CHECK-NEXT: 3 2 1.00 rcrb %dil -# CHECK-NEXT: 6 13 1.00 * rclb (%rax) -# CHECK-NEXT: 6 13 1.00 * rcrb (%rax) +# CHECK-NEXT: 6 13 1.00 * * rclb (%rax) +# CHECK-NEXT: 6 13 1.00 * * rcrb (%rax) # CHECK-NEXT: 3 2 1.00 rclb $7, %dil # CHECK-NEXT: 3 2 1.00 rcrb $7, %dil -# CHECK-NEXT: 6 13 1.00 * rclb $7, (%rax) -# CHECK-NEXT: 6 13 1.00 * rcrb $7, (%rax) +# CHECK-NEXT: 6 13 1.00 * * rclb $7, (%rax) +# CHECK-NEXT: 6 13 1.00 * * rcrb $7, (%rax) # CHECK-NEXT: 9 7 2.50 rclb %cl, %dil # CHECK-NEXT: 10 9 3.00 rcrb %cl, %dil -# CHECK-NEXT: 11 20 2.50 * rclb %cl, (%rax) -# CHECK-NEXT: 12 20 3.00 * rcrb %cl, (%rax) +# CHECK-NEXT: 11 20 2.50 * * rclb %cl, (%rax) +# CHECK-NEXT: 12 20 3.00 * * rcrb %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rclw %di # CHECK-NEXT: 3 2 1.00 rcrw %di -# CHECK-NEXT: 6 12 1.00 * rclw (%rax) -# CHECK-NEXT: 6 12 1.00 * rcrw (%rax) +# CHECK-NEXT: 6 12 1.00 * * rclw (%rax) +# CHECK-NEXT: 6 12 1.00 * * rcrw (%rax) # CHECK-NEXT: 3 2 1.00 rclw $7, %di # CHECK-NEXT: 3 2 1.00 rcrw $7, %di -# CHECK-NEXT: 6 12 1.00 * rclw $7, (%rax) -# CHECK-NEXT: 6 12 1.00 * rcrw $7, (%rax) +# CHECK-NEXT: 6 12 1.00 * * rclw $7, (%rax) +# CHECK-NEXT: 6 12 1.00 * * rcrw $7, (%rax) # CHECK-NEXT: 7 8 2.00 rclw %cl, %di # CHECK-NEXT: 7 8 2.00 rcrw %cl, %di -# CHECK-NEXT: 10 19 2.00 * rclw %cl, (%rax) -# CHECK-NEXT: 10 19 2.00 * rcrw %cl, (%rax) +# CHECK-NEXT: 10 19 2.00 * * rclw %cl, (%rax) +# CHECK-NEXT: 10 19 2.00 * * rcrw %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rcll %edi # CHECK-NEXT: 3 2 1.00 rcrl %edi -# CHECK-NEXT: 6 12 1.00 * rcll (%rax) -# CHECK-NEXT: 6 12 1.00 * rcrl (%rax) +# CHECK-NEXT: 6 12 1.00 * * rcll (%rax) +# CHECK-NEXT: 6 12 1.00 * * rcrl (%rax) # CHECK-NEXT: 3 2 1.00 rcll $7, %edi # CHECK-NEXT: 3 2 1.00 rcrl $7, %edi -# CHECK-NEXT: 6 12 1.00 * rcll $7, (%rax) -# CHECK-NEXT: 6 12 1.00 * rcrl $7, (%rax) +# CHECK-NEXT: 6 12 1.00 * * rcll $7, (%rax) +# CHECK-NEXT: 6 12 1.00 * * rcrl $7, (%rax) # CHECK-NEXT: 7 8 2.00 rcll %cl, %edi # CHECK-NEXT: 7 8 2.00 rcrl %cl, %edi -# CHECK-NEXT: 10 19 2.00 * rcll %cl, (%rax) -# CHECK-NEXT: 10 19 2.00 * rcrl %cl, (%rax) +# CHECK-NEXT: 10 19 2.00 * * rcll %cl, (%rax) +# CHECK-NEXT: 10 19 2.00 * * rcrl %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rclq %rdi # CHECK-NEXT: 3 2 1.00 rcrq %rdi -# CHECK-NEXT: 6 12 1.00 * rclq (%rax) -# CHECK-NEXT: 6 12 1.00 * rcrq (%rax) +# CHECK-NEXT: 6 12 1.00 * * rclq (%rax) +# CHECK-NEXT: 6 12 1.00 * * rcrq (%rax) # CHECK-NEXT: 3 2 1.00 rclq $7, %rdi # CHECK-NEXT: 3 2 1.00 rcrq $7, %rdi -# CHECK-NEXT: 6 12 1.00 * rclq $7, (%rax) -# CHECK-NEXT: 6 12 1.00 * rcrq $7, (%rax) +# CHECK-NEXT: 6 12 1.00 * * rclq $7, (%rax) +# CHECK-NEXT: 6 12 1.00 * * rcrq $7, (%rax) # CHECK-NEXT: 7 8 2.00 rclq %cl, %rdi # CHECK-NEXT: 7 8 2.00 rcrq %cl, %rdi -# CHECK-NEXT: 10 19 2.00 * rclq %cl, (%rax) -# CHECK-NEXT: 10 19 2.00 * rcrq %cl, (%rax) +# CHECK-NEXT: 10 19 2.00 * * rclq %cl, (%rax) +# CHECK-NEXT: 10 19 2.00 * * rcrq %cl, (%rax) # CHECK-NEXT: 54 100 13.25 U rdmsr # CHECK-NEXT: 18 100 3.60 U rdpmc # CHECK-NEXT: 15 18 3.00 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/Atom/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/Atom/resources-x86_64.s index befe09cf856c2..2d7764627ef1b 100644 --- a/llvm/test/tools/llvm-mca/X86/Atom/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/Atom/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 1 17 8.50 * * U pause # CHECK-NEXT: 1 1 1.00 rclb %dil # CHECK-NEXT: 1 1 1.00 rcrb %dil -# CHECK-NEXT: 1 1 1.00 * rclb (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrb (%rax) +# CHECK-NEXT: 1 1 1.00 * * rclb (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrb (%rax) # CHECK-NEXT: 1 1 1.00 rclb $7, %dil # CHECK-NEXT: 1 1 1.00 rcrb $7, %dil -# CHECK-NEXT: 1 1 1.00 * rclb $7, (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrb $7, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rclb $7, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrb $7, (%rax) # CHECK-NEXT: 1 1 1.00 rclb %cl, %dil # CHECK-NEXT: 1 1 1.00 rcrb %cl, %dil -# CHECK-NEXT: 1 1 1.00 * rclb %cl, (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrb %cl, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rclb %cl, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrb %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rclw %di # CHECK-NEXT: 1 1 1.00 rcrw %di -# CHECK-NEXT: 1 1 1.00 * rclw (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrw (%rax) +# CHECK-NEXT: 1 1 1.00 * * rclw (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrw (%rax) # CHECK-NEXT: 1 1 1.00 rclw $7, %di # CHECK-NEXT: 1 1 1.00 rcrw $7, %di -# CHECK-NEXT: 1 1 1.00 * rclw $7, (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrw $7, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rclw $7, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrw $7, (%rax) # CHECK-NEXT: 1 1 1.00 rclw %cl, %di # CHECK-NEXT: 1 1 1.00 rcrw %cl, %di -# CHECK-NEXT: 1 1 1.00 * rclw %cl, (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrw %cl, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rclw %cl, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrw %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rcll %edi # CHECK-NEXT: 1 1 1.00 rcrl %edi -# CHECK-NEXT: 1 1 1.00 * rcll (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrl (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcll (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrl (%rax) # CHECK-NEXT: 1 1 1.00 rcll $7, %edi # CHECK-NEXT: 1 1 1.00 rcrl $7, %edi -# CHECK-NEXT: 1 1 1.00 * rcll $7, (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrl $7, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcll $7, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrl $7, (%rax) # CHECK-NEXT: 1 1 1.00 rcll %cl, %edi # CHECK-NEXT: 1 1 1.00 rcrl %cl, %edi -# CHECK-NEXT: 1 1 1.00 * rcll %cl, (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrl %cl, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcll %cl, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrl %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rclq %rdi # CHECK-NEXT: 1 1 1.00 rcrq %rdi -# CHECK-NEXT: 1 1 1.00 * rclq (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrq (%rax) +# CHECK-NEXT: 1 1 1.00 * * rclq (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrq (%rax) # CHECK-NEXT: 1 1 1.00 rclq $7, %rdi # CHECK-NEXT: 1 1 1.00 rcrq $7, %rdi -# CHECK-NEXT: 1 1 1.00 * rclq $7, (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrq $7, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rclq $7, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrq $7, (%rax) # CHECK-NEXT: 1 1 1.00 rclq %cl, %rdi # CHECK-NEXT: 1 1 1.00 rcrq %cl, %rdi -# CHECK-NEXT: 1 1 1.00 * rclq %cl, (%rax) -# CHECK-NEXT: 1 1 1.00 * rcrq %cl, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rclq %cl, (%rax) +# CHECK-NEXT: 1 1 1.00 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 78 39.00 U rdmsr # CHECK-NEXT: 1 46 23.00 U rdpmc # CHECK-NEXT: 1 30 15.00 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/Barcelona/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/Barcelona/resources-x86_64.s index 117025ab3d038..90cbb4891e75d 100644 --- a/llvm/test/tools/llvm-mca/X86/Barcelona/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/Barcelona/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 4 4 1.33 * * U pause # CHECK-NEXT: 3 2 1.00 rclb %dil # CHECK-NEXT: 3 2 1.00 rcrb %dil -# CHECK-NEXT: 11 11 3.50 * rclb (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrb (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclb (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrb (%rax) # CHECK-NEXT: 8 4 2.67 rclb $7, %dil # CHECK-NEXT: 8 3 2.67 rcrb $7, %dil -# CHECK-NEXT: 11 11 3.50 * rclb $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrb $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclb $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrb $7, (%rax) # CHECK-NEXT: 8 5 4.00 rclb %cl, %dil # CHECK-NEXT: 8 5 4.00 rcrb %cl, %dil -# CHECK-NEXT: 11 11 3.50 * rclb %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrb %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclb %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrb %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rclw %di # CHECK-NEXT: 3 2 1.00 rcrw %di -# CHECK-NEXT: 11 11 3.50 * rclw (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrw (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclw (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrw (%rax) # CHECK-NEXT: 8 4 2.67 rclw $7, %di # CHECK-NEXT: 8 3 2.67 rcrw $7, %di -# CHECK-NEXT: 11 11 3.50 * rclw $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrw $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclw $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrw $7, (%rax) # CHECK-NEXT: 8 5 4.00 rclw %cl, %di # CHECK-NEXT: 8 5 4.00 rcrw %cl, %di -# CHECK-NEXT: 11 11 3.50 * rclw %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrw %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclw %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrw %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rcll %edi # CHECK-NEXT: 3 2 1.00 rcrl %edi -# CHECK-NEXT: 11 11 3.50 * rcll (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrl (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcll (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrl (%rax) # CHECK-NEXT: 8 4 2.67 rcll $7, %edi # CHECK-NEXT: 8 3 2.67 rcrl $7, %edi -# CHECK-NEXT: 11 11 3.50 * rcll $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrl $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcll $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrl $7, (%rax) # CHECK-NEXT: 8 5 4.00 rcll %cl, %edi # CHECK-NEXT: 8 5 4.00 rcrl %cl, %edi -# CHECK-NEXT: 11 11 3.50 * rcll %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrl %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcll %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrl %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rclq %rdi # CHECK-NEXT: 3 2 1.00 rcrq %rdi -# CHECK-NEXT: 11 11 3.50 * rclq (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrq (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclq (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrq (%rax) # CHECK-NEXT: 8 4 2.67 rclq $7, %rdi # CHECK-NEXT: 8 3 2.67 rcrq $7, %rdi -# CHECK-NEXT: 11 11 3.50 * rclq $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrq $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclq $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrq $7, (%rax) # CHECK-NEXT: 8 5 4.00 rclq %cl, %rdi # CHECK-NEXT: 8 5 4.00 rcrq %cl, %rdi -# CHECK-NEXT: 11 11 3.50 * rclq %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrq %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclq %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.33 U rdmsr # CHECK-NEXT: 1 100 0.33 U rdpmc # CHECK-NEXT: 1 100 0.33 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/BdVer2/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/BdVer2/resources-x86_64.s index acd75d46fb23f..e7a0125bd0957 100644 --- a/llvm/test/tools/llvm-mca/X86/BdVer2/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/BdVer2/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 1 1 1.00 * * U pause # CHECK-NEXT: 1 1 1.00 rclb %dil # CHECK-NEXT: 1 1 1.00 rcrb %dil -# CHECK-NEXT: 2 5 2.00 * rclb (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrb (%rax) +# CHECK-NEXT: 2 5 2.00 * * rclb (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrb (%rax) # CHECK-NEXT: 25 13 12.50 rclb $7, %dil # CHECK-NEXT: 23 12 11.50 rcrb $7, %dil -# CHECK-NEXT: 2 5 2.00 * rclb $7, (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrb $7, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rclb $7, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrb $7, (%rax) # CHECK-NEXT: 26 12 12.00 rclb %cl, %dil # CHECK-NEXT: 24 11 11.00 rcrb %cl, %dil -# CHECK-NEXT: 2 5 2.00 * rclb %cl, (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrb %cl, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rclb %cl, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrb %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rclw %di # CHECK-NEXT: 1 1 1.00 rcrw %di -# CHECK-NEXT: 2 5 2.00 * rclw (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrw (%rax) +# CHECK-NEXT: 2 5 2.00 * * rclw (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrw (%rax) # CHECK-NEXT: 21 11 10.50 rclw $7, %di # CHECK-NEXT: 19 10 9.50 rcrw $7, %di -# CHECK-NEXT: 2 5 2.00 * rclw $7, (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrw $7, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rclw $7, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrw $7, (%rax) # CHECK-NEXT: 22 10 10.00 rclw %cl, %di # CHECK-NEXT: 20 9 9.00 rcrw %cl, %di -# CHECK-NEXT: 2 5 2.00 * rclw %cl, (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrw %cl, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rclw %cl, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrw %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rcll %edi # CHECK-NEXT: 1 1 1.00 rcrl %edi -# CHECK-NEXT: 2 5 2.00 * rcll (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrl (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcll (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrl (%rax) # CHECK-NEXT: 16 8 7.50 rcll $7, %edi # CHECK-NEXT: 15 7 7.00 rcrl $7, %edi -# CHECK-NEXT: 2 5 2.00 * rcll $7, (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrl $7, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcll $7, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrl $7, (%rax) # CHECK-NEXT: 17 7 7.00 rcll %cl, %edi # CHECK-NEXT: 16 7 6.50 rcrl %cl, %edi -# CHECK-NEXT: 2 5 2.00 * rcll %cl, (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrl %cl, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcll %cl, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrl %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rclq %rdi # CHECK-NEXT: 1 1 1.00 rcrq %rdi -# CHECK-NEXT: 2 5 2.00 * rclq (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrq (%rax) +# CHECK-NEXT: 2 5 2.00 * * rclq (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrq (%rax) # CHECK-NEXT: 16 8 7.50 rclq $7, %rdi # CHECK-NEXT: 15 7 7.00 rcrq $7, %rdi -# CHECK-NEXT: 2 5 2.00 * rclq $7, (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrq $7, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rclq $7, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrq $7, (%rax) # CHECK-NEXT: 17 7 7.00 rclq %cl, %rdi # CHECK-NEXT: 16 7 6.50 rcrq %cl, %rdi -# CHECK-NEXT: 2 5 2.00 * rclq %cl, (%rax) -# CHECK-NEXT: 2 5 2.00 * rcrq %cl, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rclq %cl, (%rax) +# CHECK-NEXT: 2 5 2.00 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.50 U rdmsr # CHECK-NEXT: 1 100 0.50 U rdpmc # CHECK-NEXT: 1 100 0.50 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/Broadwell/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/Broadwell/resources-x86_64.s index c68e2dd029135..2a8722665d588 100644 --- a/llvm/test/tools/llvm-mca/X86/Broadwell/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/Broadwell/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 5 5 1.25 * * U pause # CHECK-NEXT: 3 2 0.75 rclb %dil # CHECK-NEXT: 3 2 0.75 rcrb %dil -# CHECK-NEXT: 5 8 0.75 * rclb (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrb (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclb (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrb (%rax) # CHECK-NEXT: 8 6 2.00 rclb $7, %dil # CHECK-NEXT: 8 5 2.00 rcrb $7, %dil -# CHECK-NEXT: 5 8 0.75 * rclb $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrb $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclb $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrb $7, (%rax) # CHECK-NEXT: 9 11 2.25 rclb %cl, %dil # CHECK-NEXT: 10 14 2.50 rcrb %cl, %dil -# CHECK-NEXT: 10 15 2.00 * rclb %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrb %cl, (%rax) +# CHECK-NEXT: 10 15 2.00 * * rclb %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrb %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rclw %di # CHECK-NEXT: 3 2 0.75 rcrw %di -# CHECK-NEXT: 5 8 0.75 * rclw (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrw (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclw (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrw (%rax) # CHECK-NEXT: 8 6 2.00 rclw $7, %di # CHECK-NEXT: 8 5 2.00 rcrw $7, %di -# CHECK-NEXT: 5 8 0.75 * rclw $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrw $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclw $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrw $7, (%rax) # CHECK-NEXT: 7 11 2.00 rclw %cl, %di # CHECK-NEXT: 7 11 2.00 rcrw %cl, %di -# CHECK-NEXT: 10 15 2.00 * rclw %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrw %cl, (%rax) +# CHECK-NEXT: 10 15 2.00 * * rclw %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrw %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rcll %edi # CHECK-NEXT: 3 2 0.75 rcrl %edi -# CHECK-NEXT: 5 8 0.75 * rcll (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrl (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcll (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrl (%rax) # CHECK-NEXT: 8 6 2.00 rcll $7, %edi # CHECK-NEXT: 8 5 2.00 rcrl $7, %edi -# CHECK-NEXT: 5 8 0.75 * rcll $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrl $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcll $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrl $7, (%rax) # CHECK-NEXT: 7 11 2.00 rcll %cl, %edi # CHECK-NEXT: 7 11 2.00 rcrl %cl, %edi -# CHECK-NEXT: 10 15 2.00 * rcll %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrl %cl, (%rax) +# CHECK-NEXT: 10 15 2.00 * * rcll %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrl %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rclq %rdi # CHECK-NEXT: 3 2 0.75 rcrq %rdi -# CHECK-NEXT: 5 8 0.75 * rclq (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrq (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclq (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrq (%rax) # CHECK-NEXT: 8 6 2.00 rclq $7, %rdi # CHECK-NEXT: 8 5 2.00 rcrq $7, %rdi -# CHECK-NEXT: 5 8 0.75 * rclq $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrq $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclq $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrq $7, (%rax) # CHECK-NEXT: 7 11 2.00 rclq %cl, %rdi # CHECK-NEXT: 7 11 2.00 rcrq %cl, %rdi -# CHECK-NEXT: 10 15 2.00 * rclq %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrq %cl, (%rax) +# CHECK-NEXT: 10 15 2.00 * * rclq %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.25 U rdmsr # CHECK-NEXT: 1 100 0.25 U rdpmc # CHECK-NEXT: 8 18 2.00 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/BtVer2/clear-super-register-2.s b/llvm/test/tools/llvm-mca/X86/BtVer2/clear-super-register-2.s index 987c54a07567d..134e83f73fb12 100644 --- a/llvm/test/tools/llvm-mca/X86/BtVer2/clear-super-register-2.s +++ b/llvm/test/tools/llvm-mca/X86/BtVer2/clear-super-register-2.s @@ -95,6 +95,7 @@ vandps %xmm4, %xmm1, %xmm0 # CHECK-NEXT: [1,1] . . . . D=================eeeE-------------------------------------R. vaddps %xmm0, %xmm1, %xmm3 # CHECK-NEXT: [1,2] . . . . D===================eeeE-----------------------------------R vaddps %ymm3, %ymm1, %ymm4 # CHECK-NEXT: [1,3] . . . . .D====================eeeE---------------------------------R vaddps %ymm3, %ymm1, %ymm4 +# CHECK-NEXT: Truncated display due to cycle limit # CHECK: Average Wait times (based on the timeline view): # CHECK-NEXT: [0]: Executions diff --git a/llvm/test/tools/llvm-mca/X86/BtVer2/pipes-fpu.s b/llvm/test/tools/llvm-mca/X86/BtVer2/pipes-fpu.s index 41f014fa09e47..55755d74f51e5 100644 --- a/llvm/test/tools/llvm-mca/X86/BtVer2/pipes-fpu.s +++ b/llvm/test/tools/llvm-mca/X86/BtVer2/pipes-fpu.s @@ -93,6 +93,7 @@ vsqrtps %ymm0, %ymm2 # CHECK-NEXT: [1,2] . . DeeeE--------------------------------------------------------R. vcvttps2dq %xmm0, %xmm2 # CHECK-NEXT: [1,3] . . DeeE----------------------------------------------------------R vpclmulqdq $0, %xmm0, %xmm1, %xmm2 # CHECK-NEXT: [1,4] . . DeeeE--------------------------------------------------------R vaddps %xmm0, %xmm1, %xmm2 +# CHECK-NEXT: Truncated display due to cycle limit # CHECK: Average Wait times (based on the timeline view): # CHECK-NEXT: [0]: Executions diff --git a/llvm/test/tools/llvm-mca/X86/BtVer2/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/BtVer2/resources-x86_64.s index a24bc33c5018b..ab6945ec523f1 100644 --- a/llvm/test/tools/llvm-mca/X86/BtVer2/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/BtVer2/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 1 1 0.50 * * U pause # CHECK-NEXT: 1 1 0.50 rclb %dil # CHECK-NEXT: 1 1 0.50 rcrb %dil -# CHECK-NEXT: 1 4 1.00 * rclb (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrb (%rax) +# CHECK-NEXT: 1 4 1.00 * * rclb (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrb (%rax) # CHECK-NEXT: 1 1 0.50 rclb $7, %dil # CHECK-NEXT: 1 1 0.50 rcrb $7, %dil -# CHECK-NEXT: 1 4 1.00 * rclb $7, (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrb $7, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rclb $7, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrb $7, (%rax) # CHECK-NEXT: 1 1 0.50 rclb %cl, %dil # CHECK-NEXT: 1 1 0.50 rcrb %cl, %dil -# CHECK-NEXT: 1 4 1.00 * rclb %cl, (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrb %cl, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rclb %cl, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrb %cl, (%rax) # CHECK-NEXT: 1 1 0.50 rclw %di # CHECK-NEXT: 1 1 0.50 rcrw %di -# CHECK-NEXT: 1 4 1.00 * rclw (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrw (%rax) +# CHECK-NEXT: 1 4 1.00 * * rclw (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrw (%rax) # CHECK-NEXT: 1 1 0.50 rclw $7, %di # CHECK-NEXT: 1 1 0.50 rcrw $7, %di -# CHECK-NEXT: 1 4 1.00 * rclw $7, (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrw $7, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rclw $7, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrw $7, (%rax) # CHECK-NEXT: 1 1 0.50 rclw %cl, %di # CHECK-NEXT: 1 1 0.50 rcrw %cl, %di -# CHECK-NEXT: 1 4 1.00 * rclw %cl, (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrw %cl, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rclw %cl, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrw %cl, (%rax) # CHECK-NEXT: 1 1 0.50 rcll %edi # CHECK-NEXT: 1 1 0.50 rcrl %edi -# CHECK-NEXT: 1 4 1.00 * rcll (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrl (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcll (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrl (%rax) # CHECK-NEXT: 1 1 0.50 rcll $7, %edi # CHECK-NEXT: 1 1 0.50 rcrl $7, %edi -# CHECK-NEXT: 1 4 1.00 * rcll $7, (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrl $7, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcll $7, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrl $7, (%rax) # CHECK-NEXT: 1 1 0.50 rcll %cl, %edi # CHECK-NEXT: 1 1 0.50 rcrl %cl, %edi -# CHECK-NEXT: 1 4 1.00 * rcll %cl, (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrl %cl, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcll %cl, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrl %cl, (%rax) # CHECK-NEXT: 1 1 0.50 rclq %rdi # CHECK-NEXT: 1 1 0.50 rcrq %rdi -# CHECK-NEXT: 1 4 1.00 * rclq (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrq (%rax) +# CHECK-NEXT: 1 4 1.00 * * rclq (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrq (%rax) # CHECK-NEXT: 1 1 0.50 rclq $7, %rdi # CHECK-NEXT: 1 1 0.50 rcrq $7, %rdi -# CHECK-NEXT: 1 4 1.00 * rclq $7, (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrq $7, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rclq $7, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrq $7, (%rax) # CHECK-NEXT: 1 1 0.50 rclq %cl, %rdi # CHECK-NEXT: 1 1 0.50 rcrq %cl, %rdi -# CHECK-NEXT: 1 4 1.00 * rclq %cl, (%rax) -# CHECK-NEXT: 1 4 1.00 * rcrq %cl, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rclq %cl, (%rax) +# CHECK-NEXT: 1 4 1.00 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.50 U rdmsr # CHECK-NEXT: 1 100 0.50 U rdpmc # CHECK-NEXT: 1 100 0.50 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/Generic/no-duplicate-symbols.s b/llvm/test/tools/llvm-mca/X86/Generic/no-duplicate-symbols.s index 8b8144c08b857..e8b8b86a2107c 100644 --- a/llvm/test/tools/llvm-mca/X86/Generic/no-duplicate-symbols.s +++ b/llvm/test/tools/llvm-mca/X86/Generic/no-duplicate-symbols.s @@ -1,3 +1,4 @@ +# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py # RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=x86-64 < %s 2>&1 | FileCheck %s # This test checks that https://github.com/llvm/llvm-project/issues/62528 is resolved. @@ -5,4 +6,3 @@ foo: pushq %rbp # CHECK-NOT: :4:1: error: symbol 'foo' is already defined - diff --git a/llvm/test/tools/llvm-mca/X86/Generic/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/Generic/resources-x86_64.s index 117025ab3d038..90cbb4891e75d 100644 --- a/llvm/test/tools/llvm-mca/X86/Generic/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/Generic/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 4 4 1.33 * * U pause # CHECK-NEXT: 3 2 1.00 rclb %dil # CHECK-NEXT: 3 2 1.00 rcrb %dil -# CHECK-NEXT: 11 11 3.50 * rclb (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrb (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclb (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrb (%rax) # CHECK-NEXT: 8 4 2.67 rclb $7, %dil # CHECK-NEXT: 8 3 2.67 rcrb $7, %dil -# CHECK-NEXT: 11 11 3.50 * rclb $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrb $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclb $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrb $7, (%rax) # CHECK-NEXT: 8 5 4.00 rclb %cl, %dil # CHECK-NEXT: 8 5 4.00 rcrb %cl, %dil -# CHECK-NEXT: 11 11 3.50 * rclb %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrb %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclb %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrb %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rclw %di # CHECK-NEXT: 3 2 1.00 rcrw %di -# CHECK-NEXT: 11 11 3.50 * rclw (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrw (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclw (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrw (%rax) # CHECK-NEXT: 8 4 2.67 rclw $7, %di # CHECK-NEXT: 8 3 2.67 rcrw $7, %di -# CHECK-NEXT: 11 11 3.50 * rclw $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrw $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclw $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrw $7, (%rax) # CHECK-NEXT: 8 5 4.00 rclw %cl, %di # CHECK-NEXT: 8 5 4.00 rcrw %cl, %di -# CHECK-NEXT: 11 11 3.50 * rclw %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrw %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclw %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrw %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rcll %edi # CHECK-NEXT: 3 2 1.00 rcrl %edi -# CHECK-NEXT: 11 11 3.50 * rcll (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrl (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcll (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrl (%rax) # CHECK-NEXT: 8 4 2.67 rcll $7, %edi # CHECK-NEXT: 8 3 2.67 rcrl $7, %edi -# CHECK-NEXT: 11 11 3.50 * rcll $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrl $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcll $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrl $7, (%rax) # CHECK-NEXT: 8 5 4.00 rcll %cl, %edi # CHECK-NEXT: 8 5 4.00 rcrl %cl, %edi -# CHECK-NEXT: 11 11 3.50 * rcll %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrl %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcll %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrl %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rclq %rdi # CHECK-NEXT: 3 2 1.00 rcrq %rdi -# CHECK-NEXT: 11 11 3.50 * rclq (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrq (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclq (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrq (%rax) # CHECK-NEXT: 8 4 2.67 rclq $7, %rdi # CHECK-NEXT: 8 3 2.67 rcrq $7, %rdi -# CHECK-NEXT: 11 11 3.50 * rclq $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrq $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclq $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrq $7, (%rax) # CHECK-NEXT: 8 5 4.00 rclq %cl, %rdi # CHECK-NEXT: 8 5 4.00 rcrq %cl, %rdi -# CHECK-NEXT: 11 11 3.50 * rclq %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrq %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclq %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.33 U rdmsr # CHECK-NEXT: 1 100 0.33 U rdpmc # CHECK-NEXT: 1 100 0.33 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/Haswell/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/Haswell/resources-x86_64.s index 073e23d90fdb8..5607ae2b6ebd9 100644 --- a/llvm/test/tools/llvm-mca/X86/Haswell/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/Haswell/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 5 5 1.25 * * U pause # CHECK-NEXT: 3 2 0.75 rclb %dil # CHECK-NEXT: 3 2 0.75 rcrb %dil -# CHECK-NEXT: 5 9 0.75 * rclb (%rax) -# CHECK-NEXT: 5 9 0.75 * rcrb (%rax) +# CHECK-NEXT: 5 9 0.75 * * rclb (%rax) +# CHECK-NEXT: 5 9 0.75 * * rcrb (%rax) # CHECK-NEXT: 8 6 2.00 rclb $7, %dil # CHECK-NEXT: 8 5 2.00 rcrb $7, %dil -# CHECK-NEXT: 5 9 0.75 * rclb $7, (%rax) -# CHECK-NEXT: 5 9 0.75 * rcrb $7, (%rax) +# CHECK-NEXT: 5 9 0.75 * * rclb $7, (%rax) +# CHECK-NEXT: 5 9 0.75 * * rcrb $7, (%rax) # CHECK-NEXT: 9 11 2.25 rclb %cl, %dil # CHECK-NEXT: 10 14 2.50 rcrb %cl, %dil -# CHECK-NEXT: 10 16 2.00 * rclb %cl, (%rax) -# CHECK-NEXT: 11 19 2.25 * rcrb %cl, (%rax) +# CHECK-NEXT: 10 16 2.00 * * rclb %cl, (%rax) +# CHECK-NEXT: 11 19 2.25 * * rcrb %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rclw %di # CHECK-NEXT: 3 2 0.75 rcrw %di -# CHECK-NEXT: 5 9 0.75 * rclw (%rax) -# CHECK-NEXT: 5 9 0.75 * rcrw (%rax) +# CHECK-NEXT: 5 9 0.75 * * rclw (%rax) +# CHECK-NEXT: 5 9 0.75 * * rcrw (%rax) # CHECK-NEXT: 8 6 2.00 rclw $7, %di # CHECK-NEXT: 8 5 2.00 rcrw $7, %di -# CHECK-NEXT: 5 9 0.75 * rclw $7, (%rax) -# CHECK-NEXT: 5 9 0.75 * rcrw $7, (%rax) +# CHECK-NEXT: 5 9 0.75 * * rclw $7, (%rax) +# CHECK-NEXT: 5 9 0.75 * * rcrw $7, (%rax) # CHECK-NEXT: 7 11 2.00 rclw %cl, %di # CHECK-NEXT: 7 11 2.00 rcrw %cl, %di -# CHECK-NEXT: 10 16 2.00 * rclw %cl, (%rax) -# CHECK-NEXT: 11 19 2.25 * rcrw %cl, (%rax) +# CHECK-NEXT: 10 16 2.00 * * rclw %cl, (%rax) +# CHECK-NEXT: 11 19 2.25 * * rcrw %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rcll %edi # CHECK-NEXT: 3 2 0.75 rcrl %edi -# CHECK-NEXT: 5 9 0.75 * rcll (%rax) -# CHECK-NEXT: 5 9 0.75 * rcrl (%rax) +# CHECK-NEXT: 5 9 0.75 * * rcll (%rax) +# CHECK-NEXT: 5 9 0.75 * * rcrl (%rax) # CHECK-NEXT: 8 6 2.00 rcll $7, %edi # CHECK-NEXT: 8 5 2.00 rcrl $7, %edi -# CHECK-NEXT: 5 9 0.75 * rcll $7, (%rax) -# CHECK-NEXT: 5 9 0.75 * rcrl $7, (%rax) +# CHECK-NEXT: 5 9 0.75 * * rcll $7, (%rax) +# CHECK-NEXT: 5 9 0.75 * * rcrl $7, (%rax) # CHECK-NEXT: 7 11 2.00 rcll %cl, %edi # CHECK-NEXT: 7 11 2.00 rcrl %cl, %edi -# CHECK-NEXT: 10 16 2.00 * rcll %cl, (%rax) -# CHECK-NEXT: 11 19 2.25 * rcrl %cl, (%rax) +# CHECK-NEXT: 10 16 2.00 * * rcll %cl, (%rax) +# CHECK-NEXT: 11 19 2.25 * * rcrl %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rclq %rdi # CHECK-NEXT: 3 2 0.75 rcrq %rdi -# CHECK-NEXT: 5 9 0.75 * rclq (%rax) -# CHECK-NEXT: 5 9 0.75 * rcrq (%rax) +# CHECK-NEXT: 5 9 0.75 * * rclq (%rax) +# CHECK-NEXT: 5 9 0.75 * * rcrq (%rax) # CHECK-NEXT: 8 6 2.00 rclq $7, %rdi # CHECK-NEXT: 8 5 2.00 rcrq $7, %rdi -# CHECK-NEXT: 5 9 0.75 * rclq $7, (%rax) -# CHECK-NEXT: 5 9 0.75 * rcrq $7, (%rax) +# CHECK-NEXT: 5 9 0.75 * * rclq $7, (%rax) +# CHECK-NEXT: 5 9 0.75 * * rcrq $7, (%rax) # CHECK-NEXT: 7 11 2.00 rclq %cl, %rdi # CHECK-NEXT: 7 11 2.00 rcrq %cl, %rdi -# CHECK-NEXT: 10 16 2.00 * rclq %cl, (%rax) -# CHECK-NEXT: 11 19 2.25 * rcrq %cl, (%rax) +# CHECK-NEXT: 10 16 2.00 * * rclq %cl, (%rax) +# CHECK-NEXT: 11 19 2.25 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.25 U rdmsr # CHECK-NEXT: 34 1 8.50 U rdpmc # CHECK-NEXT: 8 18 2.00 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/IceLakeServer/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/IceLakeServer/resources-x86_64.s index 178512d9be16a..1336314550335 100644 --- a/llvm/test/tools/llvm-mca/X86/IceLakeServer/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/IceLakeServer/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 4 140 1.00 * * U pause # CHECK-NEXT: 3 2 0.75 rclb %dil # CHECK-NEXT: 3 2 0.75 rcrb %dil -# CHECK-NEXT: 5 8 0.75 * rclb (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrb (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclb (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrb (%rax) # CHECK-NEXT: 7 6 2.00 rclb $7, %dil # CHECK-NEXT: 7 5 2.00 rcrb $7, %dil -# CHECK-NEXT: 5 8 0.75 * rclb $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrb $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclb $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrb $7, (%rax) # CHECK-NEXT: 9 11 2.50 rclb %cl, %dil # CHECK-NEXT: 10 14 2.50 rcrb %cl, %dil -# CHECK-NEXT: 10 15 2.50 * rclb %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrb %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rclb %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrb %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rclw %di # CHECK-NEXT: 3 2 0.75 rcrw %di -# CHECK-NEXT: 5 8 0.75 * rclw (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrw (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclw (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrw (%rax) # CHECK-NEXT: 7 6 2.00 rclw $7, %di # CHECK-NEXT: 7 5 2.00 rcrw $7, %di -# CHECK-NEXT: 5 8 0.75 * rclw $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrw $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclw $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrw $7, (%rax) # CHECK-NEXT: 7 11 2.00 rclw %cl, %di # CHECK-NEXT: 7 11 2.00 rcrw %cl, %di -# CHECK-NEXT: 10 15 2.50 * rclw %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrw %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rclw %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrw %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rcll %edi # CHECK-NEXT: 3 2 0.75 rcrl %edi -# CHECK-NEXT: 5 8 0.75 * rcll (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrl (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcll (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrl (%rax) # CHECK-NEXT: 7 6 2.00 rcll $7, %edi # CHECK-NEXT: 7 5 2.00 rcrl $7, %edi -# CHECK-NEXT: 5 8 0.75 * rcll $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrl $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcll $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrl $7, (%rax) # CHECK-NEXT: 7 11 2.00 rcll %cl, %edi # CHECK-NEXT: 7 11 2.00 rcrl %cl, %edi -# CHECK-NEXT: 10 15 2.50 * rcll %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrl %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rcll %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrl %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rclq %rdi # CHECK-NEXT: 3 2 0.75 rcrq %rdi -# CHECK-NEXT: 5 8 0.75 * rclq (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrq (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclq (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrq (%rax) # CHECK-NEXT: 7 6 2.00 rclq $7, %rdi # CHECK-NEXT: 7 5 2.00 rcrq $7, %rdi -# CHECK-NEXT: 5 8 0.75 * rclq $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrq $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclq $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrq $7, (%rax) # CHECK-NEXT: 7 11 2.00 rclq %cl, %rdi # CHECK-NEXT: 7 11 2.00 rcrq %cl, %rdi -# CHECK-NEXT: 10 15 2.50 * rclq %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrq %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rclq %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.25 U rdmsr # CHECK-NEXT: 1 100 0.25 U rdpmc # CHECK-NEXT: 8 18 2.00 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/SLM/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/SLM/resources-x86_64.s index c65d7fa4f7439..e597e976f1029 100644 --- a/llvm/test/tools/llvm-mca/X86/SLM/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/SLM/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 1 1 0.50 * * U pause # CHECK-NEXT: 1 1 1.00 rclb %dil # CHECK-NEXT: 1 1 1.00 rcrb %dil -# CHECK-NEXT: 1 4 2.00 * rclb (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrb (%rax) +# CHECK-NEXT: 1 4 2.00 * * rclb (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrb (%rax) # CHECK-NEXT: 1 1 1.00 rclb $7, %dil # CHECK-NEXT: 1 1 1.00 rcrb $7, %dil -# CHECK-NEXT: 1 4 2.00 * rclb $7, (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrb $7, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rclb $7, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrb $7, (%rax) # CHECK-NEXT: 1 1 1.00 rclb %cl, %dil # CHECK-NEXT: 1 1 1.00 rcrb %cl, %dil -# CHECK-NEXT: 1 4 2.00 * rclb %cl, (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrb %cl, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rclb %cl, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrb %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rclw %di # CHECK-NEXT: 1 1 1.00 rcrw %di -# CHECK-NEXT: 1 4 2.00 * rclw (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrw (%rax) +# CHECK-NEXT: 1 4 2.00 * * rclw (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrw (%rax) # CHECK-NEXT: 1 1 1.00 rclw $7, %di # CHECK-NEXT: 1 1 1.00 rcrw $7, %di -# CHECK-NEXT: 1 4 2.00 * rclw $7, (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrw $7, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rclw $7, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrw $7, (%rax) # CHECK-NEXT: 1 1 1.00 rclw %cl, %di # CHECK-NEXT: 1 1 1.00 rcrw %cl, %di -# CHECK-NEXT: 1 4 2.00 * rclw %cl, (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrw %cl, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rclw %cl, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrw %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rcll %edi # CHECK-NEXT: 1 1 1.00 rcrl %edi -# CHECK-NEXT: 1 4 2.00 * rcll (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrl (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcll (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrl (%rax) # CHECK-NEXT: 1 1 1.00 rcll $7, %edi # CHECK-NEXT: 1 1 1.00 rcrl $7, %edi -# CHECK-NEXT: 1 4 2.00 * rcll $7, (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrl $7, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcll $7, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrl $7, (%rax) # CHECK-NEXT: 1 1 1.00 rcll %cl, %edi # CHECK-NEXT: 1 1 1.00 rcrl %cl, %edi -# CHECK-NEXT: 1 4 2.00 * rcll %cl, (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrl %cl, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcll %cl, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrl %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rclq %rdi # CHECK-NEXT: 1 1 1.00 rcrq %rdi -# CHECK-NEXT: 1 4 2.00 * rclq (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrq (%rax) +# CHECK-NEXT: 1 4 2.00 * * rclq (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrq (%rax) # CHECK-NEXT: 1 1 1.00 rclq $7, %rdi # CHECK-NEXT: 1 1 1.00 rcrq $7, %rdi -# CHECK-NEXT: 1 4 2.00 * rclq $7, (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrq $7, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rclq $7, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrq $7, (%rax) # CHECK-NEXT: 1 1 1.00 rclq %cl, %rdi # CHECK-NEXT: 1 1 1.00 rcrq %cl, %rdi -# CHECK-NEXT: 1 4 2.00 * rclq %cl, (%rax) -# CHECK-NEXT: 1 4 2.00 * rcrq %cl, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rclq %cl, (%rax) +# CHECK-NEXT: 1 4 2.00 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 1.00 U rdmsr # CHECK-NEXT: 1 100 1.00 U rdpmc # CHECK-NEXT: 1 100 1.00 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/SandyBridge/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/SandyBridge/resources-x86_64.s index c1fad00fbdf09..974fbdd04cec1 100644 --- a/llvm/test/tools/llvm-mca/X86/SandyBridge/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/SandyBridge/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 4 4 1.33 * * U pause # CHECK-NEXT: 3 2 1.00 rclb %dil # CHECK-NEXT: 3 2 1.00 rcrb %dil -# CHECK-NEXT: 11 11 3.50 * rclb (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrb (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclb (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrb (%rax) # CHECK-NEXT: 8 4 2.67 rclb $7, %dil # CHECK-NEXT: 8 3 2.67 rcrb $7, %dil -# CHECK-NEXT: 11 11 3.50 * rclb $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrb $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclb $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrb $7, (%rax) # CHECK-NEXT: 8 5 4.00 rclb %cl, %dil # CHECK-NEXT: 8 5 4.00 rcrb %cl, %dil -# CHECK-NEXT: 11 11 3.50 * rclb %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrb %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclb %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrb %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rclw %di # CHECK-NEXT: 3 2 1.00 rcrw %di -# CHECK-NEXT: 11 11 3.50 * rclw (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrw (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclw (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrw (%rax) # CHECK-NEXT: 8 4 2.67 rclw $7, %di # CHECK-NEXT: 8 3 2.67 rcrw $7, %di -# CHECK-NEXT: 11 11 3.50 * rclw $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrw $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclw $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrw $7, (%rax) # CHECK-NEXT: 8 5 4.00 rclw %cl, %di # CHECK-NEXT: 8 5 4.00 rcrw %cl, %di -# CHECK-NEXT: 11 11 3.50 * rclw %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrw %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclw %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrw %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rcll %edi # CHECK-NEXT: 3 2 1.00 rcrl %edi -# CHECK-NEXT: 11 11 3.50 * rcll (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrl (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcll (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrl (%rax) # CHECK-NEXT: 8 4 2.67 rcll $7, %edi # CHECK-NEXT: 8 3 2.67 rcrl $7, %edi -# CHECK-NEXT: 11 11 3.50 * rcll $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrl $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcll $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrl $7, (%rax) # CHECK-NEXT: 8 5 4.00 rcll %cl, %edi # CHECK-NEXT: 8 5 4.00 rcrl %cl, %edi -# CHECK-NEXT: 11 11 3.50 * rcll %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrl %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcll %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrl %cl, (%rax) # CHECK-NEXT: 3 2 1.00 rclq %rdi # CHECK-NEXT: 3 2 1.00 rcrq %rdi -# CHECK-NEXT: 11 11 3.50 * rclq (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrq (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclq (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrq (%rax) # CHECK-NEXT: 8 4 2.67 rclq $7, %rdi # CHECK-NEXT: 8 3 2.67 rcrq $7, %rdi -# CHECK-NEXT: 11 11 3.50 * rclq $7, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrq $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclq $7, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrq $7, (%rax) # CHECK-NEXT: 8 5 4.00 rclq %cl, %rdi # CHECK-NEXT: 8 5 4.00 rcrq %cl, %rdi -# CHECK-NEXT: 11 11 3.50 * rclq %cl, (%rax) -# CHECK-NEXT: 11 11 3.50 * rcrq %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rclq %cl, (%rax) +# CHECK-NEXT: 11 11 3.50 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.33 U rdmsr # CHECK-NEXT: 1 100 0.33 U rdpmc # CHECK-NEXT: 1 100 0.33 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/SkylakeClient/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/SkylakeClient/resources-x86_64.s index 4f8743eb080c4..dbcf5f9735d6e 100644 --- a/llvm/test/tools/llvm-mca/X86/SkylakeClient/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/SkylakeClient/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 4 4 1.00 * * U pause # CHECK-NEXT: 3 2 0.75 rclb %dil # CHECK-NEXT: 3 2 0.75 rcrb %dil -# CHECK-NEXT: 5 8 0.75 * rclb (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrb (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclb (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrb (%rax) # CHECK-NEXT: 8 6 2.00 rclb $7, %dil # CHECK-NEXT: 8 5 2.00 rcrb $7, %dil -# CHECK-NEXT: 5 8 0.75 * rclb $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrb $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclb $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrb $7, (%rax) # CHECK-NEXT: 9 11 2.50 rclb %cl, %dil # CHECK-NEXT: 10 14 2.50 rcrb %cl, %dil -# CHECK-NEXT: 10 15 2.50 * rclb %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrb %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rclb %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrb %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rclw %di # CHECK-NEXT: 3 2 0.75 rcrw %di -# CHECK-NEXT: 5 8 0.75 * rclw (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrw (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclw (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrw (%rax) # CHECK-NEXT: 8 6 2.00 rclw $7, %di # CHECK-NEXT: 8 5 2.00 rcrw $7, %di -# CHECK-NEXT: 5 8 0.75 * rclw $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrw $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclw $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrw $7, (%rax) # CHECK-NEXT: 7 11 2.00 rclw %cl, %di # CHECK-NEXT: 7 11 2.00 rcrw %cl, %di -# CHECK-NEXT: 10 15 2.50 * rclw %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrw %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rclw %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrw %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rcll %edi # CHECK-NEXT: 3 2 0.75 rcrl %edi -# CHECK-NEXT: 5 8 0.75 * rcll (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrl (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcll (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrl (%rax) # CHECK-NEXT: 8 6 2.00 rcll $7, %edi # CHECK-NEXT: 8 5 2.00 rcrl $7, %edi -# CHECK-NEXT: 5 8 0.75 * rcll $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrl $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcll $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrl $7, (%rax) # CHECK-NEXT: 7 11 2.00 rcll %cl, %edi # CHECK-NEXT: 7 11 2.00 rcrl %cl, %edi -# CHECK-NEXT: 10 15 2.50 * rcll %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrl %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rcll %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrl %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rclq %rdi # CHECK-NEXT: 3 2 0.75 rcrq %rdi -# CHECK-NEXT: 5 8 0.75 * rclq (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrq (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclq (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrq (%rax) # CHECK-NEXT: 8 6 2.00 rclq $7, %rdi # CHECK-NEXT: 8 5 2.00 rcrq $7, %rdi -# CHECK-NEXT: 5 8 0.75 * rclq $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrq $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclq $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrq $7, (%rax) # CHECK-NEXT: 7 11 2.00 rclq %cl, %rdi # CHECK-NEXT: 7 11 2.00 rcrq %cl, %rdi -# CHECK-NEXT: 10 15 2.50 * rclq %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrq %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rclq %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.25 U rdmsr # CHECK-NEXT: 1 100 0.25 U rdpmc # CHECK-NEXT: 8 18 2.00 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/SkylakeServer/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/SkylakeServer/resources-x86_64.s index a47f6203423be..a1de2b929df6c 100644 --- a/llvm/test/tools/llvm-mca/X86/SkylakeServer/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/SkylakeServer/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 4 140 1.00 * * U pause # CHECK-NEXT: 3 2 0.75 rclb %dil # CHECK-NEXT: 3 2 0.75 rcrb %dil -# CHECK-NEXT: 5 8 0.75 * rclb (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrb (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclb (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrb (%rax) # CHECK-NEXT: 8 6 2.00 rclb $7, %dil # CHECK-NEXT: 8 5 2.00 rcrb $7, %dil -# CHECK-NEXT: 5 8 0.75 * rclb $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrb $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclb $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrb $7, (%rax) # CHECK-NEXT: 9 11 2.50 rclb %cl, %dil # CHECK-NEXT: 10 14 2.50 rcrb %cl, %dil -# CHECK-NEXT: 10 15 2.50 * rclb %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrb %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rclb %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrb %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rclw %di # CHECK-NEXT: 3 2 0.75 rcrw %di -# CHECK-NEXT: 5 8 0.75 * rclw (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrw (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclw (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrw (%rax) # CHECK-NEXT: 8 6 2.00 rclw $7, %di # CHECK-NEXT: 8 5 2.00 rcrw $7, %di -# CHECK-NEXT: 5 8 0.75 * rclw $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrw $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclw $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrw $7, (%rax) # CHECK-NEXT: 7 11 2.00 rclw %cl, %di # CHECK-NEXT: 7 11 2.00 rcrw %cl, %di -# CHECK-NEXT: 10 15 2.50 * rclw %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrw %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rclw %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrw %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rcll %edi # CHECK-NEXT: 3 2 0.75 rcrl %edi -# CHECK-NEXT: 5 8 0.75 * rcll (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrl (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcll (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrl (%rax) # CHECK-NEXT: 8 6 2.00 rcll $7, %edi # CHECK-NEXT: 8 5 2.00 rcrl $7, %edi -# CHECK-NEXT: 5 8 0.75 * rcll $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrl $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcll $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrl $7, (%rax) # CHECK-NEXT: 7 11 2.00 rcll %cl, %edi # CHECK-NEXT: 7 11 2.00 rcrl %cl, %edi -# CHECK-NEXT: 10 15 2.50 * rcll %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrl %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rcll %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrl %cl, (%rax) # CHECK-NEXT: 3 2 0.75 rclq %rdi # CHECK-NEXT: 3 2 0.75 rcrq %rdi -# CHECK-NEXT: 5 8 0.75 * rclq (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrq (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclq (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrq (%rax) # CHECK-NEXT: 8 6 2.00 rclq $7, %rdi # CHECK-NEXT: 8 5 2.00 rcrq $7, %rdi -# CHECK-NEXT: 5 8 0.75 * rclq $7, (%rax) -# CHECK-NEXT: 5 8 0.75 * rcrq $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rclq $7, (%rax) +# CHECK-NEXT: 5 8 0.75 * * rcrq $7, (%rax) # CHECK-NEXT: 7 11 2.00 rclq %cl, %rdi # CHECK-NEXT: 7 11 2.00 rcrq %cl, %rdi -# CHECK-NEXT: 10 15 2.50 * rclq %cl, (%rax) -# CHECK-NEXT: 11 18 2.25 * rcrq %cl, (%rax) +# CHECK-NEXT: 10 15 2.50 * * rclq %cl, (%rax) +# CHECK-NEXT: 11 18 2.25 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.25 U rdmsr # CHECK-NEXT: 1 100 0.25 U rdpmc # CHECK-NEXT: 8 18 2.00 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/Znver1/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/Znver1/resources-x86_64.s index b0449c04e68ca..5ed3284b25e43 100644 --- a/llvm/test/tools/llvm-mca/X86/Znver1/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/Znver1/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 1 100 0.25 * * U pause # CHECK-NEXT: 1 1 0.25 rclb %dil # CHECK-NEXT: 1 1 0.25 rcrb %dil -# CHECK-NEXT: 1 100 0.25 * rclb (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrb (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclb (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrb (%rax) # CHECK-NEXT: 1 1 0.25 rclb $7, %dil # CHECK-NEXT: 1 1 0.25 rcrb $7, %dil -# CHECK-NEXT: 1 100 0.25 * rclb $7, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrb $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclb $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrb $7, (%rax) # CHECK-NEXT: 1 1 0.25 rclb %cl, %dil # CHECK-NEXT: 1 1 0.25 rcrb %cl, %dil -# CHECK-NEXT: 1 100 0.25 * rclb %cl, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrb %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclb %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrb %cl, (%rax) # CHECK-NEXT: 1 1 0.25 rclw %di # CHECK-NEXT: 1 1 0.25 rcrw %di -# CHECK-NEXT: 1 100 0.25 * rclw (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrw (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclw (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrw (%rax) # CHECK-NEXT: 1 1 0.25 rclw $7, %di # CHECK-NEXT: 1 1 0.25 rcrw $7, %di -# CHECK-NEXT: 1 100 0.25 * rclw $7, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrw $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclw $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrw $7, (%rax) # CHECK-NEXT: 1 1 0.25 rclw %cl, %di # CHECK-NEXT: 1 1 0.25 rcrw %cl, %di -# CHECK-NEXT: 1 100 0.25 * rclw %cl, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrw %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclw %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrw %cl, (%rax) # CHECK-NEXT: 1 1 0.25 rcll %edi # CHECK-NEXT: 1 1 0.25 rcrl %edi -# CHECK-NEXT: 1 100 0.25 * rcll (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrl (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcll (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrl (%rax) # CHECK-NEXT: 1 1 0.25 rcll $7, %edi # CHECK-NEXT: 1 1 0.25 rcrl $7, %edi -# CHECK-NEXT: 1 100 0.25 * rcll $7, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrl $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcll $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrl $7, (%rax) # CHECK-NEXT: 1 1 0.25 rcll %cl, %edi # CHECK-NEXT: 1 1 0.25 rcrl %cl, %edi -# CHECK-NEXT: 1 100 0.25 * rcll %cl, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrl %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcll %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrl %cl, (%rax) # CHECK-NEXT: 1 1 0.25 rclq %rdi # CHECK-NEXT: 1 1 0.25 rcrq %rdi -# CHECK-NEXT: 1 100 0.25 * rclq (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrq (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclq (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrq (%rax) # CHECK-NEXT: 1 1 0.25 rclq $7, %rdi # CHECK-NEXT: 1 1 0.25 rcrq $7, %rdi -# CHECK-NEXT: 1 100 0.25 * rclq $7, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrq $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclq $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrq $7, (%rax) # CHECK-NEXT: 1 1 0.25 rclq %cl, %rdi # CHECK-NEXT: 1 1 0.25 rcrq %cl, %rdi -# CHECK-NEXT: 1 100 0.25 * rclq %cl, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrq %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclq %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.25 U rdmsr # CHECK-NEXT: 1 100 0.25 U rdpmc # CHECK-NEXT: 1 100 0.25 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/Znver2/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/Znver2/resources-x86_64.s index e2c2d0bf31684..ffa65b880164e 100644 --- a/llvm/test/tools/llvm-mca/X86/Znver2/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/Znver2/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 1 100 0.25 * * U pause # CHECK-NEXT: 1 1 0.25 rclb %dil # CHECK-NEXT: 1 1 0.25 rcrb %dil -# CHECK-NEXT: 1 100 0.25 * rclb (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrb (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclb (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrb (%rax) # CHECK-NEXT: 1 1 0.25 rclb $7, %dil # CHECK-NEXT: 1 1 0.25 rcrb $7, %dil -# CHECK-NEXT: 1 100 0.25 * rclb $7, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrb $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclb $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrb $7, (%rax) # CHECK-NEXT: 1 1 0.25 rclb %cl, %dil # CHECK-NEXT: 1 1 0.25 rcrb %cl, %dil -# CHECK-NEXT: 1 100 0.25 * rclb %cl, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrb %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclb %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrb %cl, (%rax) # CHECK-NEXT: 1 1 0.25 rclw %di # CHECK-NEXT: 1 1 0.25 rcrw %di -# CHECK-NEXT: 1 100 0.25 * rclw (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrw (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclw (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrw (%rax) # CHECK-NEXT: 1 1 0.25 rclw $7, %di # CHECK-NEXT: 1 1 0.25 rcrw $7, %di -# CHECK-NEXT: 1 100 0.25 * rclw $7, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrw $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclw $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrw $7, (%rax) # CHECK-NEXT: 1 1 0.25 rclw %cl, %di # CHECK-NEXT: 1 1 0.25 rcrw %cl, %di -# CHECK-NEXT: 1 100 0.25 * rclw %cl, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrw %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclw %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrw %cl, (%rax) # CHECK-NEXT: 1 1 0.25 rcll %edi # CHECK-NEXT: 1 1 0.25 rcrl %edi -# CHECK-NEXT: 1 100 0.25 * rcll (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrl (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcll (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrl (%rax) # CHECK-NEXT: 1 1 0.25 rcll $7, %edi # CHECK-NEXT: 1 1 0.25 rcrl $7, %edi -# CHECK-NEXT: 1 100 0.25 * rcll $7, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrl $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcll $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrl $7, (%rax) # CHECK-NEXT: 1 1 0.25 rcll %cl, %edi # CHECK-NEXT: 1 1 0.25 rcrl %cl, %edi -# CHECK-NEXT: 1 100 0.25 * rcll %cl, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrl %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcll %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrl %cl, (%rax) # CHECK-NEXT: 1 1 0.25 rclq %rdi # CHECK-NEXT: 1 1 0.25 rcrq %rdi -# CHECK-NEXT: 1 100 0.25 * rclq (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrq (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclq (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrq (%rax) # CHECK-NEXT: 1 1 0.25 rclq $7, %rdi # CHECK-NEXT: 1 1 0.25 rcrq $7, %rdi -# CHECK-NEXT: 1 100 0.25 * rclq $7, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrq $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclq $7, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrq $7, (%rax) # CHECK-NEXT: 1 1 0.25 rclq %cl, %rdi # CHECK-NEXT: 1 1 0.25 rcrq %cl, %rdi -# CHECK-NEXT: 1 100 0.25 * rclq %cl, (%rax) -# CHECK-NEXT: 1 100 0.25 * rcrq %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rclq %cl, (%rax) +# CHECK-NEXT: 1 100 0.25 * * rcrq %cl, (%rax) # CHECK-NEXT: 1 100 0.25 U rdmsr # CHECK-NEXT: 1 100 0.25 U rdpmc # CHECK-NEXT: 1 100 0.25 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/Znver3/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/Znver3/resources-x86_64.s index dca8fcce894c8..fedb3d242c452 100644 --- a/llvm/test/tools/llvm-mca/X86/Znver3/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/Znver3/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 1 0 0.25 * * U pause # CHECK-NEXT: 1 1 1.00 rclb %dil # CHECK-NEXT: 1 1 1.00 rcrb %dil -# CHECK-NEXT: 2 5 1.00 * rclb (%rax) -# CHECK-NEXT: 2 5 1.00 * rcrb (%rax) +# CHECK-NEXT: 2 5 1.00 * * rclb (%rax) +# CHECK-NEXT: 2 5 1.00 * * rcrb (%rax) # CHECK-NEXT: 9 4 4.00 rclb $7, %dil # CHECK-NEXT: 7 3 3.00 rcrb $7, %dil -# CHECK-NEXT: 11 8 4.00 * rclb $7, (%rax) -# CHECK-NEXT: 10 7 4.00 * rcrb $7, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclb $7, (%rax) +# CHECK-NEXT: 10 7 4.00 * * rcrb $7, (%rax) # CHECK-NEXT: 9 4 4.00 rclb %cl, %dil # CHECK-NEXT: 7 3 3.00 rcrb %cl, %dil -# CHECK-NEXT: 11 8 4.00 * rclb %cl, (%rax) -# CHECK-NEXT: 9 7 4.00 * rcrb %cl, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclb %cl, (%rax) +# CHECK-NEXT: 9 7 4.00 * * rcrb %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rclw %di # CHECK-NEXT: 1 1 1.00 rcrw %di -# CHECK-NEXT: 2 5 1.00 * rclw (%rax) -# CHECK-NEXT: 2 5 1.00 * rcrw (%rax) +# CHECK-NEXT: 2 5 1.00 * * rclw (%rax) +# CHECK-NEXT: 2 5 1.00 * * rcrw (%rax) # CHECK-NEXT: 9 4 4.00 rclw $7, %di # CHECK-NEXT: 7 3 3.00 rcrw $7, %di -# CHECK-NEXT: 11 8 4.00 * rclw $7, (%rax) -# CHECK-NEXT: 10 7 4.00 * rcrw $7, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclw $7, (%rax) +# CHECK-NEXT: 10 7 4.00 * * rcrw $7, (%rax) # CHECK-NEXT: 9 4 4.00 rclw %cl, %di # CHECK-NEXT: 7 3 3.00 rcrw %cl, %di -# CHECK-NEXT: 11 8 4.00 * rclw %cl, (%rax) -# CHECK-NEXT: 9 7 4.00 * rcrw %cl, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclw %cl, (%rax) +# CHECK-NEXT: 9 7 4.00 * * rcrw %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rcll %edi # CHECK-NEXT: 1 1 1.00 rcrl %edi -# CHECK-NEXT: 2 5 1.00 * rcll (%rax) -# CHECK-NEXT: 2 5 1.00 * rcrl (%rax) +# CHECK-NEXT: 2 5 1.00 * * rcll (%rax) +# CHECK-NEXT: 2 5 1.00 * * rcrl (%rax) # CHECK-NEXT: 9 4 4.00 rcll $7, %edi # CHECK-NEXT: 7 3 3.00 rcrl $7, %edi -# CHECK-NEXT: 11 8 4.00 * rcll $7, (%rax) -# CHECK-NEXT: 10 7 4.00 * rcrl $7, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rcll $7, (%rax) +# CHECK-NEXT: 10 7 4.00 * * rcrl $7, (%rax) # CHECK-NEXT: 9 4 4.00 rcll %cl, %edi # CHECK-NEXT: 7 3 3.00 rcrl %cl, %edi -# CHECK-NEXT: 11 8 4.00 * rcll %cl, (%rax) -# CHECK-NEXT: 9 7 4.00 * rcrl %cl, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rcll %cl, (%rax) +# CHECK-NEXT: 9 7 4.00 * * rcrl %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rclq %rdi # CHECK-NEXT: 1 1 1.00 rcrq %rdi -# CHECK-NEXT: 2 5 1.00 * rclq (%rax) -# CHECK-NEXT: 2 5 1.00 * rcrq (%rax) +# CHECK-NEXT: 2 5 1.00 * * rclq (%rax) +# CHECK-NEXT: 2 5 1.00 * * rcrq (%rax) # CHECK-NEXT: 9 4 4.00 rclq $7, %rdi # CHECK-NEXT: 7 3 3.00 rcrq $7, %rdi -# CHECK-NEXT: 11 8 4.00 * rclq $7, (%rax) -# CHECK-NEXT: 10 7 4.00 * rcrq $7, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclq $7, (%rax) +# CHECK-NEXT: 10 7 4.00 * * rcrq $7, (%rax) # CHECK-NEXT: 9 4 4.00 rclq %cl, %rdi # CHECK-NEXT: 7 3 3.00 rcrq %cl, %rdi -# CHECK-NEXT: 11 8 4.00 * rclq %cl, (%rax) -# CHECK-NEXT: 9 7 4.00 * rcrq %cl, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclq %cl, (%rax) +# CHECK-NEXT: 9 7 4.00 * * rcrq %cl, (%rax) # CHECK-NEXT: 100 100 25.00 U rdmsr # CHECK-NEXT: 100 100 25.00 U rdpmc # CHECK-NEXT: 100 100 25.00 U rdtsc diff --git a/llvm/test/tools/llvm-mca/X86/Znver4/resources-x86_64.s b/llvm/test/tools/llvm-mca/X86/Znver4/resources-x86_64.s index bc06a60e1c3d8..9c5b4e45896de 100644 --- a/llvm/test/tools/llvm-mca/X86/Znver4/resources-x86_64.s +++ b/llvm/test/tools/llvm-mca/X86/Znver4/resources-x86_64.s @@ -1515,52 +1515,52 @@ xorq (%rax), %rdi # CHECK-NEXT: 1 0 0.25 * * U pause # CHECK-NEXT: 1 1 1.00 rclb %dil # CHECK-NEXT: 1 1 1.00 rcrb %dil -# CHECK-NEXT: 2 5 1.00 * rclb (%rax) -# CHECK-NEXT: 2 5 1.00 * rcrb (%rax) +# CHECK-NEXT: 2 5 1.00 * * rclb (%rax) +# CHECK-NEXT: 2 5 1.00 * * rcrb (%rax) # CHECK-NEXT: 9 4 4.00 rclb $7, %dil # CHECK-NEXT: 7 3 3.00 rcrb $7, %dil -# CHECK-NEXT: 11 8 4.00 * rclb $7, (%rax) -# CHECK-NEXT: 10 7 4.00 * rcrb $7, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclb $7, (%rax) +# CHECK-NEXT: 10 7 4.00 * * rcrb $7, (%rax) # CHECK-NEXT: 9 4 4.00 rclb %cl, %dil # CHECK-NEXT: 7 3 3.00 rcrb %cl, %dil -# CHECK-NEXT: 11 8 4.00 * rclb %cl, (%rax) -# CHECK-NEXT: 9 7 4.00 * rcrb %cl, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclb %cl, (%rax) +# CHECK-NEXT: 9 7 4.00 * * rcrb %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rclw %di # CHECK-NEXT: 1 1 1.00 rcrw %di -# CHECK-NEXT: 2 5 1.00 * rclw (%rax) -# CHECK-NEXT: 2 5 1.00 * rcrw (%rax) +# CHECK-NEXT: 2 5 1.00 * * rclw (%rax) +# CHECK-NEXT: 2 5 1.00 * * rcrw (%rax) # CHECK-NEXT: 9 4 4.00 rclw $7, %di # CHECK-NEXT: 7 3 3.00 rcrw $7, %di -# CHECK-NEXT: 11 8 4.00 * rclw $7, (%rax) -# CHECK-NEXT: 10 7 4.00 * rcrw $7, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclw $7, (%rax) +# CHECK-NEXT: 10 7 4.00 * * rcrw $7, (%rax) # CHECK-NEXT: 9 4 4.00 rclw %cl, %di # CHECK-NEXT: 7 3 3.00 rcrw %cl, %di -# CHECK-NEXT: 11 8 4.00 * rclw %cl, (%rax) -# CHECK-NEXT: 9 7 4.00 * rcrw %cl, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclw %cl, (%rax) +# CHECK-NEXT: 9 7 4.00 * * rcrw %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rcll %edi # CHECK-NEXT: 1 1 1.00 rcrl %edi -# CHECK-NEXT: 2 5 1.00 * rcll (%rax) -# CHECK-NEXT: 2 5 1.00 * rcrl (%rax) +# CHECK-NEXT: 2 5 1.00 * * rcll (%rax) +# CHECK-NEXT: 2 5 1.00 * * rcrl (%rax) # CHECK-NEXT: 9 4 4.00 rcll $7, %edi # CHECK-NEXT: 7 3 3.00 rcrl $7, %edi -# CHECK-NEXT: 11 8 4.00 * rcll $7, (%rax) -# CHECK-NEXT: 10 7 4.00 * rcrl $7, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rcll $7, (%rax) +# CHECK-NEXT: 10 7 4.00 * * rcrl $7, (%rax) # CHECK-NEXT: 9 4 4.00 rcll %cl, %edi # CHECK-NEXT: 7 3 3.00 rcrl %cl, %edi -# CHECK-NEXT: 11 8 4.00 * rcll %cl, (%rax) -# CHECK-NEXT: 9 7 4.00 * rcrl %cl, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rcll %cl, (%rax) +# CHECK-NEXT: 9 7 4.00 * * rcrl %cl, (%rax) # CHECK-NEXT: 1 1 1.00 rclq %rdi # CHECK-NEXT: 1 1 1.00 rcrq %rdi -# CHECK-NEXT: 2 5 1.00 * rclq (%rax) -# CHECK-NEXT: 2 5 1.00 * rcrq (%rax) +# CHECK-NEXT: 2 5 1.00 * * rclq (%rax) +# CHECK-NEXT: 2 5 1.00 * * rcrq (%rax) # CHECK-NEXT: 9 4 4.00 rclq $7, %rdi # CHECK-NEXT: 7 3 3.00 rcrq $7, %rdi -# CHECK-NEXT: 11 8 4.00 * rclq $7, (%rax) -# CHECK-NEXT: 10 7 4.00 * rcrq $7, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclq $7, (%rax) +# CHECK-NEXT: 10 7 4.00 * * rcrq $7, (%rax) # CHECK-NEXT: 9 4 4.00 rclq %cl, %rdi # CHECK-NEXT: 7 3 3.00 rcrq %cl, %rdi -# CHECK-NEXT: 11 8 4.00 * rclq %cl, (%rax) -# CHECK-NEXT: 9 7 4.00 * rcrq %cl, (%rax) +# CHECK-NEXT: 11 8 4.00 * * rclq %cl, (%rax) +# CHECK-NEXT: 9 7 4.00 * * rcrq %cl, (%rax) # CHECK-NEXT: 100 100 25.00 U rdmsr # CHECK-NEXT: 100 100 25.00 U rdpmc # CHECK-NEXT: 100 100 25.00 U rdtsc From 17bbb224f99cf6fde83aa68e2e22e70fe9ed77be Mon Sep 17 00:00:00 2001 From: varconst Date: Mon, 8 May 2023 23:40:21 -0700 Subject: [PATCH 035/608] [libc++][ranges] Implement the changes to vector from P1206 (`ranges::to`): - add the `from_range_t` constructors and the related deduction guides; - add the `insert_range`/`assign_range`/etc. member functions. (Note: this patch is split from https://reviews.llvm.org/D142335) Differential Revision: https://reviews.llvm.org/D149826 --- libcxx/docs/Status/Cxx2bPapers.csv | 2 +- libcxx/include/CMakeLists.txt | 2 + .../__ranges/container_compatible_range.h | 33 + libcxx/include/__ranges/from_range.h | 33 + libcxx/include/__split_buffer | 25 +- libcxx/include/module.modulemap.in | 80 +- libcxx/include/ranges | 4 + libcxx/include/vector | 492 +++++++---- libcxx/test/libcxx/private_headers.verify.cpp | 2 + .../test/std/containers/from_range_helpers.h | 154 ++++ .../std/containers/insert_range_helpers.h | 123 +++ .../from_range_sequence_containers.h | 161 ++++ .../insert_range_sequence_containers.h | 827 ++++++++++++++++++ .../vector.bool/append_range.pass.cpp | 72 ++ .../vector.bool/assign_range.pass.cpp | 65 ++ .../vector.bool/construct_from_range.pass.cpp | 40 + .../vector.bool/insert_range.pass.cpp | 72 ++ .../vector.cons/construct_from_range.pass.cpp | 42 + .../vector/vector.cons/deduct.pass.cpp | 22 +- .../vector/vector.cons/exceptions.pass.cpp | 2 + .../vector.modifiers/append_range.pass.cpp | 70 ++ .../vector.modifiers/assign_range.pass.cpp | 78 ++ .../vector.modifiers/insert_range.pass.cpp | 71 ++ .../from_range_t.compile.pass.cpp | 25 + .../support/deduction_guides_sfinae_checks.h | 46 +- 25 files changed, 2347 insertions(+), 196 deletions(-) create mode 100644 libcxx/include/__ranges/container_compatible_range.h create mode 100644 libcxx/include/__ranges/from_range.h create mode 100644 libcxx/test/std/containers/from_range_helpers.h create mode 100644 libcxx/test/std/containers/insert_range_helpers.h create mode 100644 libcxx/test/std/containers/sequences/from_range_sequence_containers.h create mode 100644 libcxx/test/std/containers/sequences/insert_range_sequence_containers.h create mode 100644 libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp create mode 100644 libcxx/test/std/containers/sequences/vector.bool/assign_range.pass.cpp create mode 100644 libcxx/test/std/containers/sequences/vector.bool/construct_from_range.pass.cpp create mode 100644 libcxx/test/std/containers/sequences/vector.bool/insert_range.pass.cpp create mode 100644 libcxx/test/std/containers/sequences/vector/vector.cons/construct_from_range.pass.cpp create mode 100644 libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp create mode 100644 libcxx/test/std/containers/sequences/vector/vector.modifiers/assign_range.pass.cpp create mode 100644 libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range.pass.cpp create mode 100644 libcxx/test/std/ranges/range.utility/range.utility.conv/from_range_t.compile.pass.cpp diff --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv index c5b99c113d886..a310cfc5ff161 100644 --- a/libcxx/docs/Status/Cxx2bPapers.csv +++ b/libcxx/docs/Status/Cxx2bPapers.csv @@ -41,7 +41,7 @@ "`P0323R12 `__","LWG","``std::expected``","February 2022","|Complete|","16.0" "`P0533R9 `__","LWG","``constexpr`` for ```` and ````","February 2022","|In progress| [#note-P0533R9]_","" "`P0627R6 `__","LWG","Function to mark unreachable code","February 2022","|Complete|","15.0" -"`P1206R7 `__","LWG","``ranges::to``: A function to convert any range to a container","February 2022","","","|ranges|" +"`P1206R7 `__","LWG","``ranges::to``: A function to convert any range to a container","February 2022","|In Progress|","","|ranges|" "`P1413R3 `__","LWG","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","February 2022","|Complete| [#note-P1413R3]_","" "`P2255R2 `__","LWG","A type trait to detect reference binding to temporary","February 2022","","" "`P2273R3 `__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","|Complete|","16.0" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index f42c82c3ab146..4929501a700c7 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -581,6 +581,7 @@ set(files __ranges/as_rvalue_view.h __ranges/common_view.h __ranges/concepts.h + __ranges/container_compatible_range.h __ranges/copyable_box.h __ranges/counted.h __ranges/dangling.h @@ -593,6 +594,7 @@ set(files __ranges/enable_borrowed_range.h __ranges/enable_view.h __ranges/filter_view.h + __ranges/from_range.h __ranges/iota_view.h __ranges/istream_view.h __ranges/join_view.h diff --git a/libcxx/include/__ranges/container_compatible_range.h b/libcxx/include/__ranges/container_compatible_range.h new file mode 100644 index 0000000000000..a58f1119885e3 --- /dev/null +++ b/libcxx/include/__ranges/container_compatible_range.h @@ -0,0 +1,33 @@ +// -*- 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 _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H +#define _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__ranges/concepts.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 23 + +template +concept _ContainerCompatibleRange = + ranges::input_range<_Range> && convertible_to, _Tp>; + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H diff --git a/libcxx/include/__ranges/from_range.h b/libcxx/include/__ranges/from_range.h new file mode 100644 index 0000000000000..a6cb9e3d439eb --- /dev/null +++ b/libcxx/include/__ranges/from_range.h @@ -0,0 +1,33 @@ +// -*- 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 _LIBCPP___RANGES_FROM_RANGE_H +#define _LIBCPP___RANGES_FROM_RANGE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 23 + +struct from_range_t { + explicit from_range_t() = default; +}; + +inline constexpr from_range_t from_range{}; + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANGES_FROM_RANGE_H diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer index c4f1315ee5bf2..5efc443a4b340 100644 --- a/libcxx/include/__split_buffer +++ b/libcxx/include/__split_buffer @@ -170,6 +170,14 @@ public: __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value> __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + void __construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + void __construct_at_end_with_size(_Iterator __first, size_type __n); + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin) { __destruct_at_begin(__new_begin, is_trivially_destructible()); } @@ -279,6 +287,13 @@ template _LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value> __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last) { + __construct_at_end_with_sentinel(__first, __last); +} + +template +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 +void __split_buffer<_Tp, _Allocator>::__construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last) { __alloc_rr& __a = this->__alloc(); for (; __first != __last; ++__first) { @@ -296,13 +311,19 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIt ++this->__end_; } } - template template _LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value> __split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) { - _ConstructTransaction __tx(&this->__end_, _VSTD::distance(__first, __last)); + __construct_at_end_with_size(__first, std::distance(__first, __last)); +} + +template +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 +void __split_buffer<_Tp, _Allocator>::__construct_at_end_with_size(_ForwardIterator __first, size_type __n) { + _ConstructTransaction __tx(&this->__end_, __n); for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void) ++__first) { __alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__tx.__pos_), *__first); diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 3f96e685bdc98..6b7bba1d1d41d 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1309,62 +1309,64 @@ module std [system] { export * module __ranges { - module access { private header "__ranges/access.h" } - module all { + module access { private header "__ranges/access.h" } + module all { private header "__ranges/all.h" export functional.__functional.compose export functional.__functional.perfect_forward } - module as_rvalue_view { private header "__ranges/as_rvalue_view.h" } - module common_view { private header "__ranges/common_view.h" } - module concepts { private header "__ranges/concepts.h" } - module copyable_box { private header "__ranges/copyable_box.h" } - module counted { + module as_rvalue_view { private header "__ranges/as_rvalue_view.h" } + module common_view { private header "__ranges/common_view.h" } + module concepts { private header "__ranges/concepts.h" } + module container_compatible_range { private header "__ranges/container_compatible_range.h" } + module copyable_box { private header "__ranges/copyable_box.h" } + module counted { private header "__ranges/counted.h" export span } - module dangling { private header "__ranges/dangling.h" } - module data { private header "__ranges/data.h" } - module drop_view { private header "__ranges/drop_view.h" } - module drop_while_view { private header "__ranges/drop_while_view.h" } - module elements_view { private header "__ranges/elements_view.h" } - module empty { private header "__ranges/empty.h" } - module empty_view { private header "__ranges/empty_view.h" } - module enable_borrowed_range { private header "__ranges/enable_borrowed_range.h" } - module enable_view { private header "__ranges/enable_view.h" } - module filter_view { private header "__ranges/filter_view.h" } - module iota_view { private header "__ranges/iota_view.h" } - module istream_view { + module dangling { private header "__ranges/dangling.h" } + module data { private header "__ranges/data.h" } + module drop_view { private header "__ranges/drop_view.h" } + module drop_while_view { private header "__ranges/drop_while_view.h" } + module elements_view { private header "__ranges/elements_view.h" } + module empty { private header "__ranges/empty.h" } + module empty_view { private header "__ranges/empty_view.h" } + module enable_borrowed_range { private header "__ranges/enable_borrowed_range.h" } + module enable_view { private header "__ranges/enable_view.h" } + module filter_view { private header "__ranges/filter_view.h" } + module from_range { private header "__ranges/from_range.h" } + module iota_view { private header "__ranges/iota_view.h" } + module istream_view { @requires_LIBCXX_ENABLE_LOCALIZATION@ private header "__ranges/istream_view.h" } - module join_view { private header "__ranges/join_view.h" } - module lazy_split_view { private header "__ranges/lazy_split_view.h" } - module non_propagating_cache { private header "__ranges/non_propagating_cache.h" } - module owning_view { private header "__ranges/owning_view.h" } - module range_adaptor { private header "__ranges/range_adaptor.h" } - module rbegin { private header "__ranges/rbegin.h" } - module ref_view { private header "__ranges/ref_view.h" } - module rend { private header "__ranges/rend.h" } - module reverse_view { private header "__ranges/reverse_view.h" } - module single_view { private header "__ranges/single_view.h" } - module size { private header "__ranges/size.h" } - module split_view { private header "__ranges/split_view.h" } - module subrange { + module join_view { private header "__ranges/join_view.h" } + module lazy_split_view { private header "__ranges/lazy_split_view.h" } + module non_propagating_cache { private header "__ranges/non_propagating_cache.h" } + module owning_view { private header "__ranges/owning_view.h" } + module range_adaptor { private header "__ranges/range_adaptor.h" } + module rbegin { private header "__ranges/rbegin.h" } + module ref_view { private header "__ranges/ref_view.h" } + module rend { private header "__ranges/rend.h" } + module reverse_view { private header "__ranges/reverse_view.h" } + module single_view { private header "__ranges/single_view.h" } + module size { private header "__ranges/size.h" } + module split_view { private header "__ranges/split_view.h" } + module subrange { private header "__ranges/subrange.h" export subrange_fwd } - module subrange_fwd { private header "__fwd/subrange.h" } - module take_view { private header "__ranges/take_view.h" } - module take_while_view { private header "__ranges/take_while_view.h" } - module transform_view { + module subrange_fwd { private header "__fwd/subrange.h" } + module take_view { private header "__ranges/take_view.h" } + module take_while_view { private header "__ranges/take_while_view.h" } + module transform_view { private header "__ranges/transform_view.h" export functional.__functional.bind_back export functional.__functional.perfect_forward } - module view_interface { private header "__ranges/view_interface.h" } - module views { private header "__ranges/views.h" } - module zip_view { private header "__ranges/zip_view.h" } + module view_interface { private header "__ranges/view_interface.h" } + module views { private header "__ranges/views.h" } + module zip_view { private header "__ranges/zip_view.h" } } } module ratio { diff --git a/libcxx/include/ranges b/libcxx/include/ranges index 8f3b4b21f622c..38da82dc7581d 100644 --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -339,6 +339,9 @@ namespace std { struct tuple_element<1, const ranges::subrange> { using type = S; }; + + struct from_range_t { explicit from_range_t() = default; }; // Since C++23 + inline constexpr from_range_t from_range{}; // Since C++23 } */ @@ -360,6 +363,7 @@ namespace std { #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> #include <__ranges/filter_view.h> +#include <__ranges/from_range.h> #include <__ranges/iota_view.h> #include <__ranges/join_view.h> #include <__ranges/lazy_split_view.h> diff --git a/libcxx/include/vector b/libcxx/include/vector index a1366d0a9c2d9..374a47c7173ca 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -41,6 +41,8 @@ public: vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); template vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); + template R> + constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 vector(const vector& x); vector(vector&& x) noexcept(is_nothrow_move_constructible::value); @@ -55,6 +57,8 @@ public: vector& operator=(initializer_list il); template void assign(InputIterator first, InputIterator last); + template R> + constexpr void assign_range(R&& rg); // C++23 void assign(size_type n, const value_type& u); void assign(initializer_list il); @@ -99,6 +103,8 @@ public: void push_back(value_type&& x); template reference emplace_back(Args&&... args); // reference in C++17 + template R> + constexpr void append_range(R&& rg); // C++23 void pop_back(); template iterator emplace(const_iterator position, Args&&... args); @@ -107,6 +113,8 @@ public: iterator insert(const_iterator position, size_type n, const value_type& x); template iterator insert(const_iterator position, InputIterator first, InputIterator last); + template R> + constexpr iterator insert_range(const_iterator position, R&& rg); // C++23 iterator insert(const_iterator position, initializer_list il); iterator erase(const_iterator position); @@ -165,6 +173,8 @@ public: vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); template vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); + template R> + constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); vector(const vector& x); vector(vector&& x) noexcept(is_nothrow_move_constructible::value); @@ -179,6 +189,8 @@ public: vector& operator=(initializer_list il); template void assign(InputIterator first, InputIterator last); + template R> + constexpr void assign_range(R&& rg); // C++23 void assign(size_type n, const value_type& u); void assign(initializer_list il); @@ -218,6 +230,8 @@ public: void push_back(const value_type& x); template reference emplace_back(Args&&... args); // C++14; reference in C++17 + template R> + constexpr void append_range(R&& rg); // C++23 void pop_back(); template iterator emplace(const_iterator position, Args&&... args); // C++14 @@ -225,6 +239,8 @@ public: iterator insert(const_iterator position, size_type n, const value_type& x); template iterator insert(const_iterator position, InputIterator first, InputIterator last); + template R> + constexpr iterator insert_range(const_iterator position, R&& rg); // C++23 iterator insert(const_iterator position, initializer_list il); iterator erase(const_iterator position); @@ -247,6 +263,10 @@ template vector::value_type, Allocator>; // C++17 +template>> + vector(from_range_t, R&&, Allocator = Allocator()) + -> vector, Allocator>; // C++23 + template struct hash>; template bool operator==(const vector& x, const vector& y); @@ -281,6 +301,7 @@ template requires is-vector-bool-reference // Since C++ #include <__algorithm/copy.h> #include <__algorithm/equal.h> #include <__algorithm/fill_n.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/lexicographical_compare.h> #include <__algorithm/remove.h> #include <__algorithm/remove_if.h> @@ -297,6 +318,7 @@ template requires is-vector-bool-reference // Since C++ #include <__functional/hash.h> #include <__functional/unary_function.h> #include <__iterator/advance.h> +#include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__iterator/reverse_iterator.h> #include <__iterator/wrap_iter.h> @@ -308,6 +330,11 @@ template requires is-vector-bool-reference // Since C++ #include <__memory/temp_value.h> #include <__memory/uninitialized_algorithms.h> #include <__memory_resource/polymorphic_allocator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/container_compatible_range.h> +#include <__ranges/from_range.h> +#include <__ranges/size.h> #include <__split_buffer> #include <__type_traits/is_allocator.h> #include <__type_traits/is_constructible.h> @@ -317,6 +344,7 @@ template requires is-vector-bool-reference // Since C++ #include <__utility/exception_guard.h> #include <__utility/forward.h> #include <__utility/move.h> +#include <__utility/pair.h> #include <__utility/swap.h> #include #include @@ -345,7 +373,6 @@ template requires is-vector-bool-reference // Since C++ _LIBCPP_PUSH_MACROS #include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template */> @@ -437,6 +464,20 @@ public: _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a); +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<_Tp> _Range> + _LIBCPP_HIDE_FROM_ABI constexpr vector(from_range_t, _Range&& __range, + const allocator_type& __alloc = allocator_type()) : __end_cap_(nullptr, __alloc) { + if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { + auto __n = static_cast(ranges::distance(__range)); + __init_with_size(ranges::begin(__range), ranges::end(__range), __n); + + } else { + __init_with_sentinel(ranges::begin(__range), ranges::end(__range)); + } + } +#endif + private: class __destroy_vector { public: @@ -502,6 +543,20 @@ public: int> = 0> _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_ForwardIterator __first, _ForwardIterator __last); +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<_Tp> _Range> + _LIBCPP_HIDE_FROM_ABI + constexpr void assign_range(_Range&& __range) { + if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { + auto __n = static_cast(ranges::distance(__range)); + __assign_with_size(ranges::begin(__range), ranges::end(__range), __n); + + } else { + __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); + } + } +#endif + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const_reference __u); #ifndef _LIBCPP_CXX03_LANG @@ -604,6 +659,14 @@ public: void emplace_back(_Args&&... __args); #endif +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<_Tp> _Range> + _LIBCPP_HIDE_FROM_ABI + constexpr void append_range(_Range&& __range) { + insert_range(end(), std::forward<_Range>(__range)); + } +#endif + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back(); @@ -623,6 +686,20 @@ public: _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __position, _InputIterator __first, _InputIterator __last); +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<_Tp> _Range> + _LIBCPP_HIDE_FROM_ABI + constexpr iterator insert_range(const_iterator __position, _Range&& __range) { + if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { + auto __n = static_cast(ranges::distance(__range)); + return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n); + + } else { + return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); + } + } +#endif + template < class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value && @@ -702,9 +779,51 @@ private: _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x); - template ::value, int> = 0> - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void - __construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __n) { + auto __guard = std::__make_exception_guard(__destroy_vector(*this)); + std::__debug_db_insert_c(this); + + if (__n > 0) { + __vallocate(__n); + __construct_at_end(__first, __last, __n); + } + + __guard.__complete(); + } + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + void __init_with_sentinel(_InputIterator __first, _Sentinel __last) { + auto __guard = std::__make_exception_guard(__destroy_vector(*this)); + std::__debug_db_insert_c(this); + + for (; __first != __last; ++__first) + emplace_back(*__first); + + __guard.__complete(); + } + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + void __assign_with_sentinel(_Iterator __first, _Sentinel __last); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + void __assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + iterator __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + iterator __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x); @@ -911,6 +1030,15 @@ vector(_InputIterator, _InputIterator, _Alloc) -> vector<__iter_value_type<_InputIterator>, _Alloc>; #endif +#if _LIBCPP_STD_VER >= 23 +template >, + class = enable_if_t<__is_allocator<_Alloc>::value> + > +vector(from_range_t, _Range&&, _Alloc = _Alloc()) + -> vector, _Alloc>; +#endif + template _LIBCPP_CONSTEXPR_SINCE_CXX20 void @@ -1026,10 +1154,9 @@ vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) } template -template ::value, int> > +template _LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n) -{ +vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) { _ConstructTransaction __tx(*this, __n); __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_); } @@ -1126,11 +1253,7 @@ template ::vector(_InputIterator __first, _InputIterator __last) { - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - for (; __first != __last; ++__first) - emplace_back(*__first); - __guard.__complete(); + __init_with_sentinel(__first, __last); } template @@ -1141,11 +1264,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : __end_cap_(nullptr, __a) { - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - for (; __first != __last; ++__first) - emplace_back(*__first); - __guard.__complete(); + __init_with_sentinel(__first, __last); } template @@ -1155,15 +1274,8 @@ template ::vector(_ForwardIterator __first, _ForwardIterator __last) { - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - size_type __n = static_cast(std::distance(__first, __last)); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__first, __last, __n); - } - __guard.__complete(); + size_type __n = static_cast(std::distance(__first, __last)); + __init_with_size(__first, __last, __n); } template @@ -1174,15 +1286,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a) : __end_cap_(nullptr, __a) { - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - size_type __n = static_cast(std::distance(__first, __last)); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__first, __last, __n); - } - __guard.__complete(); + size_type __n = static_cast(std::distance(__first, __last)); + __init_with_size(__first, __last, __n); } template @@ -1190,15 +1295,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<_Tp, _Allocator>::vector(const vector& __x) : __end_cap_(nullptr, __alloc_traits::select_on_container_copy_construction(__x.__alloc())) { - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - size_type __n = __x.size(); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__x.__begin_, __x.__end_, __n); - } - __guard.__complete(); + __init_with_size(__x.__begin_, __x.__end_, __x.size()); } template @@ -1206,15 +1303,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<_Tp, _Allocator>::vector(const vector& __x, const __type_identity_t& __a) : __end_cap_(nullptr, __a) { - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - size_type __n = __x.size(); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__x.__begin_, __x.__end_, __n); - } - __guard.__complete(); + __init_with_size(__x.__begin_, __x.__end_, __x.size()); } template @@ -1358,6 +1447,13 @@ template ::assign(_InputIterator __first, _InputIterator __last) { + __assign_with_sentinel(__first, __last); +} + +template +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI +void vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) { clear(); for (; __first != __last; ++__first) emplace_back(*__first); @@ -1370,22 +1466,27 @@ template ::assign(_ForwardIterator __first, _ForwardIterator __last) { - size_type __new_size = static_cast(std::distance(__first, __last)); + __assign_with_size(__first, __last, std::distance(__first, __last)); +} + +template +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI +void vector<_Tp, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n) { + size_type __new_size = static_cast(__n); if (__new_size <= capacity()) { - _ForwardIterator __mid = __last; - bool __growing = false; if (__new_size > size()) { - __growing = true; - __mid = __first; - std::advance(__mid, size()); - } - pointer __m = std::copy(__first, __mid, this->__begin_); - if (__growing) + _ForwardIterator __mid = std::next(__first, size()); + std::copy(__first, __mid, this->__begin_); __construct_at_end(__mid, __last, __new_size - size()); + } else + { + pointer __m = std::__copy<_ClassicAlgPolicy>(__first, __last, this->__begin_).second; this->__destruct_at_end(__m); + } } else { @@ -1815,7 +1916,6 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_ } return __make_iter(__p); } - template template ::value && is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value, @@ -1823,8 +1923,17 @@ template ::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, - "vector::insert(iterator, range) called with an iterator not referring to this vector"); + return __insert_with_sentinel(__position, __first, __last); +} + +template +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI +typename vector<_Tp, _Allocator>::iterator +vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, + "vector::insert called with an iterator not referring to this vector"); + difference_type __off = __position - begin(); pointer __p = this->__begin_ + __off; allocator_type& __a = this->__alloc(); @@ -1840,7 +1949,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - __v.__construct_at_end(__first, __last); + __v.__construct_at_end_with_sentinel(std::move(__first), std::move(__last)); difference_type __old_size = __old_last - this->__begin_; difference_type __old_p = __p - this->__begin_; reserve(__recommend(size() + __v.size())); @@ -1868,17 +1977,27 @@ template ::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { + return __insert_with_size(__position, __first, __last, std::distance(__first, __last)); +} + +template +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI +typename vector<_Tp, _Allocator>::iterator +vector<_Tp, _Allocator>::__insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, + difference_type __n) { _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, - "vector::insert(iterator, range) called with an iterator not referring to this vector"); + "vector::insert called with an iterator not referring to this vector"); + + auto __insertion_size = __n; pointer __p = this->__begin_ + (__position - begin()); - difference_type __n = std::distance(__first, __last); if (__n > 0) { if (__n <= this->__end_cap() - this->__end_) { size_type __old_n = __n; pointer __old_last = this->__end_; - _ForwardIterator __m = __last; + _Iterator __m = std::next(__first, __n); difference_type __dx = this->__end_ - __p; if (__n > __dx) { @@ -1898,7 +2017,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __fi { allocator_type& __a = this->__alloc(); __split_buffer __v(__recommend(size() + __n), __p - this->__begin_, __a); - __v.__construct_at_end(__first, __last); + __v.__construct_at_end_with_size(__first, __insertion_size); __p = __swap_out_circular_buffer(__v, __p); } } @@ -2146,6 +2265,23 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a, typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0); +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange _Range> + _LIBCPP_HIDE_FROM_ABI constexpr + vector(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) + : __begin_(nullptr), + __size_(0), + __cap_alloc_(0, static_cast<__storage_allocator>(__a)) { + if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { + auto __n = static_cast(ranges::distance(__range)); + __init_with_size(ranges::begin(__range), ranges::end(__range), __n); + + } else { + __init_with_sentinel(ranges::begin(__range), ranges::end(__range)); + } + } +#endif + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v, const allocator_type& __a); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector& operator=(const vector& __v); @@ -2185,6 +2321,20 @@ public: >::type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_ForwardIterator __first, _ForwardIterator __last); +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange _Range> + _LIBCPP_HIDE_FROM_ABI + constexpr void assign_range(_Range&& __range) { + if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { + auto __n = static_cast(ranges::distance(__range)); + __assign_with_size(ranges::begin(__range), ranges::end(__range), __n); + + } else { + __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); + } + } +#endif + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void assign(size_type __n, const value_type& __x); #ifndef _LIBCPP_CXX03_LANG @@ -2274,6 +2424,14 @@ public: } #endif +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange _Range> + _LIBCPP_HIDE_FROM_ABI + constexpr void append_range(_Range&& __range) { + insert_range(end(), std::forward<_Range>(__range)); + } +#endif + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back() {--__size_;} #if _LIBCPP_STD_VER >= 14 @@ -2297,6 +2455,20 @@ public: >::type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last); +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange _Range> + _LIBCPP_HIDE_FROM_ABI + constexpr iterator insert_range(const_iterator __position, _Range&& __range) { + if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { + auto __n = static_cast(ranges::distance(__range)); + return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n); + + } else { + return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); + } + } +#endif + #ifndef _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __position, initializer_list __il) @@ -2334,6 +2506,53 @@ private: std::__throw_out_of_range("vector"); } + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __n) { + auto __guard = std::__make_exception_guard(__destroy_vector(*this)); + + if (__n > 0) { + __vallocate(__n); + __construct_at_end(std::move(__first), std::move(__last), __n); + } + + __guard.__complete(); + } + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + void __init_with_sentinel(_InputIterator __first, _Sentinel __last) { +#ifndef _LIBCPP_HAS_NO_EXCEPTIONS + try { +#endif // _LIBCPP_HAS_NO_EXCEPTIONS + for (; __first != __last; ++__first) + push_back(*__first); +#ifndef _LIBCPP_HAS_NO_EXCEPTIONS + } catch (...) { + if (__begin_ != nullptr) + __storage_traits::deallocate(__alloc(), __begin_, __cap()); + std::__debug_db_invalidate_all(this); + throw; + } +#endif // _LIBCPP_HAS_NO_EXCEPTIONS + } + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + void __assign_with_sentinel(_Iterator __first, _Sentinel __last); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + void __assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __ns); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + iterator __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + iterator __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n); + // Allocate space for __n objects // throws length_error if __n > max_size() // throws (probably bad_alloc) if memory run out @@ -2360,13 +2579,9 @@ private: {return (__new_size + (__bits_per_word-1)) & ~((size_type)__bits_per_word-1);} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __new_size) const; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_at_end(size_type __n, bool __x); - template - typename enable_if - < - __is_cpp17_forward_iterator<_ForwardIterator>::value, - void - >::type - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append(size_type __n, const_reference __x); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference __make_ref(size_type __pos) _NOEXCEPT @@ -2496,17 +2711,11 @@ vector::__construct_at_end(size_type __n, bool __x) } template -template +template _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename enable_if -< - __is_cpp17_forward_iterator<_ForwardIterator>::value, - void ->::type -vector::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) -{ +void vector::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) { size_type __old_size = this->__size_; - this->__size_ += std::distance(__first, __last); + this->__size_ += __n; if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word)) { if (this->__size_ <= __bits_per_word) @@ -2514,7 +2723,7 @@ vector::__construct_at_end(_ForwardIterator __first, _ForwardI else this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0); } - std::copy(__first, __last, __make_iter(__old_size)); + std::__copy<_ClassicAlgPolicy>(__first, __last, __make_iter(__old_size)); } template @@ -2608,22 +2817,7 @@ vector::vector(_InputIterator __first, _InputIterator __last, __size_(0), __cap_alloc_(0, __default_init_tag()) { -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_HAS_NO_EXCEPTIONS - for (; __first != __last; ++__first) - push_back(*__first); -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (...) - { - if (__begin_ != nullptr) - __storage_traits::deallocate(__alloc(), __begin_, __cap()); - std::__debug_db_invalidate_all(this); - throw; - } -#endif // _LIBCPP_HAS_NO_EXCEPTIONS + __init_with_sentinel(__first, __last); } template @@ -2635,22 +2829,7 @@ vector::vector(_InputIterator __first, _InputIterator __last, __size_(0), __cap_alloc_(0, static_cast<__storage_allocator>(__a)) { -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_HAS_NO_EXCEPTIONS - for (; __first != __last; ++__first) - push_back(*__first); -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (...) - { - if (__begin_ != nullptr) - __storage_traits::deallocate(__alloc(), __begin_, __cap()); - std::__debug_db_invalidate_all(this); - throw; - } -#endif // _LIBCPP_HAS_NO_EXCEPTIONS + __init_with_sentinel(__first, __last); } template @@ -2662,14 +2841,8 @@ vector::vector(_ForwardIterator __first, _ForwardIterator __la __size_(0), __cap_alloc_(0, __default_init_tag()) { - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - size_type __n = static_cast(std::distance(__first, __last)); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__first, __last); - } - __guard.__complete(); + auto __n = static_cast(std::distance(__first, __last)); + __init_with_size(__first, __last, __n); } template @@ -2681,14 +2854,8 @@ vector::vector(_ForwardIterator __first, _ForwardIterator __la __size_(0), __cap_alloc_(0, static_cast<__storage_allocator>(__a)) { - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - size_type __n = static_cast(std::distance(__first, __last)); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__first, __last); - } - __guard.__complete(); + auto __n = static_cast(std::distance(__first, __last)); + __init_with_size(__first, __last, __n); } #ifndef _LIBCPP_CXX03_LANG @@ -2704,7 +2871,7 @@ vector::vector(initializer_list __il) if (__n > 0) { __vallocate(__n); - __construct_at_end(__il.begin(), __il.end()); + __construct_at_end(__il.begin(), __il.end(), __n); } } @@ -2719,7 +2886,7 @@ vector::vector(initializer_list __il, const alloca if (__n > 0) { __vallocate(__n); - __construct_at_end(__il.begin(), __il.end()); + __construct_at_end(__il.begin(), __il.end(), __n); } } @@ -2735,7 +2902,7 @@ vector::vector(const vector& __v) if (__v.size() > 0) { __vallocate(__v.size()); - __construct_at_end(__v.begin(), __v.end()); + __construct_at_end(__v.begin(), __v.end(), __v.size()); } } @@ -2749,7 +2916,7 @@ vector::vector(const vector& __v, const allocator_type& __a) if (__v.size() > 0) { __vallocate(__v.size()); - __construct_at_end(__v.begin(), __v.end()); + __construct_at_end(__v.begin(), __v.end(), __v.size()); } } @@ -2808,7 +2975,7 @@ vector::vector(vector&& __v, const __type_identity_t 0) { __vallocate(__v.size()); - __construct_at_end(__v.begin(), __v.end()); + __construct_at_end(__v.begin(), __v.end(), __v.size()); } } @@ -2876,6 +3043,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__is_exactly_cpp17_input_itera >::type vector::assign(_InputIterator __first, _InputIterator __last) { + __assign_with_sentinel(__first, __last); +} + +template +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI +void vector::__assign_with_sentinel(_Iterator __first, _Sentinel __last) { clear(); for (; __first != __last; ++__first) push_back(*__first); @@ -2891,9 +3065,17 @@ typename enable_if >::type vector::assign(_ForwardIterator __first, _ForwardIterator __last) { - clear(); - difference_type __ns = std::distance(__first, __last); + __assign_with_size(__first, __last, std::distance(__first, __last)); +} + +template +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI +void vector::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __ns) { _LIBCPP_ASSERT(__ns >= 0, "invalid range specified"); + + clear(); + const size_t __n = static_cast(__ns); if (__n) { @@ -2902,7 +3084,7 @@ vector::assign(_ForwardIterator __first, _ForwardIterator __la __vdeallocate(); __vallocate(__n); } - __construct_at_end(__first, __last); + __construct_at_end(__first, __last, __n); } } @@ -2916,7 +3098,7 @@ vector::reserve(size_type __n) this->__throw_length_error(); vector __v(this->get_allocator()); __v.__vallocate(__n); - __v.__construct_at_end(this->begin(), this->end()); + __v.__construct_at_end(this->begin(), this->end(), this->size()); swap(__v); std::__debug_db_invalidate_all(this); } @@ -3028,6 +3210,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__is_exactly_cpp17_input_itera >::type vector::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { + return __insert_with_sentinel(__position, __first, __last); +} + +template +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI +typename vector::iterator +vector::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) { difference_type __off = __position - begin(); iterator __p = __const_iterator_cast(__position); iterator __old_end = end(); @@ -3043,7 +3233,7 @@ vector::insert(const_iterator __position, _InputIterator __fir try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - __v.assign(__first, __last); + __v.__assign_with_sentinel(std::move(__first), std::move(__last)); difference_type __old_size = static_cast(__old_end - begin()); difference_type __old_p = __p - begin(); reserve(__recommend(size() + __v.size())); @@ -3073,7 +3263,15 @@ typename enable_if >::type vector::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { - const difference_type __n_signed = std::distance(__first, __last); + return __insert_with_size(__position, __first, __last, std::distance(__first, __last)); +} + +template +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI +typename vector::iterator +vector::__insert_with_size(const_iterator __position, _ForwardIterator __first, _Sentinel __last, + difference_type __n_signed) { _LIBCPP_ASSERT(__n_signed >= 0, "invalid range specified"); const size_type __n = static_cast(__n_signed); iterator __r; @@ -3094,7 +3292,7 @@ vector::insert(const_iterator __position, _ForwardIterator __f std::copy_backward(__position, cend(), __v.end()); swap(__v); } - std::copy(__first, __last, __r); + std::__copy<_ClassicAlgPolicy>(__first, __last, __r); return __r; } diff --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp index d8a8218939439..c7d035274c56d 100644 --- a/libcxx/test/libcxx/private_headers.verify.cpp +++ b/libcxx/test/libcxx/private_headers.verify.cpp @@ -580,6 +580,7 @@ END-SCRIPT #include <__ranges/as_rvalue_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/as_rvalue_view.h'}} #include <__ranges/common_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/common_view.h'}} #include <__ranges/concepts.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/concepts.h'}} +#include <__ranges/container_compatible_range.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/container_compatible_range.h'}} #include <__ranges/copyable_box.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/copyable_box.h'}} #include <__ranges/counted.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/counted.h'}} #include <__ranges/dangling.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/dangling.h'}} @@ -592,6 +593,7 @@ END-SCRIPT #include <__ranges/enable_borrowed_range.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/enable_borrowed_range.h'}} #include <__ranges/enable_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/enable_view.h'}} #include <__ranges/filter_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/filter_view.h'}} +#include <__ranges/from_range.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/from_range.h'}} #include <__ranges/iota_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/iota_view.h'}} #include <__ranges/istream_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/istream_view.h'}} #include <__ranges/join_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/join_view.h'}} diff --git a/libcxx/test/std/containers/from_range_helpers.h b/libcxx/test/std/containers/from_range_helpers.h new file mode 100644 index 0000000000000..9bd72acfad09b --- /dev/null +++ b/libcxx/test/std/containers/from_range_helpers.h @@ -0,0 +1,154 @@ +//===----------------------------------------------------------------------===// +// +// 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 SUPPORT_FROM_RANGE_HELPERS_H +#define SUPPORT_FROM_RANGE_HELPERS_H + +#include +#include +#include + +#include "min_allocator.h" +#include "test_allocator.h" +#include "test_iterators.h" +#include "test_macros.h" +#include "type_algorithms.h" + +struct Empty {}; + +template +struct InputRange { + cpp20_input_iterator begin(); + sentinel_wrapper> end(); +}; + +template +constexpr auto wrap_input(Range&& input) { + auto b = Iter(std::ranges::begin(input)); + auto e = Sent(Iter(std::ranges::end(input))); + return std::ranges::subrange(std::move(b), std::move(e)); +} + +template +constexpr auto wrap_input(std::vector& input) { + auto b = Iter(input.data()); + auto e = Sent(Iter(input.data() + input.size())); + return std::ranges::subrange(std::move(b), std::move(e)); +} + +struct KeyValue { + int key; // Only the key is considered for equality comparison. + char value; // Allows distinguishing equivalent instances. + + bool operator<(const KeyValue& other) const { return key < other.key; } + bool operator==(const KeyValue& other) const { return key == other.key; } +}; + +template <> +struct std::hash { + std::size_t operator()(const KeyValue& kv) const { + return kv.key; + } +}; + +#if !defined(TEST_HAS_NO_EXCEPTIONS) +template +struct ThrowingCopy { + static bool throwing_enabled; + static int created_by_copying; + static int destroyed; + int x = 0; // Allows distinguishing between different instances. + + ThrowingCopy() = default; + ThrowingCopy(int value) : x(value) {} + ~ThrowingCopy() { + ++destroyed; + } + + ThrowingCopy(const ThrowingCopy& other) : x(other.x) { + ++created_by_copying; + if (throwing_enabled && created_by_copying == N) { + throw -1; + } + } + + // Defined to silence GCC warnings. For test purposes, only copy construction is considered `created_by_copying`. + ThrowingCopy& operator=(const ThrowingCopy& other) { + x = other.x; + return *this; + } + + friend auto operator<=>(const ThrowingCopy&, const ThrowingCopy&) = default; + + static void reset() { + created_by_copying = destroyed = 0; + } +}; + +template +struct std::hash> { + std::size_t operator()(const ThrowingCopy& value) const { + return value.x; + } +}; + +template +bool ThrowingCopy::throwing_enabled = true; +template +int ThrowingCopy::created_by_copying = 0; +template +int ThrowingCopy::destroyed = 0; + +template +struct ThrowingAllocator { + using value_type = T; + using char_type = T; + using is_always_equal = std::false_type; + + ThrowingAllocator() = default; + + template + ThrowingAllocator(const ThrowingAllocator&) {} + + T* allocate(std::size_t) { throw 1; } + void deallocate(T*, std::size_t) {} + + template + friend bool operator==(const ThrowingAllocator&, const ThrowingAllocator&) { + return true; + } +}; +#endif + +template +constexpr void for_all_iterators_and_allocators(Func f) { + using Iterators = types::type_list< + cpp20_input_iterator, + forward_iterator, + bidirectional_iterator, + random_access_iterator, + contiguous_iterator, + T* + >; + + types::for_each(Iterators{}, [=]() { + f.template operator(), std::allocator>(); + f.template operator(), test_allocator>(); + f.template operator(), min_allocator>(); + f.template operator(), safe_allocator>(); + + if constexpr (std::sentinel_for) { + f.template operator()>(); + f.template operator()>(); + f.template operator()>(); + f.template operator()>(); + } + }); +} + +#endif // SUPPORT_FROM_RANGE_HELPERS_H diff --git a/libcxx/test/std/containers/insert_range_helpers.h b/libcxx/test/std/containers/insert_range_helpers.h new file mode 100644 index 0000000000000..2c4e14ce8b737 --- /dev/null +++ b/libcxx/test/std/containers/insert_range_helpers.h @@ -0,0 +1,123 @@ +//===----------------------------------------------------------------------===// +// +// 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 SUPPORT_INSERT_RANGE_HELPERS_H +#define SUPPORT_INSERT_RANGE_HELPERS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "from_range_helpers.h" +#include "min_allocator.h" +#include "test_allocator.h" +#include "test_iterators.h" +#include "test_macros.h" +#include "type_algorithms.h" + +// A simple literal-type container. It can be used as a `constexpr` global variable (which isn't supported by +// `std::vector`). +template +class Buffer { + public: + constexpr Buffer() = default; + + constexpr Buffer(std::initializer_list input) { + assert(input.size() <= N); + std::ranges::copy(input, data_); + size_ = input.size(); + } + + // Makes initializing `Buffer` nicer -- allows writing `buf = "abc"` instead of `buf = {'a', 'b', 'c'}`. + // To make the two forms equivalent, omits the terminating null. + template + constexpr Buffer(const char (&input) [N2]) + requires std::same_as { + static_assert(N2 <= N); + std::ranges::copy(input, data_); + // Omit the terminating null. + size_ = input[N2 - 1] == '\0' ? N2 - 1 : N2; + } + + constexpr const T* begin() const { return data_; } + constexpr const T* end() const { return data_ + size_; } + constexpr std::size_t size() const { return size_; } + + private: + std::size_t size_ = 0; + T data_[N] = {}; +}; + +template +struct TestCase { + Buffer initial; + std::size_t index = 0; + Buffer input; + Buffer expected; +}; + +template +constexpr void for_all_iterators_and_allocators(Func f) { + using Iterators = types::type_list< + cpp20_input_iterator, + forward_iterator, + bidirectional_iterator, + random_access_iterator, + contiguous_iterator, + PtrT + >; + + types::for_each(Iterators{}, [=]() { + f.template operator(), std::allocator>(); + f.template operator(), test_allocator>(); + f.template operator(), min_allocator>(); + f.template operator(), safe_allocator>(); + + if constexpr (std::sentinel_for) { + f.template operator()>(); + f.template operator()>(); + f.template operator()>(); + f.template operator()>(); + } + }); +} + +// Uses a shorter list of iterator types for use in `constexpr` mode for cases when running the full set in would take +// too long. +template +constexpr void for_all_iterators_and_allocators_constexpr(Func f) { + using Iterators = types::type_list< + cpp20_input_iterator, + forward_iterator, + PtrT + >; + + types::for_each(Iterators{}, [=]() { + f.template operator(), std::allocator>(); + f.template operator(), test_allocator>(); + f.template operator(), min_allocator>(); + f.template operator(), safe_allocator>(); + + if constexpr (std::sentinel_for) { + f.template operator()>(); + f.template operator()>(); + f.template operator()>(); + f.template operator()>(); + } + }); +} + +#endif // SUPPORT_INSERT_RANGE_HELPERS_H diff --git a/libcxx/test/std/containers/sequences/from_range_sequence_containers.h b/libcxx/test/std/containers/sequences/from_range_sequence_containers.h new file mode 100644 index 0000000000000..7106cb8077332 --- /dev/null +++ b/libcxx/test/std/containers/sequences/from_range_sequence_containers.h @@ -0,0 +1,161 @@ +//===----------------------------------------------------------------------===// +// +// 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 SUPPORT_FROM_RANGE_SEQUENCE_CONTAINERS_H +#define SUPPORT_FROM_RANGE_SEQUENCE_CONTAINERS_H + +#include +#include +#include +#include +#include +#include +#include + +#include "../from_range_helpers.h" +#include "MoveOnly.h" +#include "almost_satisfies_types.h" +#include "count_new.h" +#include "test_iterators.h" +#include "test_macros.h" + +template +concept HasSize = requires (const T& value) { value.size(); }; + +template +concept HasFromRangeCtr = requires (Range&& range) { + Container(std::from_range, std::forward(range)); + Container(std::from_range, std::forward(range), std::allocator()); +}; + +template