From 16397e8ec7ffbee2907dfec698356f67672086e8 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Sat, 1 Jun 2024 16:16:15 +0800 Subject: [PATCH 001/678] [Clang][Sema] Push an evaluation context for type constraints (#93945) This helps getTemplateInstantiationArgs() to properly recover template arguments of an enclosing concept Decl. Fixes https://github.com/llvm/llvm-project/issues/93821 --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaTemplate.cpp | 2 +- clang/lib/Sema/SemaTemplateDeduction.cpp | 14 ++++++++++++++ clang/test/SemaTemplate/concepts-lambda.cpp | 12 ++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 22b4dc172c84..0c700d23257b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -822,6 +822,7 @@ Bug Fixes to C++ Support - Fix a regression introduced in Clang 18 causing incorrect overload resolution in the presence of functions only differering by their constraints when only one of these function was variadic. - Fix a crash when a variable is captured by a block nested inside a lambda. (Fixes #GH93625). +- Fixed a type constraint substitution issue involving a generic lambda expression. (#GH93821) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3e3ed77de710..40a759ea330d 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5660,7 +5660,7 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, LocalInstantiationScope Scope(*this); EnterExpressionEvaluationContext EECtx{ - *this, ExpressionEvaluationContext::ConstantEvaluated, CSD}; + *this, ExpressionEvaluationContext::Unevaluated, CSD}; if (!AreArgsDependent && CheckConstraintSatisfaction( diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 8ec49fcf553d..1011db2d2830 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5134,6 +5134,20 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, return true; MultiLevelTemplateArgumentList MLTAL(Concept, CanonicalConverted, /*Final=*/false); + // Build up an EvaluationContext with an ImplicitConceptSpecializationDecl so + // that the template arguments of the constraint can be preserved. For + // example: + // + // template + // concept C = []() { return true; }(); + // + // We need the argument for T while evaluating type constraint D in + // building the CallExpr to the lambda. + EnterExpressionEvaluationContext EECtx( + S, Sema::ExpressionEvaluationContext::Unevaluated, + ImplicitConceptSpecializationDecl::Create( + S.getASTContext(), Concept->getDeclContext(), Concept->getLocation(), + CanonicalConverted)); if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()}, MLTAL, TypeLoc.getLocalSourceRange(), Satisfaction)) diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp index fac790d09f9c..280be71284f9 100644 --- a/clang/test/SemaTemplate/concepts-lambda.cpp +++ b/clang/test/SemaTemplate/concepts-lambda.cpp @@ -225,3 +225,15 @@ void foo() { }(x); } } // namespace GH73418 + +namespace GH93821 { + +template +concept C = true; + +template +concept D = []() { return true; }(); + +D auto x = 0; + +} // namespace GH93821 -- GitLab From cd676e5b27cb985697deac052c797057f5a33c06 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Sat, 1 Jun 2024 12:47:49 +0300 Subject: [PATCH 002/678] [lldb] Guard some GCC-style flags from MSVC A follow up to #92953. Suggested in https://github.com/llvm/llvm-project/pull/92953#issuecomment-2143274065 --- lldb/cmake/modules/LLDBConfig.cmake | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index f2afced7403b..a60921990cf7 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -186,13 +186,15 @@ include_directories("${CMAKE_CURRENT_BINARY_DIR}/../clang/include") # printed. Therefore, check for whether the compiler supports options in the # form -W, and if supported, add the corresponding -Wno- option. -# Disable GCC warnings -append("-Wno-deprecated-declarations" CMAKE_CXX_FLAGS) -append("-Wno-unknown-pragmas" CMAKE_CXX_FLAGS) -append("-Wno-strict-aliasing" CMAKE_CXX_FLAGS) - -check_cxx_compiler_flag("-Wstringop-truncation" CXX_SUPPORTS_STRINGOP_TRUNCATION) -append_if(CXX_SUPPORTS_STRINGOP_TRUNCATION "-Wno-stringop-truncation" CMAKE_CXX_FLAGS) +if (LLVM_COMPILER_IS_GCC_COMPATIBLE) + # Disable GCC warnings + append("-Wno-deprecated-declarations" CMAKE_CXX_FLAGS) + append("-Wno-unknown-pragmas" CMAKE_CXX_FLAGS) + append("-Wno-strict-aliasing" CMAKE_CXX_FLAGS) + + check_cxx_compiler_flag("-Wstringop-truncation" CXX_SUPPORTS_STRINGOP_TRUNCATION) + append_if(CXX_SUPPORTS_STRINGOP_TRUNCATION "-Wno-stringop-truncation" CMAKE_CXX_FLAGS) +endif() # Disable Clang warnings if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") -- GitLab From 9d4b20a44e5c55499d6fc75663a6c7149a59543f Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Sat, 1 Jun 2024 12:04:56 +0200 Subject: [PATCH 003/678] [mlir][bufferization] Allow mixed static/dynamic shapes in `materialize_in_destination` op (#92681) This commit relaxes the verifier of `bufferization.materialize_in_destination` such that mixed static/dynamic dimensions are allowed for the source and destination operands. E.g., `tensor<5xf32>` and `tensor` are now compatible, but it is assumed that the dynamic dimension is `5` at runtime. This commit fixes #91265. --- .../Bufferization/IR/BufferizationOps.td | 9 ++++----- .../Bufferization/IR/BufferizationOps.cpp | 18 ++++++++++++++++++ mlir/test/Dialect/Bufferization/invalid.mlir | 13 ++++++++++--- mlir/test/Dialect/Bufferization/ops.mlir | 7 +++++-- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizationOps.td b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizationOps.td index 4f609ddff9a4..1c70a4b8df92 100644 --- a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizationOps.td +++ b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizationOps.td @@ -217,8 +217,7 @@ def Bufferization_CloneOp : Bufferization_Op<"clone", [ def Bufferization_MaterializeInDestinationOp : Bufferization_Op<"materialize_in_destination", - [AllShapesMatch<["source", "dest"]>, - AllElementTypesMatch<["source", "dest"]>, + [AllElementTypesMatch<["source", "dest"]>, BufferizableOpInterface, DestinationStyleOpInterface, DeclareOpInterfaceMethods, DeclareOpInterfaceMethods(getDest().getType())) return emitOpError("'writable' must be specified if and only if the " "destination is of memref type"); + TensorType srcType = getSource().getType(); + ShapedType destType = cast(getDest().getType()); + if (srcType.hasRank() != destType.hasRank()) + return emitOpError("source/destination shapes are incompatible"); + if (srcType.hasRank()) { + if (srcType.getRank() != destType.getRank()) + return emitOpError("rank mismatch between source and destination shape"); + for (auto [src, dest] : + llvm::zip(srcType.getShape(), destType.getShape())) { + if (src == ShapedType::kDynamic || dest == ShapedType::kDynamic) { + // Cannot verify dynamic dimension size. Assume that that they match at + // runtime. + continue; + } + if (src != dest) + return emitOpError("source/destination shapes are incompatible"); + } + } return success(); } diff --git a/mlir/test/Dialect/Bufferization/invalid.mlir b/mlir/test/Dialect/Bufferization/invalid.mlir index 4ebdb0a8f049..2c8807b66de7 100644 --- a/mlir/test/Dialect/Bufferization/invalid.mlir +++ b/mlir/test/Dialect/Bufferization/invalid.mlir @@ -43,9 +43,16 @@ func.func @invalid_writable_on_op() { // ----- -func.func @invalid_materialize_in_destination(%arg0: tensor, %arg1: tensor<5xf32>) { - // expected-error @below{{failed to verify that all of {source, dest} have same shape}} - bufferization.materialize_in_destination %arg0 in %arg1 : (tensor, tensor<5xf32>) -> tensor<5xf32> +func.func @invalid_materialize_in_destination(%arg0: tensor<4xf32>, %arg1: tensor<5xf32>) { + // expected-error @below{{source/destination shapes are incompatible}} + bufferization.materialize_in_destination %arg0 in %arg1 : (tensor<4xf32>, tensor<5xf32>) -> tensor<5xf32> +} + +// ----- + +func.func @invalid_materialize_in_destination(%arg0: tensor<5x5xf32>, %arg1: tensor<5xf32>) { + // expected-error @below{{rank mismatch between source and destination shape}} + bufferization.materialize_in_destination %arg0 in %arg1 : (tensor<5x5xf32>, tensor<5xf32>) -> tensor<5xf32> } // ----- diff --git a/mlir/test/Dialect/Bufferization/ops.mlir b/mlir/test/Dialect/Bufferization/ops.mlir index d4bda0632189..ad4a66c1b797 100644 --- a/mlir/test/Dialect/Bufferization/ops.mlir +++ b/mlir/test/Dialect/Bufferization/ops.mlir @@ -59,12 +59,15 @@ func.func @test_dealloc_tensor_op(%arg0: tensor<4xi32>) { } // CHECK-LABEL: func @test_materialize_in_destination_op -func.func @test_materialize_in_destination_op(%arg0: tensor, %arg1: tensor, %arg2: memref) - -> tensor { +func.func @test_materialize_in_destination_op( + %arg0: tensor, %arg1: tensor, %arg2: memref, + %arg4: tensor<5xf32>) -> tensor { // CHECK: bufferization.materialize_in_destination {{.*}} : (tensor, tensor) -> tensor %1 = bufferization.materialize_in_destination %arg0 in %arg1 : (tensor, tensor) -> tensor // CHECK: bufferization.materialize_in_destination {{.*}} : (tensor, memref) -> () bufferization.materialize_in_destination %arg0 in restrict writable %arg2 : (tensor, memref) -> () + // CHECK: bufferization.materialize_in_destination {{.*}} : (tensor, tensor<5xf32>) -> tensor<5xf32> + %2 = bufferization.materialize_in_destination %arg0 in %arg4 : (tensor, tensor<5xf32>) -> tensor<5xf32> return %1 : tensor } -- GitLab From cb7a03b41fff563c0cbb5145eed09f9b17edf9e2 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Sat, 1 Jun 2024 12:20:41 +0200 Subject: [PATCH 004/678] [libc++] Fix failures with GCC 14 (#92663) Fixes #91831 --- libcxx/include/__string/constexpr_c_functions.h | 2 +- libcxx/include/__type_traits/remove_pointer.h | 5 +++++ libcxx/include/bitset | 3 +++ .../time.zone/time.zone.leap/nonmembers/comparison.pass.cpp | 4 ++-- .../expected/expected.expected/monadic/transform.pass.cpp | 2 +- .../expected.expected/monadic/transform_error.pass.cpp | 2 +- .../expected/expected.void/monadic/transform_error.pass.cpp | 2 +- .../format.formatter.spec/formatter.char_array.pass.cpp | 2 +- .../utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp | 3 +++ .../variant/variant.visit.member/visit_return_type.pass.cpp | 3 +++ libcxxabi/test/catch_member_function_pointer_02.pass.cpp | 2 +- 11 files changed, 22 insertions(+), 8 deletions(-) diff --git a/libcxx/include/__string/constexpr_c_functions.h b/libcxx/include/__string/constexpr_c_functions.h index 4da8542e3807..a978f816f189 100644 --- a/libcxx/include/__string/constexpr_c_functions.h +++ b/libcxx/include/__string/constexpr_c_functions.h @@ -123,7 +123,7 @@ __constexpr_memcmp_equal(const _Tp* __lhs, const _Up* __rhs, __element_count __n } return true; } else { - return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)) == 0; + return ::__builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)) == 0; } } diff --git a/libcxx/include/__type_traits/remove_pointer.h b/libcxx/include/__type_traits/remove_pointer.h index 54390a1939f7..1048f67055a2 100644 --- a/libcxx/include/__type_traits/remove_pointer.h +++ b/libcxx/include/__type_traits/remove_pointer.h @@ -23,8 +23,13 @@ struct remove_pointer { using type _LIBCPP_NODEBUG = __remove_pointer(_Tp); }; +# ifdef _LIBCPP_COMPILER_GCC +template +using __remove_pointer_t = typename remove_pointer<_Tp>::type; +# else template using __remove_pointer_t = __remove_pointer(_Tp); +# endif #else // clang-format off template struct _LIBCPP_TEMPLATE_VIS remove_pointer {typedef _LIBCPP_NODEBUG _Tp type;}; diff --git a/libcxx/include/bitset b/libcxx/include/bitset index 8818ab6563b5..6bd7bfe585f3 100644 --- a/libcxx/include/bitset +++ b/libcxx/include/bitset @@ -375,8 +375,11 @@ template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const { unsigned long long __r = __first_[0]; + _LIBCPP_DIAGNOSTIC_PUSH + _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow") for (size_t __i = 1; __i < sizeof(unsigned long long) / sizeof(__storage_type); ++__i) __r |= static_cast(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT); + _LIBCPP_DIAGNOSTIC_POP return __r; } diff --git a/libcxx/test/std/time/time.zone/time.zone.leap/nonmembers/comparison.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.leap/nonmembers/comparison.pass.cpp index 448cd88d146f..ccff0248ebac 100644 --- a/libcxx/test/std/time/time.zone/time.zone.leap/nonmembers/comparison.pass.cpp +++ b/libcxx/test/std/time/time.zone/time.zone.leap/nonmembers/comparison.pass.cpp @@ -9,8 +9,8 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17 // UNSUPPORTED: no-filesystem, no-localization, no-tzdb -// TODO TZDB test whether this can be enabled with gcc 14. -// UNSUPPORTED: gcc-13 +// TODO TZDB investigate why this fails with GCC +// UNSUPPORTED: gcc-13, gcc-14 // XFAIL: libcpp-has-no-experimental-tzdb // XFAIL: availability-tzdb-missing diff --git a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp index d38a46f04524..aa7106fb91ad 100644 --- a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp +++ b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform.pass.cpp @@ -10,7 +10,7 @@ // GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`, // please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108333 -// XFAIL: gcc-13 +// XFAIL: gcc-13, gcc-14 // diff --git a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp index ec55f637f020..ae9feccb58cf 100644 --- a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp +++ b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp @@ -10,7 +10,7 @@ // GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`, // please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108333. -// XFAIL: gcc-13 +// XFAIL: gcc-13, gcc-14 // diff --git a/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp index cd6e5a5038d2..f70bddbed020 100644 --- a/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp +++ b/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp @@ -10,7 +10,7 @@ // GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`, // please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108333 -// XFAIL: gcc-13 +// XFAIL: gcc-13, gcc-14 // diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp index b0ee399a1c19..cad13c1efeca 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp @@ -7,7 +7,7 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17 // TODO FMT __builtin_memcpy isn't constexpr in GCC -// UNSUPPORTED: gcc-13 +// UNSUPPORTED: gcc-13, gcc-14 // diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp index c9e7bb6a57e2..0b40ac9ff046 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp @@ -8,6 +8,9 @@ // UNSUPPORTED: c++03 +// FIXME: Why does this start to fail with GCC 14? +// XFAIL: gcc-14 + // See https://llvm.org/PR31384. #include diff --git a/libcxx/test/std/utilities/variant/variant.visit.member/visit_return_type.pass.cpp b/libcxx/test/std/utilities/variant/variant.visit.member/visit_return_type.pass.cpp index 2c1cbb06e706..7429cdf80fac 100644 --- a/libcxx/test/std/utilities/variant/variant.visit.member/visit_return_type.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.visit.member/visit_return_type.pass.cpp @@ -34,6 +34,9 @@ struct overloaded : Ts... { using Ts::operator()...; }; +template +overloaded(Ts...) -> overloaded; + void test_overload_ambiguity() { using V = std::variant; using namespace std::string_literals; diff --git a/libcxxabi/test/catch_member_function_pointer_02.pass.cpp b/libcxxabi/test/catch_member_function_pointer_02.pass.cpp index c4a07c1297dd..b4b8ce823499 100644 --- a/libcxxabi/test/catch_member_function_pointer_02.pass.cpp +++ b/libcxxabi/test/catch_member_function_pointer_02.pass.cpp @@ -15,7 +15,7 @@ // GCC supports noexcept function types but this test still fails. // This is likely a bug in their implementation. Investigation needed. -// XFAIL: gcc-13 +// XFAIL: gcc-13, gcc-14 #include -- GitLab From 47fd32f81c593ae698765e3f3f13998ac9a9abbf Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 1 Jun 2024 19:04:55 +0800 Subject: [PATCH 005/678] [DAGCombine] Fix type mismatch in `(shl X, cttz(Y)) -> (mul (Y & -Y), X)` (#94008) Proof: https://alive2.llvm.org/ce/z/J7GBMU Same as https://github.com/llvm/llvm-project/pull/92753, the types of LHS and RHS in shift nodes may differ. + When VT is smaller than ShiftVT, it is safe to use trunc. + When VT is larger than ShiftVT, it is safe to use zext iff `is_zero_poison` is true (i.e., `opcode == ISD::CTTZ_ZERO_UNDEF`). See also the counterexample `src_shl_cttz2 -> tgt_shl_cttz2` in the alive2 proofs. Fixes issue https://github.com/llvm/llvm-project/pull/85066#issuecomment-2142553617. --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 11 +++-- llvm/test/CodeGen/PowerPC/pr85066.ll | 45 +++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/pr85066.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 4debebf30441..5148b7258257 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -10120,13 +10120,16 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { // fold (shl X, cttz(Y)) -> (mul (Y & -Y), X) if cttz is unsupported on the // target. - if ((N1.getOpcode() == ISD::CTTZ || N1.getOpcode() == ISD::CTTZ_ZERO_UNDEF) && - N1.hasOneUse() && !TLI.isOperationLegalOrCustom(ISD::CTTZ, VT) && + if (((N1.getOpcode() == ISD::CTTZ && + VT.getScalarSizeInBits() >= ShiftVT.getScalarSizeInBits()) || + N1.getOpcode() == ISD::CTTZ_ZERO_UNDEF) && + N1.hasOneUse() && !TLI.isOperationLegalOrCustom(ISD::CTTZ, ShiftVT) && TLI.isOperationLegalOrCustom(ISD::MUL, VT)) { SDValue Y = N1.getOperand(0); SDLoc DL(N); - SDValue NegY = DAG.getNegative(Y, DL, VT); - SDValue And = DAG.getNode(ISD::AND, DL, VT, Y, NegY); + SDValue NegY = DAG.getNegative(Y, DL, ShiftVT); + SDValue And = + DAG.getZExtOrTrunc(DAG.getNode(ISD::AND, DL, ShiftVT, Y, NegY), DL, VT); return DAG.getNode(ISD::MUL, DL, VT, And, N0); } diff --git a/llvm/test/CodeGen/PowerPC/pr85066.ll b/llvm/test/CodeGen/PowerPC/pr85066.ll new file mode 100644 index 000000000000..335038ec4734 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/pr85066.ll @@ -0,0 +1,45 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=powerpc64le < %s | FileCheck %s + +; Tests from pr85066 +define i64 @test_shl_zext_cttz(i16 %x) { +; CHECK-LABEL: test_shl_zext_cttz: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: oris 3, 3, 1 +; CHECK-NEXT: neg 4, 3 +; CHECK-NEXT: and 3, 3, 4 +; CHECK-NEXT: clrldi 3, 3, 32 +; CHECK-NEXT: blr +entry: + %cttz = tail call i16 @llvm.cttz.i16(i16 %x, i1 false) + %zext = zext i16 %cttz to i64 + %res = shl i64 1, %zext + ret i64 %res +} + +define i64 @test_shl_zext_cttz_zero_is_poison(i16 %x) { +; CHECK-LABEL: test_shl_zext_cttz_zero_is_poison: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: neg 4, 3 +; CHECK-NEXT: and 3, 3, 4 +; CHECK-NEXT: clrldi 3, 3, 32 +; CHECK-NEXT: blr +entry: + %cttz = tail call i16 @llvm.cttz.i16(i16 %x, i1 true) + %zext = zext i16 %cttz to i64 + %res = shl i64 1, %zext + ret i64 %res +} + +define i16 @test_shl_trunc_cttz(i32 %x) { +; CHECK-LABEL: test_shl_trunc_cttz: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: neg 4, 3 +; CHECK-NEXT: and 3, 3, 4 +; CHECK-NEXT: blr +entry: + %cttz = tail call i32 @llvm.cttz.i32(i32 %x, i1 false) + %trunc = trunc i32 %cttz to i16 + %res = shl i16 1, %trunc + ret i16 %res +} -- GitLab From 4c6367b3e521f0c18c14db5678748964aeae5215 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Fri, 31 May 2024 17:38:31 -0700 Subject: [PATCH 006/678] [LV] Add test with strided interleave groups and maximizing bandwidth. --- .../LoopVectorize/X86/strided_load_cost.ll | 509 ++++++++++++++++++ 1 file changed, 509 insertions(+) diff --git a/llvm/test/Transforms/LoopVectorize/X86/strided_load_cost.ll b/llvm/test/Transforms/LoopVectorize/X86/strided_load_cost.ll index a72e15870726..48c6063e9409 100644 --- a/llvm/test/Transforms/LoopVectorize/X86/strided_load_cost.ll +++ b/llvm/test/Transforms/LoopVectorize/X86/strided_load_cost.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=loop-vectorize -S -o - | FileCheck %s +; RUN: opt < %s -passes=loop-vectorize -vectorizer-maximize-bandwidth -S -o - | FileCheck --check-prefix=MAX-BW %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -204,6 +205,201 @@ define i32 @matrix_row_col(ptr nocapture readonly %data, i32 %i, i32 %j) local_u ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 100 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] ; +; MAX-BW-LABEL: @matrix_row_col( +; MAX-BW-NEXT: entry: +; MAX-BW-NEXT: [[IDXPROM:%.*]] = sext i32 [[I:%.*]] to i64 +; MAX-BW-NEXT: [[IDXPROM5:%.*]] = sext i32 [[J:%.*]] to i64 +; MAX-BW-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; MAX-BW: vector.ph: +; MAX-BW-NEXT: br label [[VECTOR_BODY:%.*]] +; MAX-BW: vector.body: +; MAX-BW-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] +; MAX-BW-NEXT: [[VEC_PHI:%.*]] = phi <8 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP144:%.*]], [[VECTOR_BODY]] ] +; MAX-BW-NEXT: [[VEC_PHI1:%.*]] = phi <8 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP145:%.*]], [[VECTOR_BODY]] ] +; MAX-BW-NEXT: [[VEC_PHI2:%.*]] = phi <8 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP146:%.*]], [[VECTOR_BODY]] ] +; MAX-BW-NEXT: [[VEC_PHI3:%.*]] = phi <8 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP147:%.*]], [[VECTOR_BODY]] ] +; MAX-BW-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 +; MAX-BW-NEXT: [[TMP1:%.*]] = add i64 [[INDEX]], 1 +; MAX-BW-NEXT: [[TMP2:%.*]] = add i64 [[INDEX]], 2 +; MAX-BW-NEXT: [[TMP3:%.*]] = add i64 [[INDEX]], 3 +; MAX-BW-NEXT: [[TMP4:%.*]] = add i64 [[INDEX]], 4 +; MAX-BW-NEXT: [[TMP5:%.*]] = add i64 [[INDEX]], 5 +; MAX-BW-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], 6 +; MAX-BW-NEXT: [[TMP7:%.*]] = add i64 [[INDEX]], 7 +; MAX-BW-NEXT: [[TMP8:%.*]] = add i64 [[INDEX]], 8 +; MAX-BW-NEXT: [[TMP9:%.*]] = add i64 [[INDEX]], 9 +; MAX-BW-NEXT: [[TMP10:%.*]] = add i64 [[INDEX]], 10 +; MAX-BW-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 11 +; MAX-BW-NEXT: [[TMP12:%.*]] = add i64 [[INDEX]], 12 +; MAX-BW-NEXT: [[TMP13:%.*]] = add i64 [[INDEX]], 13 +; MAX-BW-NEXT: [[TMP14:%.*]] = add i64 [[INDEX]], 14 +; MAX-BW-NEXT: [[TMP15:%.*]] = add i64 [[INDEX]], 15 +; MAX-BW-NEXT: [[TMP16:%.*]] = add i64 [[INDEX]], 16 +; MAX-BW-NEXT: [[TMP17:%.*]] = add i64 [[INDEX]], 17 +; MAX-BW-NEXT: [[TMP18:%.*]] = add i64 [[INDEX]], 18 +; MAX-BW-NEXT: [[TMP19:%.*]] = add i64 [[INDEX]], 19 +; MAX-BW-NEXT: [[TMP20:%.*]] = add i64 [[INDEX]], 20 +; MAX-BW-NEXT: [[TMP21:%.*]] = add i64 [[INDEX]], 21 +; MAX-BW-NEXT: [[TMP22:%.*]] = add i64 [[INDEX]], 22 +; MAX-BW-NEXT: [[TMP23:%.*]] = add i64 [[INDEX]], 23 +; MAX-BW-NEXT: [[TMP24:%.*]] = add i64 [[INDEX]], 24 +; MAX-BW-NEXT: [[TMP25:%.*]] = add i64 [[INDEX]], 25 +; MAX-BW-NEXT: [[TMP26:%.*]] = add i64 [[INDEX]], 26 +; MAX-BW-NEXT: [[TMP27:%.*]] = add i64 [[INDEX]], 27 +; MAX-BW-NEXT: [[TMP28:%.*]] = add i64 [[INDEX]], 28 +; MAX-BW-NEXT: [[TMP29:%.*]] = add i64 [[INDEX]], 29 +; MAX-BW-NEXT: [[TMP30:%.*]] = add i64 [[INDEX]], 30 +; MAX-BW-NEXT: [[TMP31:%.*]] = add i64 [[INDEX]], 31 +; MAX-BW-NEXT: [[TMP32:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA:%.*]], i64 [[IDXPROM]], i64 [[TMP0]] +; MAX-BW-NEXT: [[TMP33:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[IDXPROM]], i64 [[TMP8]] +; MAX-BW-NEXT: [[TMP34:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[IDXPROM]], i64 [[TMP16]] +; MAX-BW-NEXT: [[TMP35:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[IDXPROM]], i64 [[TMP24]] +; MAX-BW-NEXT: [[TMP36:%.*]] = getelementptr inbounds i32, ptr [[TMP32]], i32 0 +; MAX-BW-NEXT: [[TMP37:%.*]] = getelementptr inbounds i32, ptr [[TMP32]], i32 8 +; MAX-BW-NEXT: [[TMP38:%.*]] = getelementptr inbounds i32, ptr [[TMP32]], i32 16 +; MAX-BW-NEXT: [[TMP39:%.*]] = getelementptr inbounds i32, ptr [[TMP32]], i32 24 +; MAX-BW-NEXT: [[WIDE_LOAD:%.*]] = load <8 x i32>, ptr [[TMP36]], align 4, !tbaa [[TBAA1:![0-9]+]] +; MAX-BW-NEXT: [[WIDE_LOAD4:%.*]] = load <8 x i32>, ptr [[TMP37]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[WIDE_LOAD5:%.*]] = load <8 x i32>, ptr [[TMP38]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[WIDE_LOAD6:%.*]] = load <8 x i32>, ptr [[TMP39]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP40:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP0]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP41:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP1]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP42:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP2]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP43:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP3]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP44:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP4]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP45:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP5]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP46:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP6]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP47:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP7]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP48:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP8]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP49:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP9]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP50:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP10]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP51:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP11]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP52:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP12]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP53:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP13]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP54:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP14]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP55:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP15]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP56:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP16]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP57:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP17]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP58:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP18]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP59:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP19]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP60:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP20]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP61:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP21]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP62:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP22]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP63:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP23]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP64:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP24]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP65:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP25]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP66:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP26]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP67:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP27]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP68:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP28]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP69:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP29]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP70:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP30]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP71:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[TMP31]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP72:%.*]] = load i32, ptr [[TMP40]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP73:%.*]] = load i32, ptr [[TMP41]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP74:%.*]] = load i32, ptr [[TMP42]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP75:%.*]] = load i32, ptr [[TMP43]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP76:%.*]] = load i32, ptr [[TMP44]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP77:%.*]] = load i32, ptr [[TMP45]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP78:%.*]] = load i32, ptr [[TMP46]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP79:%.*]] = load i32, ptr [[TMP47]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP80:%.*]] = insertelement <8 x i32> poison, i32 [[TMP72]], i32 0 +; MAX-BW-NEXT: [[TMP81:%.*]] = insertelement <8 x i32> [[TMP80]], i32 [[TMP73]], i32 1 +; MAX-BW-NEXT: [[TMP82:%.*]] = insertelement <8 x i32> [[TMP81]], i32 [[TMP74]], i32 2 +; MAX-BW-NEXT: [[TMP83:%.*]] = insertelement <8 x i32> [[TMP82]], i32 [[TMP75]], i32 3 +; MAX-BW-NEXT: [[TMP84:%.*]] = insertelement <8 x i32> [[TMP83]], i32 [[TMP76]], i32 4 +; MAX-BW-NEXT: [[TMP85:%.*]] = insertelement <8 x i32> [[TMP84]], i32 [[TMP77]], i32 5 +; MAX-BW-NEXT: [[TMP86:%.*]] = insertelement <8 x i32> [[TMP85]], i32 [[TMP78]], i32 6 +; MAX-BW-NEXT: [[TMP87:%.*]] = insertelement <8 x i32> [[TMP86]], i32 [[TMP79]], i32 7 +; MAX-BW-NEXT: [[TMP88:%.*]] = load i32, ptr [[TMP48]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP89:%.*]] = load i32, ptr [[TMP49]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP90:%.*]] = load i32, ptr [[TMP50]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP91:%.*]] = load i32, ptr [[TMP51]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP92:%.*]] = load i32, ptr [[TMP52]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP93:%.*]] = load i32, ptr [[TMP53]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP94:%.*]] = load i32, ptr [[TMP54]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP95:%.*]] = load i32, ptr [[TMP55]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP96:%.*]] = insertelement <8 x i32> poison, i32 [[TMP88]], i32 0 +; MAX-BW-NEXT: [[TMP97:%.*]] = insertelement <8 x i32> [[TMP96]], i32 [[TMP89]], i32 1 +; MAX-BW-NEXT: [[TMP98:%.*]] = insertelement <8 x i32> [[TMP97]], i32 [[TMP90]], i32 2 +; MAX-BW-NEXT: [[TMP99:%.*]] = insertelement <8 x i32> [[TMP98]], i32 [[TMP91]], i32 3 +; MAX-BW-NEXT: [[TMP100:%.*]] = insertelement <8 x i32> [[TMP99]], i32 [[TMP92]], i32 4 +; MAX-BW-NEXT: [[TMP101:%.*]] = insertelement <8 x i32> [[TMP100]], i32 [[TMP93]], i32 5 +; MAX-BW-NEXT: [[TMP102:%.*]] = insertelement <8 x i32> [[TMP101]], i32 [[TMP94]], i32 6 +; MAX-BW-NEXT: [[TMP103:%.*]] = insertelement <8 x i32> [[TMP102]], i32 [[TMP95]], i32 7 +; MAX-BW-NEXT: [[TMP104:%.*]] = load i32, ptr [[TMP56]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP105:%.*]] = load i32, ptr [[TMP57]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP106:%.*]] = load i32, ptr [[TMP58]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP107:%.*]] = load i32, ptr [[TMP59]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP108:%.*]] = load i32, ptr [[TMP60]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP109:%.*]] = load i32, ptr [[TMP61]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP110:%.*]] = load i32, ptr [[TMP62]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP111:%.*]] = load i32, ptr [[TMP63]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP112:%.*]] = insertelement <8 x i32> poison, i32 [[TMP104]], i32 0 +; MAX-BW-NEXT: [[TMP113:%.*]] = insertelement <8 x i32> [[TMP112]], i32 [[TMP105]], i32 1 +; MAX-BW-NEXT: [[TMP114:%.*]] = insertelement <8 x i32> [[TMP113]], i32 [[TMP106]], i32 2 +; MAX-BW-NEXT: [[TMP115:%.*]] = insertelement <8 x i32> [[TMP114]], i32 [[TMP107]], i32 3 +; MAX-BW-NEXT: [[TMP116:%.*]] = insertelement <8 x i32> [[TMP115]], i32 [[TMP108]], i32 4 +; MAX-BW-NEXT: [[TMP117:%.*]] = insertelement <8 x i32> [[TMP116]], i32 [[TMP109]], i32 5 +; MAX-BW-NEXT: [[TMP118:%.*]] = insertelement <8 x i32> [[TMP117]], i32 [[TMP110]], i32 6 +; MAX-BW-NEXT: [[TMP119:%.*]] = insertelement <8 x i32> [[TMP118]], i32 [[TMP111]], i32 7 +; MAX-BW-NEXT: [[TMP120:%.*]] = load i32, ptr [[TMP64]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP121:%.*]] = load i32, ptr [[TMP65]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP122:%.*]] = load i32, ptr [[TMP66]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP123:%.*]] = load i32, ptr [[TMP67]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP124:%.*]] = load i32, ptr [[TMP68]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP125:%.*]] = load i32, ptr [[TMP69]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP126:%.*]] = load i32, ptr [[TMP70]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP127:%.*]] = load i32, ptr [[TMP71]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[TMP128:%.*]] = insertelement <8 x i32> poison, i32 [[TMP120]], i32 0 +; MAX-BW-NEXT: [[TMP129:%.*]] = insertelement <8 x i32> [[TMP128]], i32 [[TMP121]], i32 1 +; MAX-BW-NEXT: [[TMP130:%.*]] = insertelement <8 x i32> [[TMP129]], i32 [[TMP122]], i32 2 +; MAX-BW-NEXT: [[TMP131:%.*]] = insertelement <8 x i32> [[TMP130]], i32 [[TMP123]], i32 3 +; MAX-BW-NEXT: [[TMP132:%.*]] = insertelement <8 x i32> [[TMP131]], i32 [[TMP124]], i32 4 +; MAX-BW-NEXT: [[TMP133:%.*]] = insertelement <8 x i32> [[TMP132]], i32 [[TMP125]], i32 5 +; MAX-BW-NEXT: [[TMP134:%.*]] = insertelement <8 x i32> [[TMP133]], i32 [[TMP126]], i32 6 +; MAX-BW-NEXT: [[TMP135:%.*]] = insertelement <8 x i32> [[TMP134]], i32 [[TMP127]], i32 7 +; MAX-BW-NEXT: [[TMP136:%.*]] = mul nsw <8 x i32> [[TMP87]], [[WIDE_LOAD]] +; MAX-BW-NEXT: [[TMP137:%.*]] = mul nsw <8 x i32> [[TMP103]], [[WIDE_LOAD4]] +; MAX-BW-NEXT: [[TMP138:%.*]] = mul nsw <8 x i32> [[TMP119]], [[WIDE_LOAD5]] +; MAX-BW-NEXT: [[TMP139:%.*]] = mul nsw <8 x i32> [[TMP135]], [[WIDE_LOAD6]] +; MAX-BW-NEXT: [[TMP140:%.*]] = add <8 x i32> [[VEC_PHI]], +; MAX-BW-NEXT: [[TMP141:%.*]] = add <8 x i32> [[VEC_PHI1]], +; MAX-BW-NEXT: [[TMP142:%.*]] = add <8 x i32> [[VEC_PHI2]], +; MAX-BW-NEXT: [[TMP143:%.*]] = add <8 x i32> [[VEC_PHI3]], +; MAX-BW-NEXT: [[TMP144]] = add <8 x i32> [[TMP140]], [[TMP136]] +; MAX-BW-NEXT: [[TMP145]] = add <8 x i32> [[TMP141]], [[TMP137]] +; MAX-BW-NEXT: [[TMP146]] = add <8 x i32> [[TMP142]], [[TMP138]] +; MAX-BW-NEXT: [[TMP147]] = add <8 x i32> [[TMP143]], [[TMP139]] +; MAX-BW-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32 +; MAX-BW-NEXT: [[TMP148:%.*]] = icmp eq i64 [[INDEX_NEXT]], 96 +; MAX-BW-NEXT: br i1 [[TMP148]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]] +; MAX-BW: middle.block: +; MAX-BW-NEXT: [[BIN_RDX:%.*]] = add <8 x i32> [[TMP145]], [[TMP144]] +; MAX-BW-NEXT: [[BIN_RDX7:%.*]] = add <8 x i32> [[TMP146]], [[BIN_RDX]] +; MAX-BW-NEXT: [[BIN_RDX8:%.*]] = add <8 x i32> [[TMP147]], [[BIN_RDX7]] +; MAX-BW-NEXT: [[TMP149:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[BIN_RDX8]]) +; MAX-BW-NEXT: br i1 false, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] +; MAX-BW: scalar.ph: +; MAX-BW-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 96, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] +; MAX-BW-NEXT: [[BC_MERGE_RDX:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP149]], [[MIDDLE_BLOCK]] ] +; MAX-BW-NEXT: br label [[FOR_BODY:%.*]] +; MAX-BW: for.cond.cleanup: +; MAX-BW-NEXT: [[ADD7_LCSSA:%.*]] = phi i32 [ [[ADD7:%.*]], [[FOR_BODY]] ], [ [[TMP149]], [[MIDDLE_BLOCK]] ] +; MAX-BW-NEXT: ret i32 [[ADD7_LCSSA]] +; MAX-BW: for.body: +; MAX-BW-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] +; MAX-BW-NEXT: [[SUM_015:%.*]] = phi i32 [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[ADD7]], [[FOR_BODY]] ] +; MAX-BW-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[IDXPROM]], i64 [[INDVARS_IV]] +; MAX-BW-NEXT: [[TMP150:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x i32], ptr [[DATA]], i64 [[INDVARS_IV]], i64 [[IDXPROM5]] +; MAX-BW-NEXT: [[TMP151:%.*]] = load i32, ptr [[ARRAYIDX6]], align 4, !tbaa [[TBAA1]] +; MAX-BW-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP151]], [[TMP150]] +; MAX-BW-NEXT: [[ADD:%.*]] = add i32 [[SUM_015]], 4 +; MAX-BW-NEXT: [[ADD7]] = add i32 [[ADD]], [[MUL]] +; MAX-BW-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; MAX-BW-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 100 +; MAX-BW-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] +; entry: %idxprom = sext i32 %i to i64 %idxprom5 = sext i32 %j to i64 @@ -229,6 +425,319 @@ entry: br i1 %exitcond, label %for.cond.cleanup, label %for.body } +define void @test(ptr %A, ptr noalias %B) #0 { +; CHECK-LABEL: @test( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; CHECK: vector.ph: +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 2 +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 2 +; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 4 +; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 6 +; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[OFFSET_IDX]], 8 +; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[OFFSET_IDX]], 10 +; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[OFFSET_IDX]], 12 +; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[OFFSET_IDX]], 14 +; CHECK-NEXT: [[TMP8:%.*]] = add nuw nsw i64 [[TMP0]], 0 +; CHECK-NEXT: [[TMP9:%.*]] = add nuw nsw i64 [[TMP1]], 0 +; CHECK-NEXT: [[TMP10:%.*]] = add nuw nsw i64 [[TMP2]], 0 +; CHECK-NEXT: [[TMP11:%.*]] = add nuw nsw i64 [[TMP3]], 0 +; CHECK-NEXT: [[TMP12:%.*]] = add nuw nsw i64 [[TMP4]], 0 +; CHECK-NEXT: [[TMP13:%.*]] = add nuw nsw i64 [[TMP5]], 0 +; CHECK-NEXT: [[TMP14:%.*]] = add nuw nsw i64 [[TMP6]], 0 +; CHECK-NEXT: [[TMP15:%.*]] = add nuw nsw i64 [[TMP7]], 0 +; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds [1024 x i32], ptr [[A:%.*]], i64 0, i64 [[TMP8]] +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0 +; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <16 x i32>, ptr [[TMP17]], align 4 +; CHECK-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <16 x i32> [[WIDE_VEC]], <16 x i32> poison, <8 x i32> +; CHECK-NEXT: [[STRIDED_VEC1:%.*]] = shufflevector <16 x i32> [[WIDE_VEC]], <16 x i32> poison, <8 x i32> +; CHECK-NEXT: [[TMP18:%.*]] = add <8 x i32> [[STRIDED_VEC]], [[STRIDED_VEC1]] +; CHECK-NEXT: [[TMP19:%.*]] = trunc <8 x i32> [[TMP18]] to <8 x i8> +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B:%.*]], i64 0, i64 [[TMP8]] +; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP9]] +; CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP10]] +; CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP11]] +; CHECK-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP12]] +; CHECK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP13]] +; CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP14]] +; CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP15]] +; CHECK-NEXT: [[TMP28:%.*]] = extractelement <8 x i8> [[TMP19]], i32 0 +; CHECK-NEXT: store i8 [[TMP28]], ptr [[TMP20]], align 1 +; CHECK-NEXT: [[TMP29:%.*]] = extractelement <8 x i8> [[TMP19]], i32 1 +; CHECK-NEXT: store i8 [[TMP29]], ptr [[TMP21]], align 1 +; CHECK-NEXT: [[TMP30:%.*]] = extractelement <8 x i8> [[TMP19]], i32 2 +; CHECK-NEXT: store i8 [[TMP30]], ptr [[TMP22]], align 1 +; CHECK-NEXT: [[TMP31:%.*]] = extractelement <8 x i8> [[TMP19]], i32 3 +; CHECK-NEXT: store i8 [[TMP31]], ptr [[TMP23]], align 1 +; CHECK-NEXT: [[TMP32:%.*]] = extractelement <8 x i8> [[TMP19]], i32 4 +; CHECK-NEXT: store i8 [[TMP32]], ptr [[TMP24]], align 1 +; CHECK-NEXT: [[TMP33:%.*]] = extractelement <8 x i8> [[TMP19]], i32 5 +; CHECK-NEXT: store i8 [[TMP33]], ptr [[TMP25]], align 1 +; CHECK-NEXT: [[TMP34:%.*]] = extractelement <8 x i8> [[TMP19]], i32 6 +; CHECK-NEXT: store i8 [[TMP34]], ptr [[TMP26]], align 1 +; CHECK-NEXT: [[TMP35:%.*]] = extractelement <8 x i8> [[TMP19]], i32 7 +; CHECK-NEXT: store i8 [[TMP35]], ptr [[TMP27]], align 1 +; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8 +; CHECK-NEXT: [[TMP36:%.*]] = icmp eq i64 [[INDEX_NEXT]], 512 +; CHECK-NEXT: br i1 [[TMP36]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]] +; CHECK: middle.block: +; CHECK-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[IV_0:%.*]] = add nuw nsw i64 [[IV]], 0 +; CHECK-NEXT: [[IV_1:%.*]] = add nuw nsw i64 [[IV]], 1 +; CHECK-NEXT: [[IN0:%.*]] = getelementptr inbounds [1024 x i32], ptr [[A]], i64 0, i64 [[IV_0]] +; CHECK-NEXT: [[IN1:%.*]] = getelementptr inbounds [1024 x i32], ptr [[A]], i64 0, i64 [[IV_1]] +; CHECK-NEXT: [[V0:%.*]] = load i32, ptr [[IN0]], align 4 +; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[IN1]], align 4 +; CHECK-NEXT: [[REDUCE_ADD_0:%.*]] = add i32 [[V0]], [[V1]] +; CHECK-NEXT: [[REDUCE_ADD_0_NARROW:%.*]] = trunc i32 [[REDUCE_ADD_0]] to i8 +; CHECK-NEXT: [[OUT:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[IV_0]] +; CHECK-NEXT: store i8 [[REDUCE_ADD_0_NARROW]], ptr [[OUT]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV_0]], 2 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], 1024 +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP]], !llvm.loop [[LOOP10:![0-9]+]] +; CHECK: for.cond.cleanup: +; CHECK-NEXT: ret void +; +; MAX-BW-LABEL: @test( +; MAX-BW-NEXT: entry: +; MAX-BW-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; MAX-BW: vector.ph: +; MAX-BW-NEXT: br label [[VECTOR_BODY:%.*]] +; MAX-BW: vector.body: +; MAX-BW-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] +; MAX-BW-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 2 +; MAX-BW-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 +; MAX-BW-NEXT: [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 2 +; MAX-BW-NEXT: [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 4 +; MAX-BW-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 6 +; MAX-BW-NEXT: [[TMP4:%.*]] = add i64 [[OFFSET_IDX]], 8 +; MAX-BW-NEXT: [[TMP5:%.*]] = add i64 [[OFFSET_IDX]], 10 +; MAX-BW-NEXT: [[TMP6:%.*]] = add i64 [[OFFSET_IDX]], 12 +; MAX-BW-NEXT: [[TMP7:%.*]] = add i64 [[OFFSET_IDX]], 14 +; MAX-BW-NEXT: [[TMP8:%.*]] = add i64 [[OFFSET_IDX]], 16 +; MAX-BW-NEXT: [[TMP9:%.*]] = add i64 [[OFFSET_IDX]], 18 +; MAX-BW-NEXT: [[TMP10:%.*]] = add i64 [[OFFSET_IDX]], 20 +; MAX-BW-NEXT: [[TMP11:%.*]] = add i64 [[OFFSET_IDX]], 22 +; MAX-BW-NEXT: [[TMP12:%.*]] = add i64 [[OFFSET_IDX]], 24 +; MAX-BW-NEXT: [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 26 +; MAX-BW-NEXT: [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 28 +; MAX-BW-NEXT: [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 30 +; MAX-BW-NEXT: [[TMP16:%.*]] = add i64 [[OFFSET_IDX]], 32 +; MAX-BW-NEXT: [[TMP17:%.*]] = add i64 [[OFFSET_IDX]], 34 +; MAX-BW-NEXT: [[TMP18:%.*]] = add i64 [[OFFSET_IDX]], 36 +; MAX-BW-NEXT: [[TMP19:%.*]] = add i64 [[OFFSET_IDX]], 38 +; MAX-BW-NEXT: [[TMP20:%.*]] = add i64 [[OFFSET_IDX]], 40 +; MAX-BW-NEXT: [[TMP21:%.*]] = add i64 [[OFFSET_IDX]], 42 +; MAX-BW-NEXT: [[TMP22:%.*]] = add i64 [[OFFSET_IDX]], 44 +; MAX-BW-NEXT: [[TMP23:%.*]] = add i64 [[OFFSET_IDX]], 46 +; MAX-BW-NEXT: [[TMP24:%.*]] = add i64 [[OFFSET_IDX]], 48 +; MAX-BW-NEXT: [[TMP25:%.*]] = add i64 [[OFFSET_IDX]], 50 +; MAX-BW-NEXT: [[TMP26:%.*]] = add i64 [[OFFSET_IDX]], 52 +; MAX-BW-NEXT: [[TMP27:%.*]] = add i64 [[OFFSET_IDX]], 54 +; MAX-BW-NEXT: [[TMP28:%.*]] = add i64 [[OFFSET_IDX]], 56 +; MAX-BW-NEXT: [[TMP29:%.*]] = add i64 [[OFFSET_IDX]], 58 +; MAX-BW-NEXT: [[TMP30:%.*]] = add i64 [[OFFSET_IDX]], 60 +; MAX-BW-NEXT: [[TMP31:%.*]] = add i64 [[OFFSET_IDX]], 62 +; MAX-BW-NEXT: [[TMP32:%.*]] = add nuw nsw i64 [[TMP0]], 0 +; MAX-BW-NEXT: [[TMP33:%.*]] = add nuw nsw i64 [[TMP1]], 0 +; MAX-BW-NEXT: [[TMP34:%.*]] = add nuw nsw i64 [[TMP2]], 0 +; MAX-BW-NEXT: [[TMP35:%.*]] = add nuw nsw i64 [[TMP3]], 0 +; MAX-BW-NEXT: [[TMP36:%.*]] = add nuw nsw i64 [[TMP4]], 0 +; MAX-BW-NEXT: [[TMP37:%.*]] = add nuw nsw i64 [[TMP5]], 0 +; MAX-BW-NEXT: [[TMP38:%.*]] = add nuw nsw i64 [[TMP6]], 0 +; MAX-BW-NEXT: [[TMP39:%.*]] = add nuw nsw i64 [[TMP7]], 0 +; MAX-BW-NEXT: [[TMP40:%.*]] = add nuw nsw i64 [[TMP8]], 0 +; MAX-BW-NEXT: [[TMP41:%.*]] = add nuw nsw i64 [[TMP9]], 0 +; MAX-BW-NEXT: [[TMP42:%.*]] = add nuw nsw i64 [[TMP10]], 0 +; MAX-BW-NEXT: [[TMP43:%.*]] = add nuw nsw i64 [[TMP11]], 0 +; MAX-BW-NEXT: [[TMP44:%.*]] = add nuw nsw i64 [[TMP12]], 0 +; MAX-BW-NEXT: [[TMP45:%.*]] = add nuw nsw i64 [[TMP13]], 0 +; MAX-BW-NEXT: [[TMP46:%.*]] = add nuw nsw i64 [[TMP14]], 0 +; MAX-BW-NEXT: [[TMP47:%.*]] = add nuw nsw i64 [[TMP15]], 0 +; MAX-BW-NEXT: [[TMP48:%.*]] = add nuw nsw i64 [[TMP16]], 0 +; MAX-BW-NEXT: [[TMP49:%.*]] = add nuw nsw i64 [[TMP17]], 0 +; MAX-BW-NEXT: [[TMP50:%.*]] = add nuw nsw i64 [[TMP18]], 0 +; MAX-BW-NEXT: [[TMP51:%.*]] = add nuw nsw i64 [[TMP19]], 0 +; MAX-BW-NEXT: [[TMP52:%.*]] = add nuw nsw i64 [[TMP20]], 0 +; MAX-BW-NEXT: [[TMP53:%.*]] = add nuw nsw i64 [[TMP21]], 0 +; MAX-BW-NEXT: [[TMP54:%.*]] = add nuw nsw i64 [[TMP22]], 0 +; MAX-BW-NEXT: [[TMP55:%.*]] = add nuw nsw i64 [[TMP23]], 0 +; MAX-BW-NEXT: [[TMP56:%.*]] = add nuw nsw i64 [[TMP24]], 0 +; MAX-BW-NEXT: [[TMP57:%.*]] = add nuw nsw i64 [[TMP25]], 0 +; MAX-BW-NEXT: [[TMP58:%.*]] = add nuw nsw i64 [[TMP26]], 0 +; MAX-BW-NEXT: [[TMP59:%.*]] = add nuw nsw i64 [[TMP27]], 0 +; MAX-BW-NEXT: [[TMP60:%.*]] = add nuw nsw i64 [[TMP28]], 0 +; MAX-BW-NEXT: [[TMP61:%.*]] = add nuw nsw i64 [[TMP29]], 0 +; MAX-BW-NEXT: [[TMP62:%.*]] = add nuw nsw i64 [[TMP30]], 0 +; MAX-BW-NEXT: [[TMP63:%.*]] = add nuw nsw i64 [[TMP31]], 0 +; MAX-BW-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1024 x i32], ptr [[A:%.*]], i64 0, i64 [[TMP32]] +; MAX-BW-NEXT: [[TMP65:%.*]] = getelementptr inbounds i32, ptr [[TMP64]], i32 0 +; MAX-BW-NEXT: [[WIDE_VEC:%.*]] = load <64 x i32>, ptr [[TMP65]], align 4 +; MAX-BW-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <64 x i32> [[WIDE_VEC]], <64 x i32> poison, <32 x i32> +; MAX-BW-NEXT: [[STRIDED_VEC1:%.*]] = shufflevector <64 x i32> [[WIDE_VEC]], <64 x i32> poison, <32 x i32> +; MAX-BW-NEXT: [[TMP66:%.*]] = add <32 x i32> [[STRIDED_VEC]], [[STRIDED_VEC1]] +; MAX-BW-NEXT: [[TMP67:%.*]] = trunc <32 x i32> [[TMP66]] to <32 x i8> +; MAX-BW-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B:%.*]], i64 0, i64 [[TMP32]] +; MAX-BW-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP33]] +; MAX-BW-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP34]] +; MAX-BW-NEXT: [[TMP71:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP35]] +; MAX-BW-NEXT: [[TMP72:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP36]] +; MAX-BW-NEXT: [[TMP73:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP37]] +; MAX-BW-NEXT: [[TMP74:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP38]] +; MAX-BW-NEXT: [[TMP75:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP39]] +; MAX-BW-NEXT: [[TMP76:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP40]] +; MAX-BW-NEXT: [[TMP77:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP41]] +; MAX-BW-NEXT: [[TMP78:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP42]] +; MAX-BW-NEXT: [[TMP79:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP43]] +; MAX-BW-NEXT: [[TMP80:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP44]] +; MAX-BW-NEXT: [[TMP81:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP45]] +; MAX-BW-NEXT: [[TMP82:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP46]] +; MAX-BW-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP47]] +; MAX-BW-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP48]] +; MAX-BW-NEXT: [[TMP85:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP49]] +; MAX-BW-NEXT: [[TMP86:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP50]] +; MAX-BW-NEXT: [[TMP87:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP51]] +; MAX-BW-NEXT: [[TMP88:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP52]] +; MAX-BW-NEXT: [[TMP89:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP53]] +; MAX-BW-NEXT: [[TMP90:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP54]] +; MAX-BW-NEXT: [[TMP91:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP55]] +; MAX-BW-NEXT: [[TMP92:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP56]] +; MAX-BW-NEXT: [[TMP93:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP57]] +; MAX-BW-NEXT: [[TMP94:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP58]] +; MAX-BW-NEXT: [[TMP95:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP59]] +; MAX-BW-NEXT: [[TMP96:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP60]] +; MAX-BW-NEXT: [[TMP97:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP61]] +; MAX-BW-NEXT: [[TMP98:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP62]] +; MAX-BW-NEXT: [[TMP99:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP63]] +; MAX-BW-NEXT: [[TMP100:%.*]] = extractelement <32 x i8> [[TMP67]], i32 0 +; MAX-BW-NEXT: store i8 [[TMP100]], ptr [[TMP68]], align 1 +; MAX-BW-NEXT: [[TMP101:%.*]] = extractelement <32 x i8> [[TMP67]], i32 1 +; MAX-BW-NEXT: store i8 [[TMP101]], ptr [[TMP69]], align 1 +; MAX-BW-NEXT: [[TMP102:%.*]] = extractelement <32 x i8> [[TMP67]], i32 2 +; MAX-BW-NEXT: store i8 [[TMP102]], ptr [[TMP70]], align 1 +; MAX-BW-NEXT: [[TMP103:%.*]] = extractelement <32 x i8> [[TMP67]], i32 3 +; MAX-BW-NEXT: store i8 [[TMP103]], ptr [[TMP71]], align 1 +; MAX-BW-NEXT: [[TMP104:%.*]] = extractelement <32 x i8> [[TMP67]], i32 4 +; MAX-BW-NEXT: store i8 [[TMP104]], ptr [[TMP72]], align 1 +; MAX-BW-NEXT: [[TMP105:%.*]] = extractelement <32 x i8> [[TMP67]], i32 5 +; MAX-BW-NEXT: store i8 [[TMP105]], ptr [[TMP73]], align 1 +; MAX-BW-NEXT: [[TMP106:%.*]] = extractelement <32 x i8> [[TMP67]], i32 6 +; MAX-BW-NEXT: store i8 [[TMP106]], ptr [[TMP74]], align 1 +; MAX-BW-NEXT: [[TMP107:%.*]] = extractelement <32 x i8> [[TMP67]], i32 7 +; MAX-BW-NEXT: store i8 [[TMP107]], ptr [[TMP75]], align 1 +; MAX-BW-NEXT: [[TMP108:%.*]] = extractelement <32 x i8> [[TMP67]], i32 8 +; MAX-BW-NEXT: store i8 [[TMP108]], ptr [[TMP76]], align 1 +; MAX-BW-NEXT: [[TMP109:%.*]] = extractelement <32 x i8> [[TMP67]], i32 9 +; MAX-BW-NEXT: store i8 [[TMP109]], ptr [[TMP77]], align 1 +; MAX-BW-NEXT: [[TMP110:%.*]] = extractelement <32 x i8> [[TMP67]], i32 10 +; MAX-BW-NEXT: store i8 [[TMP110]], ptr [[TMP78]], align 1 +; MAX-BW-NEXT: [[TMP111:%.*]] = extractelement <32 x i8> [[TMP67]], i32 11 +; MAX-BW-NEXT: store i8 [[TMP111]], ptr [[TMP79]], align 1 +; MAX-BW-NEXT: [[TMP112:%.*]] = extractelement <32 x i8> [[TMP67]], i32 12 +; MAX-BW-NEXT: store i8 [[TMP112]], ptr [[TMP80]], align 1 +; MAX-BW-NEXT: [[TMP113:%.*]] = extractelement <32 x i8> [[TMP67]], i32 13 +; MAX-BW-NEXT: store i8 [[TMP113]], ptr [[TMP81]], align 1 +; MAX-BW-NEXT: [[TMP114:%.*]] = extractelement <32 x i8> [[TMP67]], i32 14 +; MAX-BW-NEXT: store i8 [[TMP114]], ptr [[TMP82]], align 1 +; MAX-BW-NEXT: [[TMP115:%.*]] = extractelement <32 x i8> [[TMP67]], i32 15 +; MAX-BW-NEXT: store i8 [[TMP115]], ptr [[TMP83]], align 1 +; MAX-BW-NEXT: [[TMP116:%.*]] = extractelement <32 x i8> [[TMP67]], i32 16 +; MAX-BW-NEXT: store i8 [[TMP116]], ptr [[TMP84]], align 1 +; MAX-BW-NEXT: [[TMP117:%.*]] = extractelement <32 x i8> [[TMP67]], i32 17 +; MAX-BW-NEXT: store i8 [[TMP117]], ptr [[TMP85]], align 1 +; MAX-BW-NEXT: [[TMP118:%.*]] = extractelement <32 x i8> [[TMP67]], i32 18 +; MAX-BW-NEXT: store i8 [[TMP118]], ptr [[TMP86]], align 1 +; MAX-BW-NEXT: [[TMP119:%.*]] = extractelement <32 x i8> [[TMP67]], i32 19 +; MAX-BW-NEXT: store i8 [[TMP119]], ptr [[TMP87]], align 1 +; MAX-BW-NEXT: [[TMP120:%.*]] = extractelement <32 x i8> [[TMP67]], i32 20 +; MAX-BW-NEXT: store i8 [[TMP120]], ptr [[TMP88]], align 1 +; MAX-BW-NEXT: [[TMP121:%.*]] = extractelement <32 x i8> [[TMP67]], i32 21 +; MAX-BW-NEXT: store i8 [[TMP121]], ptr [[TMP89]], align 1 +; MAX-BW-NEXT: [[TMP122:%.*]] = extractelement <32 x i8> [[TMP67]], i32 22 +; MAX-BW-NEXT: store i8 [[TMP122]], ptr [[TMP90]], align 1 +; MAX-BW-NEXT: [[TMP123:%.*]] = extractelement <32 x i8> [[TMP67]], i32 23 +; MAX-BW-NEXT: store i8 [[TMP123]], ptr [[TMP91]], align 1 +; MAX-BW-NEXT: [[TMP124:%.*]] = extractelement <32 x i8> [[TMP67]], i32 24 +; MAX-BW-NEXT: store i8 [[TMP124]], ptr [[TMP92]], align 1 +; MAX-BW-NEXT: [[TMP125:%.*]] = extractelement <32 x i8> [[TMP67]], i32 25 +; MAX-BW-NEXT: store i8 [[TMP125]], ptr [[TMP93]], align 1 +; MAX-BW-NEXT: [[TMP126:%.*]] = extractelement <32 x i8> [[TMP67]], i32 26 +; MAX-BW-NEXT: store i8 [[TMP126]], ptr [[TMP94]], align 1 +; MAX-BW-NEXT: [[TMP127:%.*]] = extractelement <32 x i8> [[TMP67]], i32 27 +; MAX-BW-NEXT: store i8 [[TMP127]], ptr [[TMP95]], align 1 +; MAX-BW-NEXT: [[TMP128:%.*]] = extractelement <32 x i8> [[TMP67]], i32 28 +; MAX-BW-NEXT: store i8 [[TMP128]], ptr [[TMP96]], align 1 +; MAX-BW-NEXT: [[TMP129:%.*]] = extractelement <32 x i8> [[TMP67]], i32 29 +; MAX-BW-NEXT: store i8 [[TMP129]], ptr [[TMP97]], align 1 +; MAX-BW-NEXT: [[TMP130:%.*]] = extractelement <32 x i8> [[TMP67]], i32 30 +; MAX-BW-NEXT: store i8 [[TMP130]], ptr [[TMP98]], align 1 +; MAX-BW-NEXT: [[TMP131:%.*]] = extractelement <32 x i8> [[TMP67]], i32 31 +; MAX-BW-NEXT: store i8 [[TMP131]], ptr [[TMP99]], align 1 +; MAX-BW-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32 +; MAX-BW-NEXT: [[TMP132:%.*]] = icmp eq i64 [[INDEX_NEXT]], 512 +; MAX-BW-NEXT: br i1 [[TMP132]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]] +; MAX-BW: middle.block: +; MAX-BW-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] +; MAX-BW: scalar.ph: +; MAX-BW-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] +; MAX-BW-NEXT: br label [[FOR_BODY:%.*]] +; MAX-BW: for.body: +; MAX-BW-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ] +; MAX-BW-NEXT: [[IV_0:%.*]] = add nuw nsw i64 [[IV]], 0 +; MAX-BW-NEXT: [[IV_1:%.*]] = add nuw nsw i64 [[IV]], 1 +; MAX-BW-NEXT: [[IN0:%.*]] = getelementptr inbounds [1024 x i32], ptr [[A]], i64 0, i64 [[IV_0]] +; MAX-BW-NEXT: [[IN1:%.*]] = getelementptr inbounds [1024 x i32], ptr [[A]], i64 0, i64 [[IV_1]] +; MAX-BW-NEXT: [[V0:%.*]] = load i32, ptr [[IN0]], align 4 +; MAX-BW-NEXT: [[V1:%.*]] = load i32, ptr [[IN1]], align 4 +; MAX-BW-NEXT: [[REDUCE_ADD_0:%.*]] = add i32 [[V0]], [[V1]] +; MAX-BW-NEXT: [[REDUCE_ADD_0_NARROW:%.*]] = trunc i32 [[REDUCE_ADD_0]] to i8 +; MAX-BW-NEXT: [[OUT:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[IV_0]] +; MAX-BW-NEXT: store i8 [[REDUCE_ADD_0_NARROW]], ptr [[OUT]], align 1 +; MAX-BW-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV_0]], 2 +; MAX-BW-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], 1024 +; MAX-BW-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP]], !llvm.loop [[LOOP10:![0-9]+]] +; MAX-BW: for.cond.cleanup: +; MAX-BW-NEXT: ret void +; +entry: + br label %for.body + +for.body: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ] + + %iv.0 = add nuw nsw i64 %iv, 0 + %iv.1 = add nuw nsw i64 %iv, 1 + + %in0 = getelementptr inbounds [1024 x i32], ptr %A, i64 0, i64 %iv.0 + %in1 = getelementptr inbounds [1024 x i32], ptr %A, i64 0, i64 %iv.1 + + %v0 = load i32, ptr %in0 + %v1 = load i32, ptr %in1 + + %reduce.add.0 = add i32 %v0, %v1 + + %reduce.add.0.narrow = trunc i32 %reduce.add.0 to i8 + + %out = getelementptr inbounds [1024 x i8], ptr %B, i64 0, i64 %iv.0 + store i8 %reduce.add.0.narrow, ptr %out + + %iv.next = add nuw nsw i64 %iv.0, 2 + %cmp = icmp ult i64 %iv.next, 1024 + br i1 %cmp, label %for.body, label %for.cond.cleanup + +for.cond.cleanup: + ret void +} + attributes #0 = { "target-cpu"="core-avx2" "target-features"="+avx,+avx2,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3" } !llvm.ident = !{!0} -- GitLab From b263033c2be531939dca3a0ed3e5280f9952390d Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Sat, 1 Jun 2024 14:19:38 +0200 Subject: [PATCH 007/678] AMDGPU: Remove arbitrary SCC liveness scan threshold (#94097) --- llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 9 +- ...e92561-restore-undef-scc-verifier-error.ll | 160 ++++++++++++++++++ 2 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/issue92561-restore-undef-scc-verifier-error.ll diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp index 779f4c853326..d8e21da8019a 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -6437,8 +6437,13 @@ loadMBUFScalarOperandsFromVGPR(const SIInstrInfo &TII, MachineInstr &MI, // Save SCC. Waterfall Loop may overwrite SCC. Register SaveSCCReg; - bool SCCNotDead = (MBB.computeRegisterLiveness(TRI, AMDGPU::SCC, MI, 30) != - MachineBasicBlock::LQR_Dead); + + // FIXME: We should maintain SCC liveness while doing the FixSGPRCopies walk + // rather than unlimited scan everywhere + bool SCCNotDead = + MBB.computeRegisterLiveness(TRI, AMDGPU::SCC, MI, + std::numeric_limits::max()) != + MachineBasicBlock::LQR_Dead; if (SCCNotDead) { SaveSCCReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); BuildMI(MBB, Begin, DL, TII.get(AMDGPU::S_CSELECT_B32), SaveSCCReg) diff --git a/llvm/test/CodeGen/AMDGPU/issue92561-restore-undef-scc-verifier-error.ll b/llvm/test/CodeGen/AMDGPU/issue92561-restore-undef-scc-verifier-error.ll new file mode 100644 index 000000000000..0adce2b84aa0 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/issue92561-restore-undef-scc-verifier-error.ll @@ -0,0 +1,160 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs < %s | FileCheck -check-prefix=SDAG %s +; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs < %s | FileCheck -check-prefix=GISEL %s + +; Check for verifier error due to trying to save and restore SCC +; around a waterfall looop when it was never defined. We have to get +; an accurate liveness at the use point and cannot rely on an +; imprecise maybe-live query. + +define void @issue92561(ptr addrspace(1) %arg) { +; SDAG-LABEL: issue92561: +; SDAG: ; %bb.0: ; %bb +; SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; SDAG-NEXT: s_clause 0x1 +; SDAG-NEXT: global_load_b128 v[4:7], v[0:1], off offset:16 +; SDAG-NEXT: global_load_b128 v[0:3], v[0:1], off +; SDAG-NEXT: v_mov_b32_e32 v8, 0 +; SDAG-NEXT: s_mov_b32 s12, 0 +; SDAG-NEXT: s_mov_b32 s3, exec_lo +; SDAG-NEXT: s_mov_b32 s13, s12 +; SDAG-NEXT: s_mov_b32 s14, s12 +; SDAG-NEXT: s_mov_b32 s15, s12 +; SDAG-NEXT: s_waitcnt vmcnt(0) +; SDAG-NEXT: .LBB0_1: ; =>This Inner Loop Header: Depth=1 +; SDAG-NEXT: v_readfirstlane_b32 s4, v0 +; SDAG-NEXT: v_readfirstlane_b32 s5, v1 +; SDAG-NEXT: v_readfirstlane_b32 s6, v2 +; SDAG-NEXT: v_readfirstlane_b32 s7, v3 +; SDAG-NEXT: v_readfirstlane_b32 s8, v4 +; SDAG-NEXT: v_readfirstlane_b32 s9, v5 +; SDAG-NEXT: v_readfirstlane_b32 s10, v6 +; SDAG-NEXT: v_readfirstlane_b32 s11, v7 +; SDAG-NEXT: v_cmp_eq_u64_e32 vcc_lo, s[4:5], v[0:1] +; SDAG-NEXT: v_cmp_eq_u64_e64 s0, s[6:7], v[2:3] +; SDAG-NEXT: v_cmp_eq_u64_e64 s1, s[8:9], v[4:5] +; SDAG-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_3) +; SDAG-NEXT: v_cmp_eq_u64_e64 s2, s[10:11], v[6:7] +; SDAG-NEXT: s_and_b32 s0, vcc_lo, s0 +; SDAG-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1) +; SDAG-NEXT: s_and_b32 s0, s0, s1 +; SDAG-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1) +; SDAG-NEXT: s_and_b32 s0, s0, s2 +; SDAG-NEXT: s_delay_alu instid0(SALU_CYCLE_1) +; SDAG-NEXT: s_and_saveexec_b32 s0, s0 +; SDAG-NEXT: image_sample_c_lz v9, [v8, v8, v8, v8], s[4:11], s[12:15] dmask:0x1 dim:SQ_RSRC_IMG_2D_ARRAY +; SDAG-NEXT: ; implicit-def: $vgpr0_vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7 +; SDAG-NEXT: ; implicit-def: $vgpr8 +; SDAG-NEXT: s_xor_b32 exec_lo, exec_lo, s0 +; SDAG-NEXT: s_cbranch_execnz .LBB0_1 +; SDAG-NEXT: ; %bb.2: +; SDAG-NEXT: s_mov_b32 exec_lo, s3 +; SDAG-NEXT: v_dual_mov_b32 v0, 0x7fc00000 :: v_dual_mov_b32 v1, 0 +; SDAG-NEXT: v_mov_b32_e32 v2, 1.0 +; SDAG-NEXT: s_mov_b32 s0, s12 +; SDAG-NEXT: s_mov_b32 s1, s12 +; SDAG-NEXT: s_mov_b32 s2, s12 +; SDAG-NEXT: s_mov_b32 s3, s12 +; SDAG-NEXT: s_mov_b32 s4, s12 +; SDAG-NEXT: s_mov_b32 s5, s12 +; SDAG-NEXT: s_mov_b32 s6, s12 +; SDAG-NEXT: s_mov_b32 s7, s12 +; SDAG-NEXT: s_clause 0x2 +; SDAG-NEXT: image_sample_c_lz v0, [v1, v1, v0, v1], s[0:7], s[12:15] dmask:0x1 dim:SQ_RSRC_IMG_2D_ARRAY +; SDAG-NEXT: image_sample_c_lz v3, [v1, v1, v1, v1], s[0:7], s[12:15] dmask:0x1 dim:SQ_RSRC_IMG_2D_ARRAY +; SDAG-NEXT: image_sample_c_lz v2, [v1, v2, v1, v1], s[0:7], s[12:15] dmask:0x1 dim:SQ_RSRC_IMG_2D_ARRAY +; SDAG-NEXT: v_mov_b32_e32 v4, v1 +; SDAG-NEXT: s_waitcnt vmcnt(2) +; SDAG-NEXT: v_add_f32_e32 v0, v9, v0 +; SDAG-NEXT: s_waitcnt vmcnt(0) +; SDAG-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2) +; SDAG-NEXT: v_add_f32_e32 v0, v2, v0 +; SDAG-NEXT: v_mov_b32_e32 v2, v1 +; SDAG-NEXT: v_dual_add_f32 v0, v3, v0 :: v_dual_mov_b32 v3, v1 +; SDAG-NEXT: s_delay_alu instid0(VALU_DEP_1) +; SDAG-NEXT: v_mul_f32_e32 v0, 0x3e800000, v0 +; SDAG-NEXT: image_store v[0:2], v[3:4], s[0:7] dim:SQ_RSRC_IMG_2D unorm +; SDAG-NEXT: s_setpc_b64 s[30:31] +; +; GISEL-LABEL: issue92561: +; GISEL: ; %bb.0: ; %bb +; GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GISEL-NEXT: s_clause 0x1 +; GISEL-NEXT: global_load_b128 v[2:5], v[0:1], off +; GISEL-NEXT: global_load_b128 v[6:9], v[0:1], off offset:16 +; GISEL-NEXT: v_mov_b32_e32 v0, 0 +; GISEL-NEXT: s_mov_b32 s20, 0 +; GISEL-NEXT: s_mov_b32 s3, exec_lo +; GISEL-NEXT: s_mov_b32 s21, s20 +; GISEL-NEXT: s_mov_b32 s22, s20 +; GISEL-NEXT: s_mov_b32 s23, s20 +; GISEL-NEXT: s_mov_b32 s4, s20 +; GISEL-NEXT: s_mov_b32 s5, s20 +; GISEL-NEXT: s_mov_b32 s6, s20 +; GISEL-NEXT: s_mov_b32 s7, s20 +; GISEL-NEXT: s_mov_b32 s8, s20 +; GISEL-NEXT: s_mov_b32 s9, s20 +; GISEL-NEXT: s_mov_b32 s10, s20 +; GISEL-NEXT: s_mov_b32 s11, s20 +; GISEL-NEXT: s_waitcnt vmcnt(0) +; GISEL-NEXT: .LBB0_1: ; =>This Inner Loop Header: Depth=1 +; GISEL-NEXT: v_readfirstlane_b32 s12, v2 +; GISEL-NEXT: v_readfirstlane_b32 s13, v3 +; GISEL-NEXT: v_readfirstlane_b32 s14, v4 +; GISEL-NEXT: v_readfirstlane_b32 s15, v5 +; GISEL-NEXT: v_readfirstlane_b32 s16, v6 +; GISEL-NEXT: v_readfirstlane_b32 s17, v7 +; GISEL-NEXT: v_readfirstlane_b32 s18, v8 +; GISEL-NEXT: v_readfirstlane_b32 s19, v9 +; GISEL-NEXT: v_cmp_eq_u64_e32 vcc_lo, s[12:13], v[2:3] +; GISEL-NEXT: v_cmp_eq_u64_e64 s0, s[14:15], v[4:5] +; GISEL-NEXT: v_cmp_eq_u64_e64 s1, s[16:17], v[6:7] +; GISEL-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_3) +; GISEL-NEXT: v_cmp_eq_u64_e64 s2, s[18:19], v[8:9] +; GISEL-NEXT: s_and_b32 s0, vcc_lo, s0 +; GISEL-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1) +; GISEL-NEXT: s_and_b32 s0, s0, s1 +; GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1) +; GISEL-NEXT: s_and_b32 s0, s0, s2 +; GISEL-NEXT: s_delay_alu instid0(SALU_CYCLE_1) +; GISEL-NEXT: s_and_saveexec_b32 s0, s0 +; GISEL-NEXT: image_sample_c_lz v1, [v0, v0, v0, v0], s[12:19], s[20:23] dmask:0x1 dim:SQ_RSRC_IMG_2D_ARRAY +; GISEL-NEXT: ; implicit-def: $vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7_vgpr8_vgpr9 +; GISEL-NEXT: ; implicit-def: $vgpr0 +; GISEL-NEXT: s_xor_b32 exec_lo, exec_lo, s0 +; GISEL-NEXT: s_cbranch_execnz .LBB0_1 +; GISEL-NEXT: ; %bb.2: +; GISEL-NEXT: s_mov_b32 exec_lo, s3 +; GISEL-NEXT: v_dual_mov_b32 v2, 0 :: v_dual_mov_b32 v3, 1.0 +; GISEL-NEXT: v_mov_b32_e32 v0, 0x7fc00000 +; GISEL-NEXT: s_clause 0x2 +; GISEL-NEXT: image_sample_c_lz v0, [v2, v2, v0, v2], s[4:11], s[20:23] dmask:0x1 dim:SQ_RSRC_IMG_2D_ARRAY +; GISEL-NEXT: image_sample_c_lz v3, [v2, v3, v2, v2], s[4:11], s[20:23] dmask:0x1 dim:SQ_RSRC_IMG_2D_ARRAY +; GISEL-NEXT: image_sample_c_lz v4, [v2, v2, v2, v2], s[4:11], s[20:23] dmask:0x1 dim:SQ_RSRC_IMG_2D_ARRAY +; GISEL-NEXT: s_mov_b32 s21, s20 +; GISEL-NEXT: s_waitcnt vmcnt(2) +; GISEL-NEXT: v_add_f32_e32 v0, v1, v0 +; GISEL-NEXT: s_waitcnt vmcnt(1) +; GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1) +; GISEL-NEXT: v_dual_add_f32 v0, v3, v0 :: v_dual_mov_b32 v3, v2 +; GISEL-NEXT: s_waitcnt vmcnt(0) +; GISEL-NEXT: v_add_f32_e32 v0, v4, v0 +; GISEL-NEXT: v_dual_mov_b32 v4, s20 :: v_dual_mov_b32 v5, s21 +; GISEL-NEXT: s_delay_alu instid0(VALU_DEP_2) +; GISEL-NEXT: v_mul_f32_e32 v1, 0x3e800000, v0 +; GISEL-NEXT: image_store v[1:3], v[4:5], s[4:11] dim:SQ_RSRC_IMG_2D unorm +; GISEL-NEXT: s_setpc_b64 s[30:31] +bb: + %descriptor = load <8 x i32>, ptr addrspace(1) %arg, align 32 + %needs.waterfall = call float @llvm.amdgcn.image.sample.c.lz.2darray.f32.f32(i32 1, float 0.0, float 0.0, float 0.0, float 0.0, <8 x i32> %descriptor, <4 x i32> zeroinitializer, i1 false, i32 0, i32 0) + %i2 = call float @llvm.amdgcn.image.sample.c.lz.2darray.f32.f32(i32 1, float 0.0, float 0.0, float 0x7FF8000000000000, float 0.0, <8 x i32> zeroinitializer, <4 x i32> zeroinitializer, i1 false, i32 0, i32 0) + %i3 = fadd float %needs.waterfall, %i2 + %i4 = call float @llvm.amdgcn.image.sample.c.lz.2darray.f32.f32(i32 1, float 0.0, float 1.000000e+00, float 0.0, float 0.0, <8 x i32> zeroinitializer, <4 x i32> zeroinitializer, i1 false, i32 0, i32 0) + %i5 = fadd float %i4, %i3 + %i6 = call float @llvm.amdgcn.image.sample.c.lz.2darray.f32.f32(i32 1, float 0.0, float 0.0, float 0.0, float 0.0, <8 x i32> zeroinitializer, <4 x i32> zeroinitializer, i1 false, i32 0, i32 0) + %i7 = fadd float %i6, %i5 + %i8 = fmul float %i7, 2.500000e-01 + %i9 = insertelement <3 x float> zeroinitializer, float %i8, i64 0 + call void @llvm.amdgcn.image.store.2d.v3f32.i32(<3 x float> %i9, i32 0, i32 0, i32 0, <8 x i32> zeroinitializer, i32 0, i32 0) + ret void +} -- GitLab From f7e63e8b46257d6eea35357e8e4ab44e2677a0a8 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sat, 1 Jun 2024 01:08:45 -0700 Subject: [PATCH 008/678] [LV] Operands feeding pointers of interleave member pointers are free. For interleave groups we only create a pointer for the start of the interleave group, not all original loads/stores. Mark single-use ops feeding interleave group mem ops as free when vectorizing. --- .../Transforms/Vectorize/LoopVectorize.cpp | 23 +- .../LoopVectorize/X86/strided_load_cost.ll | 228 ++++++------------ 2 files changed, 95 insertions(+), 156 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 51221481b1ca..5939ce5b917a 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -7139,14 +7139,33 @@ void LoopVectorizationCostModel::collectValuesToIgnore() { // Ignore ephemeral values. CodeMetrics::collectEphemeralValues(TheLoop, AC, ValuesToIgnore); - // Find all stores to invariant variables. Since they are going to sink - // outside the loop we do not need calculate cost for them. for (BasicBlock *BB : TheLoop->blocks()) for (Instruction &I : *BB) { + // Find all stores to invariant variables. Since they are going to sink + // outside the loop we do not need calculate cost for them. StoreInst *SI; if ((SI = dyn_cast(&I)) && Legal->isInvariantAddressOfReduction(SI->getPointerOperand())) ValuesToIgnore.insert(&I); + + // For interleave groups, we only create a pointer for the start of the + // interleave group. Mark single-use ops feeding interleave group mem ops + // as free when vectorizing, expect the insert-pos memory op. + if (isAccessInterleaved(&I)) { + auto *Group = getInterleavedAccessGroup(&I); + if (Group->getInsertPos() == &I) + continue; + Value *PointerOp = getLoadStorePointerOperand(&I); + SmallSetVector Worklist; + Worklist.insert(PointerOp); + for (unsigned I = 0; I != Worklist.size(); ++I) { + auto *Op = dyn_cast(Worklist[I]); + if (!Op || !TheLoop->contains(Op) || !Op->hasOneUse()) + continue; + VecValuesToIgnore.insert(Op); + Worklist.insert(Op->op_begin(), Op->op_end()); + } + } } // Ignore type-promoting instructions we identified during reduction diff --git a/llvm/test/Transforms/LoopVectorize/X86/strided_load_cost.ll b/llvm/test/Transforms/LoopVectorize/X86/strided_load_cost.ll index 48c6063e9409..200afadc4c61 100644 --- a/llvm/test/Transforms/LoopVectorize/X86/strided_load_cost.ll +++ b/llvm/test/Transforms/LoopVectorize/X86/strided_load_cost.ll @@ -531,160 +531,80 @@ define void @test(ptr %A, ptr noalias %B) #0 { ; MAX-BW-NEXT: [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 26 ; MAX-BW-NEXT: [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 28 ; MAX-BW-NEXT: [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 30 -; MAX-BW-NEXT: [[TMP16:%.*]] = add i64 [[OFFSET_IDX]], 32 -; MAX-BW-NEXT: [[TMP17:%.*]] = add i64 [[OFFSET_IDX]], 34 -; MAX-BW-NEXT: [[TMP18:%.*]] = add i64 [[OFFSET_IDX]], 36 -; MAX-BW-NEXT: [[TMP19:%.*]] = add i64 [[OFFSET_IDX]], 38 -; MAX-BW-NEXT: [[TMP20:%.*]] = add i64 [[OFFSET_IDX]], 40 -; MAX-BW-NEXT: [[TMP21:%.*]] = add i64 [[OFFSET_IDX]], 42 -; MAX-BW-NEXT: [[TMP22:%.*]] = add i64 [[OFFSET_IDX]], 44 -; MAX-BW-NEXT: [[TMP23:%.*]] = add i64 [[OFFSET_IDX]], 46 -; MAX-BW-NEXT: [[TMP24:%.*]] = add i64 [[OFFSET_IDX]], 48 -; MAX-BW-NEXT: [[TMP25:%.*]] = add i64 [[OFFSET_IDX]], 50 -; MAX-BW-NEXT: [[TMP26:%.*]] = add i64 [[OFFSET_IDX]], 52 -; MAX-BW-NEXT: [[TMP27:%.*]] = add i64 [[OFFSET_IDX]], 54 -; MAX-BW-NEXT: [[TMP28:%.*]] = add i64 [[OFFSET_IDX]], 56 -; MAX-BW-NEXT: [[TMP29:%.*]] = add i64 [[OFFSET_IDX]], 58 -; MAX-BW-NEXT: [[TMP30:%.*]] = add i64 [[OFFSET_IDX]], 60 -; MAX-BW-NEXT: [[TMP31:%.*]] = add i64 [[OFFSET_IDX]], 62 -; MAX-BW-NEXT: [[TMP32:%.*]] = add nuw nsw i64 [[TMP0]], 0 -; MAX-BW-NEXT: [[TMP33:%.*]] = add nuw nsw i64 [[TMP1]], 0 -; MAX-BW-NEXT: [[TMP34:%.*]] = add nuw nsw i64 [[TMP2]], 0 -; MAX-BW-NEXT: [[TMP35:%.*]] = add nuw nsw i64 [[TMP3]], 0 -; MAX-BW-NEXT: [[TMP36:%.*]] = add nuw nsw i64 [[TMP4]], 0 -; MAX-BW-NEXT: [[TMP37:%.*]] = add nuw nsw i64 [[TMP5]], 0 -; MAX-BW-NEXT: [[TMP38:%.*]] = add nuw nsw i64 [[TMP6]], 0 -; MAX-BW-NEXT: [[TMP39:%.*]] = add nuw nsw i64 [[TMP7]], 0 -; MAX-BW-NEXT: [[TMP40:%.*]] = add nuw nsw i64 [[TMP8]], 0 -; MAX-BW-NEXT: [[TMP41:%.*]] = add nuw nsw i64 [[TMP9]], 0 -; MAX-BW-NEXT: [[TMP42:%.*]] = add nuw nsw i64 [[TMP10]], 0 -; MAX-BW-NEXT: [[TMP43:%.*]] = add nuw nsw i64 [[TMP11]], 0 -; MAX-BW-NEXT: [[TMP44:%.*]] = add nuw nsw i64 [[TMP12]], 0 -; MAX-BW-NEXT: [[TMP45:%.*]] = add nuw nsw i64 [[TMP13]], 0 -; MAX-BW-NEXT: [[TMP46:%.*]] = add nuw nsw i64 [[TMP14]], 0 -; MAX-BW-NEXT: [[TMP47:%.*]] = add nuw nsw i64 [[TMP15]], 0 -; MAX-BW-NEXT: [[TMP48:%.*]] = add nuw nsw i64 [[TMP16]], 0 -; MAX-BW-NEXT: [[TMP49:%.*]] = add nuw nsw i64 [[TMP17]], 0 -; MAX-BW-NEXT: [[TMP50:%.*]] = add nuw nsw i64 [[TMP18]], 0 -; MAX-BW-NEXT: [[TMP51:%.*]] = add nuw nsw i64 [[TMP19]], 0 -; MAX-BW-NEXT: [[TMP52:%.*]] = add nuw nsw i64 [[TMP20]], 0 -; MAX-BW-NEXT: [[TMP53:%.*]] = add nuw nsw i64 [[TMP21]], 0 -; MAX-BW-NEXT: [[TMP54:%.*]] = add nuw nsw i64 [[TMP22]], 0 -; MAX-BW-NEXT: [[TMP55:%.*]] = add nuw nsw i64 [[TMP23]], 0 -; MAX-BW-NEXT: [[TMP56:%.*]] = add nuw nsw i64 [[TMP24]], 0 -; MAX-BW-NEXT: [[TMP57:%.*]] = add nuw nsw i64 [[TMP25]], 0 -; MAX-BW-NEXT: [[TMP58:%.*]] = add nuw nsw i64 [[TMP26]], 0 -; MAX-BW-NEXT: [[TMP59:%.*]] = add nuw nsw i64 [[TMP27]], 0 -; MAX-BW-NEXT: [[TMP60:%.*]] = add nuw nsw i64 [[TMP28]], 0 -; MAX-BW-NEXT: [[TMP61:%.*]] = add nuw nsw i64 [[TMP29]], 0 -; MAX-BW-NEXT: [[TMP62:%.*]] = add nuw nsw i64 [[TMP30]], 0 -; MAX-BW-NEXT: [[TMP63:%.*]] = add nuw nsw i64 [[TMP31]], 0 -; MAX-BW-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1024 x i32], ptr [[A:%.*]], i64 0, i64 [[TMP32]] -; MAX-BW-NEXT: [[TMP65:%.*]] = getelementptr inbounds i32, ptr [[TMP64]], i32 0 -; MAX-BW-NEXT: [[WIDE_VEC:%.*]] = load <64 x i32>, ptr [[TMP65]], align 4 -; MAX-BW-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <64 x i32> [[WIDE_VEC]], <64 x i32> poison, <32 x i32> -; MAX-BW-NEXT: [[STRIDED_VEC1:%.*]] = shufflevector <64 x i32> [[WIDE_VEC]], <64 x i32> poison, <32 x i32> -; MAX-BW-NEXT: [[TMP66:%.*]] = add <32 x i32> [[STRIDED_VEC]], [[STRIDED_VEC1]] -; MAX-BW-NEXT: [[TMP67:%.*]] = trunc <32 x i32> [[TMP66]] to <32 x i8> -; MAX-BW-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B:%.*]], i64 0, i64 [[TMP32]] -; MAX-BW-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP33]] -; MAX-BW-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP34]] -; MAX-BW-NEXT: [[TMP71:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP35]] -; MAX-BW-NEXT: [[TMP72:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP36]] -; MAX-BW-NEXT: [[TMP73:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP37]] -; MAX-BW-NEXT: [[TMP74:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP38]] -; MAX-BW-NEXT: [[TMP75:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP39]] -; MAX-BW-NEXT: [[TMP76:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP40]] -; MAX-BW-NEXT: [[TMP77:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP41]] -; MAX-BW-NEXT: [[TMP78:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP42]] -; MAX-BW-NEXT: [[TMP79:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP43]] -; MAX-BW-NEXT: [[TMP80:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP44]] -; MAX-BW-NEXT: [[TMP81:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP45]] -; MAX-BW-NEXT: [[TMP82:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP46]] -; MAX-BW-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP47]] -; MAX-BW-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP48]] -; MAX-BW-NEXT: [[TMP85:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP49]] -; MAX-BW-NEXT: [[TMP86:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP50]] -; MAX-BW-NEXT: [[TMP87:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP51]] -; MAX-BW-NEXT: [[TMP88:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP52]] -; MAX-BW-NEXT: [[TMP89:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP53]] -; MAX-BW-NEXT: [[TMP90:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP54]] -; MAX-BW-NEXT: [[TMP91:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP55]] -; MAX-BW-NEXT: [[TMP92:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP56]] -; MAX-BW-NEXT: [[TMP93:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP57]] -; MAX-BW-NEXT: [[TMP94:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP58]] -; MAX-BW-NEXT: [[TMP95:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP59]] -; MAX-BW-NEXT: [[TMP96:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP60]] -; MAX-BW-NEXT: [[TMP97:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP61]] -; MAX-BW-NEXT: [[TMP98:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP62]] -; MAX-BW-NEXT: [[TMP99:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP63]] -; MAX-BW-NEXT: [[TMP100:%.*]] = extractelement <32 x i8> [[TMP67]], i32 0 -; MAX-BW-NEXT: store i8 [[TMP100]], ptr [[TMP68]], align 1 -; MAX-BW-NEXT: [[TMP101:%.*]] = extractelement <32 x i8> [[TMP67]], i32 1 -; MAX-BW-NEXT: store i8 [[TMP101]], ptr [[TMP69]], align 1 -; MAX-BW-NEXT: [[TMP102:%.*]] = extractelement <32 x i8> [[TMP67]], i32 2 -; MAX-BW-NEXT: store i8 [[TMP102]], ptr [[TMP70]], align 1 -; MAX-BW-NEXT: [[TMP103:%.*]] = extractelement <32 x i8> [[TMP67]], i32 3 -; MAX-BW-NEXT: store i8 [[TMP103]], ptr [[TMP71]], align 1 -; MAX-BW-NEXT: [[TMP104:%.*]] = extractelement <32 x i8> [[TMP67]], i32 4 -; MAX-BW-NEXT: store i8 [[TMP104]], ptr [[TMP72]], align 1 -; MAX-BW-NEXT: [[TMP105:%.*]] = extractelement <32 x i8> [[TMP67]], i32 5 -; MAX-BW-NEXT: store i8 [[TMP105]], ptr [[TMP73]], align 1 -; MAX-BW-NEXT: [[TMP106:%.*]] = extractelement <32 x i8> [[TMP67]], i32 6 -; MAX-BW-NEXT: store i8 [[TMP106]], ptr [[TMP74]], align 1 -; MAX-BW-NEXT: [[TMP107:%.*]] = extractelement <32 x i8> [[TMP67]], i32 7 -; MAX-BW-NEXT: store i8 [[TMP107]], ptr [[TMP75]], align 1 -; MAX-BW-NEXT: [[TMP108:%.*]] = extractelement <32 x i8> [[TMP67]], i32 8 -; MAX-BW-NEXT: store i8 [[TMP108]], ptr [[TMP76]], align 1 -; MAX-BW-NEXT: [[TMP109:%.*]] = extractelement <32 x i8> [[TMP67]], i32 9 -; MAX-BW-NEXT: store i8 [[TMP109]], ptr [[TMP77]], align 1 -; MAX-BW-NEXT: [[TMP110:%.*]] = extractelement <32 x i8> [[TMP67]], i32 10 -; MAX-BW-NEXT: store i8 [[TMP110]], ptr [[TMP78]], align 1 -; MAX-BW-NEXT: [[TMP111:%.*]] = extractelement <32 x i8> [[TMP67]], i32 11 -; MAX-BW-NEXT: store i8 [[TMP111]], ptr [[TMP79]], align 1 -; MAX-BW-NEXT: [[TMP112:%.*]] = extractelement <32 x i8> [[TMP67]], i32 12 -; MAX-BW-NEXT: store i8 [[TMP112]], ptr [[TMP80]], align 1 -; MAX-BW-NEXT: [[TMP113:%.*]] = extractelement <32 x i8> [[TMP67]], i32 13 -; MAX-BW-NEXT: store i8 [[TMP113]], ptr [[TMP81]], align 1 -; MAX-BW-NEXT: [[TMP114:%.*]] = extractelement <32 x i8> [[TMP67]], i32 14 -; MAX-BW-NEXT: store i8 [[TMP114]], ptr [[TMP82]], align 1 -; MAX-BW-NEXT: [[TMP115:%.*]] = extractelement <32 x i8> [[TMP67]], i32 15 -; MAX-BW-NEXT: store i8 [[TMP115]], ptr [[TMP83]], align 1 -; MAX-BW-NEXT: [[TMP116:%.*]] = extractelement <32 x i8> [[TMP67]], i32 16 -; MAX-BW-NEXT: store i8 [[TMP116]], ptr [[TMP84]], align 1 -; MAX-BW-NEXT: [[TMP117:%.*]] = extractelement <32 x i8> [[TMP67]], i32 17 -; MAX-BW-NEXT: store i8 [[TMP117]], ptr [[TMP85]], align 1 -; MAX-BW-NEXT: [[TMP118:%.*]] = extractelement <32 x i8> [[TMP67]], i32 18 -; MAX-BW-NEXT: store i8 [[TMP118]], ptr [[TMP86]], align 1 -; MAX-BW-NEXT: [[TMP119:%.*]] = extractelement <32 x i8> [[TMP67]], i32 19 -; MAX-BW-NEXT: store i8 [[TMP119]], ptr [[TMP87]], align 1 -; MAX-BW-NEXT: [[TMP120:%.*]] = extractelement <32 x i8> [[TMP67]], i32 20 -; MAX-BW-NEXT: store i8 [[TMP120]], ptr [[TMP88]], align 1 -; MAX-BW-NEXT: [[TMP121:%.*]] = extractelement <32 x i8> [[TMP67]], i32 21 -; MAX-BW-NEXT: store i8 [[TMP121]], ptr [[TMP89]], align 1 -; MAX-BW-NEXT: [[TMP122:%.*]] = extractelement <32 x i8> [[TMP67]], i32 22 -; MAX-BW-NEXT: store i8 [[TMP122]], ptr [[TMP90]], align 1 -; MAX-BW-NEXT: [[TMP123:%.*]] = extractelement <32 x i8> [[TMP67]], i32 23 -; MAX-BW-NEXT: store i8 [[TMP123]], ptr [[TMP91]], align 1 -; MAX-BW-NEXT: [[TMP124:%.*]] = extractelement <32 x i8> [[TMP67]], i32 24 -; MAX-BW-NEXT: store i8 [[TMP124]], ptr [[TMP92]], align 1 -; MAX-BW-NEXT: [[TMP125:%.*]] = extractelement <32 x i8> [[TMP67]], i32 25 -; MAX-BW-NEXT: store i8 [[TMP125]], ptr [[TMP93]], align 1 -; MAX-BW-NEXT: [[TMP126:%.*]] = extractelement <32 x i8> [[TMP67]], i32 26 -; MAX-BW-NEXT: store i8 [[TMP126]], ptr [[TMP94]], align 1 -; MAX-BW-NEXT: [[TMP127:%.*]] = extractelement <32 x i8> [[TMP67]], i32 27 -; MAX-BW-NEXT: store i8 [[TMP127]], ptr [[TMP95]], align 1 -; MAX-BW-NEXT: [[TMP128:%.*]] = extractelement <32 x i8> [[TMP67]], i32 28 -; MAX-BW-NEXT: store i8 [[TMP128]], ptr [[TMP96]], align 1 -; MAX-BW-NEXT: [[TMP129:%.*]] = extractelement <32 x i8> [[TMP67]], i32 29 -; MAX-BW-NEXT: store i8 [[TMP129]], ptr [[TMP97]], align 1 -; MAX-BW-NEXT: [[TMP130:%.*]] = extractelement <32 x i8> [[TMP67]], i32 30 -; MAX-BW-NEXT: store i8 [[TMP130]], ptr [[TMP98]], align 1 -; MAX-BW-NEXT: [[TMP131:%.*]] = extractelement <32 x i8> [[TMP67]], i32 31 -; MAX-BW-NEXT: store i8 [[TMP131]], ptr [[TMP99]], align 1 -; MAX-BW-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32 -; MAX-BW-NEXT: [[TMP132:%.*]] = icmp eq i64 [[INDEX_NEXT]], 512 -; MAX-BW-NEXT: br i1 [[TMP132]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]] +; MAX-BW-NEXT: [[TMP16:%.*]] = add nuw nsw i64 [[TMP0]], 0 +; MAX-BW-NEXT: [[TMP17:%.*]] = add nuw nsw i64 [[TMP1]], 0 +; MAX-BW-NEXT: [[TMP18:%.*]] = add nuw nsw i64 [[TMP2]], 0 +; MAX-BW-NEXT: [[TMP19:%.*]] = add nuw nsw i64 [[TMP3]], 0 +; MAX-BW-NEXT: [[TMP20:%.*]] = add nuw nsw i64 [[TMP4]], 0 +; MAX-BW-NEXT: [[TMP21:%.*]] = add nuw nsw i64 [[TMP5]], 0 +; MAX-BW-NEXT: [[TMP22:%.*]] = add nuw nsw i64 [[TMP6]], 0 +; MAX-BW-NEXT: [[TMP23:%.*]] = add nuw nsw i64 [[TMP7]], 0 +; MAX-BW-NEXT: [[TMP24:%.*]] = add nuw nsw i64 [[TMP8]], 0 +; MAX-BW-NEXT: [[TMP25:%.*]] = add nuw nsw i64 [[TMP9]], 0 +; MAX-BW-NEXT: [[TMP26:%.*]] = add nuw nsw i64 [[TMP10]], 0 +; MAX-BW-NEXT: [[TMP27:%.*]] = add nuw nsw i64 [[TMP11]], 0 +; MAX-BW-NEXT: [[TMP28:%.*]] = add nuw nsw i64 [[TMP12]], 0 +; MAX-BW-NEXT: [[TMP29:%.*]] = add nuw nsw i64 [[TMP13]], 0 +; MAX-BW-NEXT: [[TMP30:%.*]] = add nuw nsw i64 [[TMP14]], 0 +; MAX-BW-NEXT: [[TMP31:%.*]] = add nuw nsw i64 [[TMP15]], 0 +; MAX-BW-NEXT: [[TMP32:%.*]] = getelementptr inbounds [1024 x i32], ptr [[A:%.*]], i64 0, i64 [[TMP16]] +; MAX-BW-NEXT: [[TMP33:%.*]] = getelementptr inbounds i32, ptr [[TMP32]], i32 0 +; MAX-BW-NEXT: [[WIDE_VEC:%.*]] = load <32 x i32>, ptr [[TMP33]], align 4 +; MAX-BW-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <32 x i32> [[WIDE_VEC]], <32 x i32> poison, <16 x i32> +; MAX-BW-NEXT: [[STRIDED_VEC1:%.*]] = shufflevector <32 x i32> [[WIDE_VEC]], <32 x i32> poison, <16 x i32> +; MAX-BW-NEXT: [[TMP34:%.*]] = add <16 x i32> [[STRIDED_VEC]], [[STRIDED_VEC1]] +; MAX-BW-NEXT: [[TMP35:%.*]] = trunc <16 x i32> [[TMP34]] to <16 x i8> +; MAX-BW-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B:%.*]], i64 0, i64 [[TMP16]] +; MAX-BW-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP17]] +; MAX-BW-NEXT: [[TMP38:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP18]] +; MAX-BW-NEXT: [[TMP39:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP19]] +; MAX-BW-NEXT: [[TMP40:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP20]] +; MAX-BW-NEXT: [[TMP41:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP21]] +; MAX-BW-NEXT: [[TMP42:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP22]] +; MAX-BW-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP23]] +; MAX-BW-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP24]] +; MAX-BW-NEXT: [[TMP45:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP25]] +; MAX-BW-NEXT: [[TMP46:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP26]] +; MAX-BW-NEXT: [[TMP47:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP27]] +; MAX-BW-NEXT: [[TMP48:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP28]] +; MAX-BW-NEXT: [[TMP49:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP29]] +; MAX-BW-NEXT: [[TMP50:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP30]] +; MAX-BW-NEXT: [[TMP51:%.*]] = getelementptr inbounds [1024 x i8], ptr [[B]], i64 0, i64 [[TMP31]] +; MAX-BW-NEXT: [[TMP52:%.*]] = extractelement <16 x i8> [[TMP35]], i32 0 +; MAX-BW-NEXT: store i8 [[TMP52]], ptr [[TMP36]], align 1 +; MAX-BW-NEXT: [[TMP53:%.*]] = extractelement <16 x i8> [[TMP35]], i32 1 +; MAX-BW-NEXT: store i8 [[TMP53]], ptr [[TMP37]], align 1 +; MAX-BW-NEXT: [[TMP54:%.*]] = extractelement <16 x i8> [[TMP35]], i32 2 +; MAX-BW-NEXT: store i8 [[TMP54]], ptr [[TMP38]], align 1 +; MAX-BW-NEXT: [[TMP55:%.*]] = extractelement <16 x i8> [[TMP35]], i32 3 +; MAX-BW-NEXT: store i8 [[TMP55]], ptr [[TMP39]], align 1 +; MAX-BW-NEXT: [[TMP56:%.*]] = extractelement <16 x i8> [[TMP35]], i32 4 +; MAX-BW-NEXT: store i8 [[TMP56]], ptr [[TMP40]], align 1 +; MAX-BW-NEXT: [[TMP57:%.*]] = extractelement <16 x i8> [[TMP35]], i32 5 +; MAX-BW-NEXT: store i8 [[TMP57]], ptr [[TMP41]], align 1 +; MAX-BW-NEXT: [[TMP58:%.*]] = extractelement <16 x i8> [[TMP35]], i32 6 +; MAX-BW-NEXT: store i8 [[TMP58]], ptr [[TMP42]], align 1 +; MAX-BW-NEXT: [[TMP59:%.*]] = extractelement <16 x i8> [[TMP35]], i32 7 +; MAX-BW-NEXT: store i8 [[TMP59]], ptr [[TMP43]], align 1 +; MAX-BW-NEXT: [[TMP60:%.*]] = extractelement <16 x i8> [[TMP35]], i32 8 +; MAX-BW-NEXT: store i8 [[TMP60]], ptr [[TMP44]], align 1 +; MAX-BW-NEXT: [[TMP61:%.*]] = extractelement <16 x i8> [[TMP35]], i32 9 +; MAX-BW-NEXT: store i8 [[TMP61]], ptr [[TMP45]], align 1 +; MAX-BW-NEXT: [[TMP62:%.*]] = extractelement <16 x i8> [[TMP35]], i32 10 +; MAX-BW-NEXT: store i8 [[TMP62]], ptr [[TMP46]], align 1 +; MAX-BW-NEXT: [[TMP63:%.*]] = extractelement <16 x i8> [[TMP35]], i32 11 +; MAX-BW-NEXT: store i8 [[TMP63]], ptr [[TMP47]], align 1 +; MAX-BW-NEXT: [[TMP64:%.*]] = extractelement <16 x i8> [[TMP35]], i32 12 +; MAX-BW-NEXT: store i8 [[TMP64]], ptr [[TMP48]], align 1 +; MAX-BW-NEXT: [[TMP65:%.*]] = extractelement <16 x i8> [[TMP35]], i32 13 +; MAX-BW-NEXT: store i8 [[TMP65]], ptr [[TMP49]], align 1 +; MAX-BW-NEXT: [[TMP66:%.*]] = extractelement <16 x i8> [[TMP35]], i32 14 +; MAX-BW-NEXT: store i8 [[TMP66]], ptr [[TMP50]], align 1 +; MAX-BW-NEXT: [[TMP67:%.*]] = extractelement <16 x i8> [[TMP35]], i32 15 +; MAX-BW-NEXT: store i8 [[TMP67]], ptr [[TMP51]], align 1 +; MAX-BW-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16 +; MAX-BW-NEXT: [[TMP68:%.*]] = icmp eq i64 [[INDEX_NEXT]], 512 +; MAX-BW-NEXT: br i1 [[TMP68]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]] ; MAX-BW: middle.block: ; MAX-BW-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] ; MAX-BW: scalar.ph: -- GitLab From 598f37bb27c3a6e71252bbd15c587c7f11e20520 Mon Sep 17 00:00:00 2001 From: Sayhaan Siddiqui <49014204+sayhaan@users.noreply.github.com> Date: Sat, 1 Jun 2024 08:14:41 -0700 Subject: [PATCH 009/678] [BOLT][DWARF][NFC] Add split-dwarf4 test with multiple CUs (#93741) Adds a split-dwarf test for DWARF4 with multiple CUs. --- .../dwarf4-df-input-lowpc-ranges-other.s | 710 ++++++++++++++++++ .../X86/dwarf4-df-input-lowpc-ranges-cus.test | 97 +++ 2 files changed, 807 insertions(+) create mode 100644 bolt/test/X86/Inputs/dwarf4-df-input-lowpc-ranges-other.s create mode 100644 bolt/test/X86/dwarf4-df-input-lowpc-ranges-cus.test diff --git a/bolt/test/X86/Inputs/dwarf4-df-input-lowpc-ranges-other.s b/bolt/test/X86/Inputs/dwarf4-df-input-lowpc-ranges-other.s new file mode 100644 index 000000000000..c04fb521c75d --- /dev/null +++ b/bolt/test/X86/Inputs/dwarf4-df-input-lowpc-ranges-other.s @@ -0,0 +1,710 @@ +## clang++ -fbasic-block-sections=all -ffunction-sections -g2 -gdwarf-4 -gsplit-dwarf -fdebug-compilation-dir='.' +## __attribute__((always_inline)) +## int doStuffOther(int val) { +## if (val) +## ++val; +## return val; +## } +## __attribute__((always_inline)) +## int doStuffOther2(int val) { +## int foo = 3; +## return val + foo; +## } +## +## +## int mainOther(int argc, const char** argv) { +## return doStuffOther(argc) + doStuffOther2(argc);; +## } + + .text + .file "mainOther.cpp" + .section .text._Z12doStuffOtheri,"ax",@progbits + .globl _Z12doStuffOtheri # -- Begin function _Z12doStuffOtheri + .p2align 4, 0x90 + .type _Z12doStuffOtheri,@function +_Z12doStuffOtheri: # @_Z12doStuffOtheri +.Lfunc_begin0: + .file 1 "." "mainOther.cpp" + .loc 1 2 0 # mainOther.cpp:2:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) +.Ltmp0: + .loc 1 3 8 prologue_end # mainOther.cpp:3:8 + cmpl $0, -4(%rbp) +.Ltmp1: + .loc 1 3 8 is_stmt 0 # mainOther.cpp:3:8 + je _Z12doStuffOtheri.__part.2 + jmp _Z12doStuffOtheri.__part.1 +.LBB_END0_0: + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits,unique,1 +_Z12doStuffOtheri.__part.1: # %if.then + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 1 4 6 is_stmt 1 # mainOther.cpp:4:6 + movl -4(%rbp), %eax + addl $1, %eax + movl %eax, -4(%rbp) + jmp _Z12doStuffOtheri.__part.2 +.LBB_END0_1: + .size _Z12doStuffOtheri.__part.1, .LBB_END0_1-_Z12doStuffOtheri.__part.1 + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits,unique,2 +_Z12doStuffOtheri.__part.2: # %if.end + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 1 5 11 # mainOther.cpp:5:11 + movl -4(%rbp), %eax + .loc 1 5 4 epilogue_begin is_stmt 0 # mainOther.cpp:5:4 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.LBB_END0_2: + .size _Z12doStuffOtheri.__part.2, .LBB_END0_2-_Z12doStuffOtheri.__part.2 + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits +.Lfunc_end0: + .size _Z12doStuffOtheri, .Lfunc_end0-_Z12doStuffOtheri + # -- End function + .section .text._Z13doStuffOther2i,"ax",@progbits + .globl _Z13doStuffOther2i # -- Begin function _Z13doStuffOther2i + .p2align 4, 0x90 + .type _Z13doStuffOther2i,@function +_Z13doStuffOther2i: # @_Z13doStuffOther2i +.Lfunc_begin1: + .loc 1 8 0 is_stmt 1 # mainOther.cpp:8:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) +.Ltmp2: + .loc 1 9 8 prologue_end # mainOther.cpp:9:8 + movl $3, -8(%rbp) + .loc 1 10 11 # mainOther.cpp:10:11 + movl -4(%rbp), %eax + .loc 1 10 15 is_stmt 0 # mainOther.cpp:10:15 + addl -8(%rbp), %eax + .loc 1 10 4 epilogue_begin # mainOther.cpp:10:4 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.LBB_END1_0: + .cfi_endproc +.Lfunc_end1: + .size _Z13doStuffOther2i, .Lfunc_end1-_Z13doStuffOther2i + # -- End function + .section .text._Z9mainOtheriPPKc,"ax",@progbits + .globl _Z9mainOtheriPPKc # -- Begin function _Z9mainOtheriPPKc + .p2align 4, 0x90 + .type _Z9mainOtheriPPKc,@function +_Z9mainOtheriPPKc: # @_Z9mainOtheriPPKc +.Lfunc_begin2: + .loc 1 14 0 is_stmt 1 # mainOther.cpp:14:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -16(%rbp) + movq %rsi, -24(%rbp) +.Ltmp3: + .loc 1 15 27 prologue_end # mainOther.cpp:15:27 + movl -16(%rbp), %eax + movl %eax, -12(%rbp) +.Ltmp4: + .loc 1 3 8 # mainOther.cpp:3:8 + cmpl $0, -12(%rbp) +.Ltmp5: + .loc 1 3 8 is_stmt 0 # mainOther.cpp:3:8 + je _Z9mainOtheriPPKc.__part.2 + jmp _Z9mainOtheriPPKc.__part.1 +.LBB_END2_0: + .cfi_endproc + .section .text._Z9mainOtheriPPKc,"ax",@progbits,unique,3 +_Z9mainOtheriPPKc.__part.1: # %if.then.i + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 1 4 6 is_stmt 1 # mainOther.cpp:4:6 + movl -12(%rbp), %eax + addl $1, %eax + movl %eax, -12(%rbp) + jmp _Z9mainOtheriPPKc.__part.2 +.LBB_END2_1: + .size _Z9mainOtheriPPKc.__part.1, .LBB_END2_1-_Z9mainOtheriPPKc.__part.1 + .cfi_endproc + .section .text._Z9mainOtheriPPKc,"ax",@progbits,unique,4 +_Z9mainOtheriPPKc.__part.2: # %_Z12doStuffOtheri.exit + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 1 5 11 # mainOther.cpp:5:11 + movl -12(%rbp), %eax +.Ltmp6: + .loc 1 15 49 # mainOther.cpp:15:49 + movl -16(%rbp), %ecx + movl %ecx, -4(%rbp) +.Ltmp7: + .loc 1 9 8 # mainOther.cpp:9:8 + movl $3, -8(%rbp) + .loc 1 10 11 # mainOther.cpp:10:11 + movl -4(%rbp), %ecx + .loc 1 10 15 is_stmt 0 # mainOther.cpp:10:15 + addl -8(%rbp), %ecx +.Ltmp8: + .loc 1 15 33 is_stmt 1 # mainOther.cpp:15:33 + addl %ecx, %eax + .loc 1 15 6 epilogue_begin is_stmt 0 # mainOther.cpp:15:6 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.LBB_END2_2: + .size _Z9mainOtheriPPKc.__part.2, .LBB_END2_2-_Z9mainOtheriPPKc.__part.2 + .cfi_endproc + .section .text._Z9mainOtheriPPKc,"ax",@progbits +.Lfunc_end2: + .size _Z9mainOtheriPPKc, .Lfunc_end2-_Z9mainOtheriPPKc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .ascii "\264B" # DW_AT_GNU_pubnames + .byte 25 # DW_FORM_flag_present + .ascii "\260B" # DW_AT_GNU_dwo_name + .byte 14 # DW_FORM_strp + .ascii "\261B" # DW_AT_GNU_dwo_id + .byte 7 # DW_FORM_data8 + .ascii "\262B" # DW_AT_GNU_ranges_base + .byte 23 # DW_FORM_sec_offset + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .ascii "\263B" # DW_AT_GNU_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x29 DW_TAG_compile_unit + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lskel_string0 # DW_AT_comp_dir + # DW_AT_GNU_pubnames + .long .Lskel_string1 # DW_AT_GNU_dwo_name + .quad -1082921489565291703 # DW_AT_GNU_dwo_id + .long .debug_ranges # DW_AT_GNU_ranges_base + .quad 0 # DW_AT_low_pc + .long .Ldebug_ranges3 # DW_AT_ranges + .long .Laddr_table_base0 # DW_AT_GNU_addr_base +.Ldebug_info_end0: + .section .debug_ranges,"",@progbits +.Ldebug_ranges0: + .quad _Z12doStuffOtheri.__part.1 + .quad .LBB_END0_1 + .quad _Z12doStuffOtheri.__part.2 + .quad .LBB_END0_2 + .quad .Lfunc_begin0 + .quad .Lfunc_end0 + .quad 0 + .quad 0 +.Ldebug_ranges1: + .quad _Z9mainOtheriPPKc.__part.1 + .quad .LBB_END2_1 + .quad _Z9mainOtheriPPKc.__part.2 + .quad .LBB_END2_2 + .quad .Lfunc_begin2 + .quad .Lfunc_end2 + .quad 0 + .quad 0 +.Ldebug_ranges2: + .quad .Ltmp4 + .quad .Lfunc_end2 + .quad _Z9mainOtheriPPKc.__part.1 + .quad .LBB_END2_1 + .quad _Z9mainOtheriPPKc.__part.2 + .quad .Ltmp6 + .quad 0 + .quad 0 +.Ldebug_ranges3: + .quad _Z12doStuffOtheri.__part.1 + .quad .LBB_END0_1 + .quad _Z12doStuffOtheri.__part.2 + .quad .LBB_END0_2 + .quad .Lfunc_begin0 + .quad .Lfunc_end0 + .quad .Lfunc_begin1 + .quad .Lfunc_end1 + .quad _Z9mainOtheriPPKc.__part.1 + .quad .LBB_END2_1 + .quad _Z9mainOtheriPPKc.__part.2 + .quad .LBB_END2_2 + .quad .Lfunc_begin2 + .quad .Lfunc_end2 + .quad 0 + .quad 0 + .section .debug_str,"MS",@progbits,1 +.Lskel_string0: + .asciz "." # string offset=0 +.Lskel_string1: + .asciz "mainOther.dwo" # string offset=2 + .section .debug_str.dwo,"eMS",@progbits,1 +.Linfo_string0: + .asciz "_Z12doStuffOtheri" # string offset=0 +.Linfo_string1: + .asciz "doStuffOther" # string offset=18 +.Linfo_string2: + .asciz "int" # string offset=31 +.Linfo_string3: + .asciz "val" # string offset=35 +.Linfo_string4: + .asciz "_Z13doStuffOther2i" # string offset=39 +.Linfo_string5: + .asciz "doStuffOther2" # string offset=58 +.Linfo_string6: + .asciz "foo" # string offset=72 +.Linfo_string7: + .asciz "_Z9mainOtheriPPKc" # string offset=76 +.Linfo_string8: + .asciz "mainOther" # string offset=94 +.Linfo_string9: + .asciz "argc" # string offset=104 +.Linfo_string10: + .asciz "argv" # string offset=109 +.Linfo_string11: + .asciz "char" # string offset=114 +.Linfo_string12: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git df542e1ed82bd4e5a9e345d3a3ae63a76893a0cf)" # string offset=119 +.Linfo_string13: + .asciz "mainOther.cpp" # string offset=223 +.Linfo_string14: + .asciz "mainOther.dwo" # string offset=237 + .section .debug_str_offsets.dwo,"e",@progbits + .long 0 + .long 18 + .long 31 + .long 35 + .long 39 + .long 58 + .long 72 + .long 76 + .long 94 + .long 104 + .long 109 + .long 114 + .long 119 + .long 223 + .long 237 + .section .debug_info.dwo,"e",@progbits + .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit +.Ldebug_info_dwo_start0: + .short 4 # DWARF version number + .long 0 # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0xde DW_TAG_compile_unit + .byte 12 # DW_AT_producer + .short 33 # DW_AT_language + .byte 13 # DW_AT_name + .byte 14 # DW_AT_GNU_dwo_name + .quad -1082921489565291703 # DW_AT_GNU_dwo_id + .byte 2 # Abbrev [2] 0x19:0x14 DW_TAG_subprogram + .long .Ldebug_ranges0-.debug_ranges # DW_AT_ranges + .byte 1 # DW_AT_frame_base + .byte 86 + .long 74 # DW_AT_abstract_origin + .byte 3 # Abbrev [3] 0x24:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long 84 # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x2d:0x1d DW_TAG_subprogram + .byte 3 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long 97 # DW_AT_abstract_origin + .byte 3 # Abbrev [3] 0x39:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long 107 # DW_AT_abstract_origin + .byte 5 # Abbrev [5] 0x41:0x8 DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .long 115 # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0x4a:0x13 DW_TAG_subprogram + .byte 0 # DW_AT_linkage_name + .byte 1 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 93 # DW_AT_type + # DW_AT_external + .byte 1 # DW_AT_inline + .byte 7 # Abbrev [7] 0x54:0x8 DW_TAG_formal_parameter + .byte 3 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 93 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 8 # Abbrev [8] 0x5d:0x4 DW_TAG_base_type + .byte 2 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 6 # Abbrev [6] 0x61:0x1b DW_TAG_subprogram + .byte 4 # DW_AT_linkage_name + .byte 5 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 93 # DW_AT_type + # DW_AT_external + .byte 1 # DW_AT_inline + .byte 7 # Abbrev [7] 0x6b:0x8 DW_TAG_formal_parameter + .byte 3 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 93 # DW_AT_type + .byte 9 # Abbrev [9] 0x73:0x8 DW_TAG_variable + .byte 6 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 9 # DW_AT_decl_line + .long 93 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 10 # Abbrev [10] 0x7c:0x59 DW_TAG_subprogram + .long .Ldebug_ranges1-.debug_ranges # DW_AT_ranges + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 7 # DW_AT_linkage_name + .byte 8 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 14 # DW_AT_decl_line + .long 93 # DW_AT_type + # DW_AT_external + .byte 11 # Abbrev [11] 0x8b:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 112 + .byte 9 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 14 # DW_AT_decl_line + .long 93 # DW_AT_type + .byte 11 # Abbrev [11] 0x96:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 104 + .byte 10 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 14 # DW_AT_decl_line + .long 213 # DW_AT_type + .byte 12 # Abbrev [12] 0xa1:0x15 DW_TAG_inlined_subroutine + .long 74 # DW_AT_abstract_origin + .long .Ldebug_ranges2-.debug_ranges # DW_AT_ranges + .byte 1 # DW_AT_call_file + .byte 15 # DW_AT_call_line + .byte 14 # DW_AT_call_column + .byte 3 # Abbrev [3] 0xad:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 116 + .long 84 # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 13 # Abbrev [13] 0xb6:0x1e DW_TAG_inlined_subroutine + .long 97 # DW_AT_abstract_origin + .byte 7 # DW_AT_low_pc + .long .Ltmp8-.Ltmp7 # DW_AT_high_pc + .byte 1 # DW_AT_call_file + .byte 15 # DW_AT_call_line + .byte 35 # DW_AT_call_column + .byte 3 # Abbrev [3] 0xc3:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long 107 # DW_AT_abstract_origin + .byte 5 # Abbrev [5] 0xcb:0x8 DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .long 115 # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 14 # Abbrev [14] 0xd5:0x5 DW_TAG_pointer_type + .long 218 # DW_AT_type + .byte 14 # Abbrev [14] 0xda:0x5 DW_TAG_pointer_type + .long 223 # DW_AT_type + .byte 15 # Abbrev [15] 0xdf:0x5 DW_TAG_const_type + .long 228 # DW_AT_type + .byte 8 # Abbrev [8] 0xe4:0x4 DW_TAG_base_type + .byte 11 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_dwo_end0: + .section .debug_abbrev.dwo,"e",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .ascii "\260B" # DW_AT_GNU_dwo_name + .ascii "\202>" # DW_FORM_GNU_str_index + .ascii "\261B" # DW_AT_GNU_dwo_id + .byte 7 # DW_FORM_data8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .ascii "\201>" # DW_FORM_GNU_addr_index + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 110 # DW_AT_linkage_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 32 # DW_AT_inline + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 11 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 12 # Abbreviation Code + .byte 29 # DW_TAG_inlined_subroutine + .byte 1 # DW_CHILDREN_yes + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .byte 88 # DW_AT_call_file + .byte 11 # DW_FORM_data1 + .byte 89 # DW_AT_call_line + .byte 11 # DW_FORM_data1 + .byte 87 # DW_AT_call_column + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 13 # Abbreviation Code + .byte 29 # DW_TAG_inlined_subroutine + .byte 1 # DW_CHILDREN_yes + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 17 # DW_AT_low_pc + .ascii "\201>" # DW_FORM_GNU_addr_index + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 88 # DW_AT_call_file + .byte 11 # DW_FORM_data1 + .byte 89 # DW_AT_call_line + .byte 11 # DW_FORM_data1 + .byte 87 # DW_AT_call_column + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 14 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 15 # Abbreviation Code + .byte 38 # DW_TAG_const_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_addr,"",@progbits +.Laddr_table_base0: + .quad _Z12doStuffOtheri.__part.1 + .quad _Z12doStuffOtheri.__part.2 + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 + .quad _Z9mainOtheriPPKc.__part.1 + .quad _Z9mainOtheriPPKc.__part.2 + .quad .Lfunc_begin2 + .quad .Ltmp7 + .section .debug_gnu_pubnames,"",@progbits + .long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info +.LpubNames_start0: + .short 2 # DWARF Version + .long .Lcu_begin0 # Offset of Compilation Unit Info + .long 52 # Compilation Unit Length + .long 74 # DIE offset + .byte 48 # Attributes: FUNCTION, EXTERNAL + .asciz "doStuffOther" # External Name + .long 97 # DIE offset + .byte 48 # Attributes: FUNCTION, EXTERNAL + .asciz "doStuffOther2" # External Name + .long 124 # DIE offset + .byte 48 # Attributes: FUNCTION, EXTERNAL + .asciz "mainOther" # External Name + .long 0 # End Mark +.LpubNames_end0: + .section .debug_gnu_pubtypes,"",@progbits + .long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info +.LpubTypes_start0: + .short 2 # DWARF Version + .long .Lcu_begin0 # Offset of Compilation Unit Info + .long 52 # Compilation Unit Length + .long 93 # DIE offset + .byte 144 # Attributes: TYPE, STATIC + .asciz "int" # External Name + .long 228 # DIE offset + .byte 144 # Attributes: TYPE, STATIC + .asciz "char" # External Name + .long 0 # End Mark +.LpubTypes_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git df542e1ed82bd4e5a9e345d3a3ae63a76893a0cf)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/dwarf4-df-input-lowpc-ranges-cus.test b/bolt/test/X86/dwarf4-df-input-lowpc-ranges-cus.test new file mode 100644 index 000000000000..c9abd02bbb7d --- /dev/null +++ b/bolt/test/X86/dwarf4-df-input-lowpc-ranges-cus.test @@ -0,0 +1,97 @@ +; RUN: rm -rf %t +; RUN: mkdir %t +; RUN: cd %t +; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-input-lowpc-ranges-main.s \ +; RUN: -split-dwarf-file=main.dwo -o main.o +; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-input-lowpc-ranges-other.s \ +; RUN: -split-dwarf-file=mainOther.dwo -o other.o +; RUN: %clang %cflags -gdwarf-4 -gsplit-dwarf=split main.o other.o -o main.exe +; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections +; RUN: llvm-dwarfdump --show-form --verbose --debug-ranges main.exe.bolt &> %t/foo.txt +; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt >> %t/foo.txt +; RUN: cat %t/foo.txt | FileCheck -check-prefix=BOLT %s +; RUN: not llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo mainOther.dwo.dwo &> %t/mainddwodwo.txt +; RUN: cat %t/mainddwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s + +;; Tests that BOLT correctly handles Skeleton CU which has DW_AT_low_pc/DW_AT_ranges as input and handles multiple CUs with ranges. + +; BOLT: .debug_ranges +; BOLT-NEXT: 00000000 +; BOLT-NEXT: 00000010 +; BOLT-NEXT: 00000010 +; BOLT-NEXT: 00000010 +; BOLT-NEXT: 00000010 +; BOLT-NEXT: 00000050 +; BOLT-NEXT: 00000050 +; BOLT-NEXT: 00000050 +; BOLT-NEXT: 00000050 +; BOLT-NEXT: 00000090 [[#%.16x,ADDR1:]] [[#%.16x,ADDRB1:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR2:]] [[#%.16x,ADDRB2:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR3:]] [[#%.16x,ADDRB3:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR4:]] [[#%.16x,ADDRB4:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR5:]] [[#%.16x,ADDRB5:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR6:]] [[#%.16x,ADDRB6:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR7:]] [[#%.16x,ADDRB7:]] +; BOLT-NEXT: 00000090 +; BOLT-NEXT: 00000110 +; BOLT-NEXT: 00000110 +; BOLT-NEXT: 00000110 +; BOLT-NEXT: 00000110 +; BOLT-NEXT: 00000150 +; BOLT-NEXT: 00000150 +; BOLT-NEXT: 00000150 +; BOLT-NEXT: 00000150 +; BOLT-NEXT: 00000190 [[#%.16x,ADDR8:]] [[#%.16x,ADDRB8:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR9:]] [[#%.16x,ADDRB9:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR10:]] [[#%.16x,ADDRB10:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR11:]] [[#%.16x,ADDRB11:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR12:]] [[#%.16x,ADDRB12:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR13:]] [[#%.16x,ADDRB13:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR14:]] [[#%.16x,ADDRB14:]] +; BOLT-NEXT: 00000190 + +; BOLT: DW_TAG_compile_unit +; BOLT: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x{{[0-9a-fA-F]+}}] = "main.dwo.dwo") +; BOLT-NEXT: DW_AT_GNU_dwo_id +; BOLT-NEXT: DW_AT_GNU_ranges_base [DW_FORM_sec_offset] (0x00000010) +; BOLT-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000) +; BOLT-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000090 +; BOLT-NEXT: [0x[[#ADDR1]], 0x[[#ADDRB1]]) +; BOLT-NEXT: [0x[[#ADDR2]], 0x[[#ADDRB2]]) +; BOLT-NEXT: [0x[[#ADDR3]], 0x[[#ADDRB3]]) +; BOLT-NEXT: [0x[[#ADDR4]], 0x[[#ADDRB4]]) +; BOLT-NEXT: [0x[[#ADDR5]], 0x[[#ADDRB5]]) +; BOLT-NEXT: [0x[[#ADDR6]], 0x[[#ADDRB6]]) +; BOLT-NEXT: [0x[[#ADDR7]], 0x[[#ADDRB7]]) +; BOLT-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000000) + +; BOLT: DW_TAG_compile_unit +; BOLT: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x{{[0-9a-fA-F]+}}] = "mainOther.dwo.dwo") +; BOLT-NEXT: DW_AT_GNU_dwo_id +; BOLT-NEXT: DW_AT_GNU_ranges_base [DW_FORM_sec_offset] (0x00000110) +; BOLT-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000) +; BOLT-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000190 +; BOLT-NEXT: [0x[[#ADDR8]], 0x[[#ADDRB8]]) +; BOLT-NEXT: [0x[[#ADDR9]], 0x[[#ADDRB9]]) +; BOLT-NEXT: [0x[[#ADDR10]], 0x[[#ADDRB10]]) +; BOLT-NEXT: [0x[[#ADDR11]], 0x[[#ADDRB11]]) +; BOLT-NEXT: [0x[[#ADDR12]], 0x[[#ADDRB12]]) +; BOLT-NEXT: [0x[[#ADDR13]], 0x[[#ADDRB13]]) +; BOLT-NEXT: [0x[[#ADDR14]], 0x[[#ADDRB14]]) +; BOLT-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000018) + +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000 +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000040 + +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000 +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000040 -- GitLab From 2b1dfd2b35b5684c8af85206e199152bd6ac3a8d Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sat, 1 Jun 2024 16:48:26 +0100 Subject: [PATCH 010/678] [DAG] Replace getValid*ShiftAmountConstant helpers with getValid*ShiftAmount helpers to support KnownBits analysis (#93182) The getValidShiftAmountConstant/getValidMinimumShiftAmountConstant/getValidMaximumShiftAmountConstant helpers only worked with constant shift amounts, which could be problematic after type legalization (e.g. v2i64 might be partially scalarized or split into v4i32 on some targets such as 32-bit x86, Thumb2 MVE). This patch proposes we generalize these helpers to work with ConstantRange+KnownBits if a scalar/buildvector constant isn't available. Most restrictions are the same - the helper fails if any shift amount is out of bounds, getValidShiftConstant must be a specific constant uniform etc. However, getValidMinimumShiftAmount/getValidMaximumShiftAmount now can return bounds values that aren't values in the actual data, as they are based off the common KnownBits of every vector element. This addresses feedback on #92096 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 63 ++++--- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 170 ++++++++++-------- .../CodeGen/SelectionDAG/TargetLowering.cpp | 65 ++++--- llvm/lib/Target/X86/X86ISelLowering.cpp | 2 +- llvm/test/CodeGen/PowerPC/pr44183.ll | 7 +- 5 files changed, 163 insertions(+), 144 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 0dc237301abb..6d28273029bd 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -32,6 +32,7 @@ #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGenTypes/MachineValueType.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Metadata.h" #include "llvm/Support/Allocator.h" @@ -2159,36 +2160,44 @@ public: /// splatted value it will return SDValue(). SDValue getSplatValue(SDValue V, bool LegalTypes = false); - /// If a SHL/SRA/SRL node \p V has a constant or splat constant shift amount + /// If a SHL/SRA/SRL node \p V has shift amounts that are all less than the + /// element bit-width of the shift node, return the valid constant range. + std::optional + getValidShiftAmountRange(SDValue V, const APInt &DemandedElts, + unsigned Depth) const; + + /// If a SHL/SRA/SRL node \p V has a uniform shift amount /// that is less than the element bit-width of the shift node, return it. - const APInt *getValidShiftAmountConstant(SDValue V, - const APInt &DemandedElts) const; + std::optional getValidShiftAmount(SDValue V, + const APInt &DemandedElts, + unsigned Depth = 0) const; - /// If a SHL/SRA/SRL node \p V has a constant or splat constant shift amount + /// If a SHL/SRA/SRL node \p V has a uniform shift amount /// that is less than the element bit-width of the shift node, return it. - const APInt *getValidShiftAmountConstant(SDValue V) const; - - /// If a SHL/SRA/SRL node \p V has constant shift amounts that are all less - /// than the element bit-width of the shift node, return the minimum value. - const APInt * - getValidMinimumShiftAmountConstant(SDValue V, - const APInt &DemandedElts) const; - - /// If a SHL/SRA/SRL node \p V has constant shift amounts that are all less - /// than the element bit-width of the shift node, return the minimum value. - const APInt * - getValidMinimumShiftAmountConstant(SDValue V) const; - - /// If a SHL/SRA/SRL node \p V has constant shift amounts that are all less - /// than the element bit-width of the shift node, return the maximum value. - const APInt * - getValidMaximumShiftAmountConstant(SDValue V, - const APInt &DemandedElts) const; - - /// If a SHL/SRA/SRL node \p V has constant shift amounts that are all less - /// than the element bit-width of the shift node, return the maximum value. - const APInt * - getValidMaximumShiftAmountConstant(SDValue V) const; + std::optional getValidShiftAmount(SDValue V, + unsigned Depth = 0) const; + + /// If a SHL/SRA/SRL node \p V has shift amounts that are all less than the + /// element bit-width of the shift node, return the minimum possible value. + std::optional getValidMinimumShiftAmount(SDValue V, + const APInt &DemandedElts, + unsigned Depth = 0) const; + + /// If a SHL/SRA/SRL node \p V has shift amounts that are all less than the + /// element bit-width of the shift node, return the minimum possible value. + std::optional getValidMinimumShiftAmount(SDValue V, + unsigned Depth = 0) const; + + /// If a SHL/SRA/SRL node \p V has shift amounts that are all less than the + /// element bit-width of the shift node, return the maximum possible value. + std::optional getValidMaximumShiftAmount(SDValue V, + const APInt &DemandedElts, + unsigned Depth = 0) const; + + /// If a SHL/SRA/SRL node \p V has shift amounts that are all less than the + /// element bit-width of the shift node, return the maximum possible value. + std::optional getValidMaximumShiftAmount(SDValue V, + unsigned Depth = 0) const; /// Match a binop + shuffle pyramid that represents a horizontal reduction /// over the elements of a vector starting from the EXTRACT_VECTOR_ELT node /p diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index b05649c6ce95..0ea33c1c699b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -48,7 +48,6 @@ #include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGenTypes/MachineValueType.h" #include "llvm/IR/Constant.h" -#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugInfoMetadata.h" @@ -3009,102 +3008,117 @@ SDValue SelectionDAG::getSplatValue(SDValue V, bool LegalTypes) { return SDValue(); } -const APInt * -SelectionDAG::getValidShiftAmountConstant(SDValue V, - const APInt &DemandedElts) const { +std::optional +SelectionDAG::getValidShiftAmountRange(SDValue V, const APInt &DemandedElts, + unsigned Depth) const { assert((V.getOpcode() == ISD::SHL || V.getOpcode() == ISD::SRL || V.getOpcode() == ISD::SRA) && "Unknown shift node"); + // Shifting more than the bitwidth is not valid. unsigned BitWidth = V.getScalarValueSizeInBits(); - if (ConstantSDNode *SA = isConstOrConstSplat(V.getOperand(1), DemandedElts)) { - // Shifting more than the bitwidth is not valid. - const APInt &ShAmt = SA->getAPIntValue(); - if (ShAmt.ult(BitWidth)) - return &ShAmt; + + if (auto *Cst = dyn_cast(V.getOperand(1))) { + const APInt &ShAmt = Cst->getAPIntValue(); + if (ShAmt.uge(BitWidth)) + return std::nullopt; + return ConstantRange(ShAmt); } - return nullptr; + + if (auto *BV = dyn_cast(V.getOperand(1))) { + const APInt *MinAmt = nullptr, *MaxAmt = nullptr; + for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) { + if (!DemandedElts[i]) + continue; + auto *SA = dyn_cast(BV->getOperand(i)); + if (!SA) { + MinAmt = MaxAmt = nullptr; + break; + } + const APInt &ShAmt = SA->getAPIntValue(); + if (ShAmt.uge(BitWidth)) + return std::nullopt; + if (!MinAmt || MinAmt->ugt(ShAmt)) + MinAmt = &ShAmt; + if (!MaxAmt || MaxAmt->ult(ShAmt)) + MaxAmt = &ShAmt; + } + assert(((!MinAmt && !MaxAmt) || (MinAmt && MaxAmt)) && + "Failed to find matching min/max shift amounts"); + if (MinAmt && MaxAmt) + return ConstantRange(*MinAmt, *MaxAmt + 1); + } + + // Use computeKnownBits to find a hidden constant/knownbits (usually type + // legalized). e.g. Hidden behind multiple bitcasts/build_vector/casts etc. + KnownBits KnownAmt = computeKnownBits(V.getOperand(1), DemandedElts, Depth); + if (KnownAmt.getMaxValue().ult(BitWidth)) + return ConstantRange::fromKnownBits(KnownAmt, /*IsSigned=*/false); + + return std::nullopt; } -const APInt *SelectionDAG::getValidShiftAmountConstant(SDValue V) const { +std::optional +SelectionDAG::getValidShiftAmount(SDValue V, const APInt &DemandedElts, + unsigned Depth) const { + assert((V.getOpcode() == ISD::SHL || V.getOpcode() == ISD::SRL || + V.getOpcode() == ISD::SRA) && + "Unknown shift node"); + if (std::optional AmtRange = + getValidShiftAmountRange(V, DemandedElts, Depth)) + if (const APInt *ShAmt = AmtRange->getSingleElement()) + return ShAmt->getZExtValue(); + return std::nullopt; +} + +std::optional +SelectionDAG::getValidShiftAmount(SDValue V, unsigned Depth) const { EVT VT = V.getValueType(); APInt DemandedElts = VT.isFixedLengthVector() ? APInt::getAllOnes(VT.getVectorNumElements()) : APInt(1, 1); - return getValidShiftAmountConstant(V, DemandedElts); + return getValidShiftAmount(V, DemandedElts, Depth); } -const APInt *SelectionDAG::getValidMinimumShiftAmountConstant( - SDValue V, const APInt &DemandedElts) const { +std::optional +SelectionDAG::getValidMinimumShiftAmount(SDValue V, const APInt &DemandedElts, + unsigned Depth) const { assert((V.getOpcode() == ISD::SHL || V.getOpcode() == ISD::SRL || V.getOpcode() == ISD::SRA) && "Unknown shift node"); - if (const APInt *ValidAmt = getValidShiftAmountConstant(V, DemandedElts)) - return ValidAmt; - unsigned BitWidth = V.getScalarValueSizeInBits(); - auto *BV = dyn_cast(V.getOperand(1)); - if (!BV) - return nullptr; - const APInt *MinShAmt = nullptr; - for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) { - if (!DemandedElts[i]) - continue; - auto *SA = dyn_cast(BV->getOperand(i)); - if (!SA) - return nullptr; - // Shifting more than the bitwidth is not valid. - const APInt &ShAmt = SA->getAPIntValue(); - if (ShAmt.uge(BitWidth)) - return nullptr; - if (MinShAmt && MinShAmt->ule(ShAmt)) - continue; - MinShAmt = &ShAmt; - } - return MinShAmt; + if (std::optional AmtRange = + getValidShiftAmountRange(V, DemandedElts, Depth)) + return AmtRange->getUnsignedMin().getZExtValue(); + return std::nullopt; } -const APInt *SelectionDAG::getValidMinimumShiftAmountConstant(SDValue V) const { +std::optional +SelectionDAG::getValidMinimumShiftAmount(SDValue V, unsigned Depth) const { EVT VT = V.getValueType(); APInt DemandedElts = VT.isFixedLengthVector() ? APInt::getAllOnes(VT.getVectorNumElements()) : APInt(1, 1); - return getValidMinimumShiftAmountConstant(V, DemandedElts); + return getValidMinimumShiftAmount(V, DemandedElts, Depth); } -const APInt *SelectionDAG::getValidMaximumShiftAmountConstant( - SDValue V, const APInt &DemandedElts) const { +std::optional +SelectionDAG::getValidMaximumShiftAmount(SDValue V, const APInt &DemandedElts, + unsigned Depth) const { assert((V.getOpcode() == ISD::SHL || V.getOpcode() == ISD::SRL || V.getOpcode() == ISD::SRA) && "Unknown shift node"); - if (const APInt *ValidAmt = getValidShiftAmountConstant(V, DemandedElts)) - return ValidAmt; - unsigned BitWidth = V.getScalarValueSizeInBits(); - auto *BV = dyn_cast(V.getOperand(1)); - if (!BV) - return nullptr; - const APInt *MaxShAmt = nullptr; - for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) { - if (!DemandedElts[i]) - continue; - auto *SA = dyn_cast(BV->getOperand(i)); - if (!SA) - return nullptr; - // Shifting more than the bitwidth is not valid. - const APInt &ShAmt = SA->getAPIntValue(); - if (ShAmt.uge(BitWidth)) - return nullptr; - if (MaxShAmt && MaxShAmt->uge(ShAmt)) - continue; - MaxShAmt = &ShAmt; - } - return MaxShAmt; + if (std::optional AmtRange = + getValidShiftAmountRange(V, DemandedElts, Depth)) + return AmtRange->getUnsignedMax().getZExtValue(); + return std::nullopt; } -const APInt *SelectionDAG::getValidMaximumShiftAmountConstant(SDValue V) const { +std::optional +SelectionDAG::getValidMaximumShiftAmount(SDValue V, unsigned Depth) const { EVT VT = V.getValueType(); APInt DemandedElts = VT.isFixedLengthVector() ? APInt::getAllOnes(VT.getVectorNumElements()) : APInt(1, 1); - return getValidMaximumShiftAmountConstant(V, DemandedElts); + return getValidMaximumShiftAmount(V, DemandedElts, Depth); } /// Determine which bits of Op are known to be either zero or one and return @@ -3569,9 +3583,9 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts, Known = KnownBits::shl(Known, Known2, NUW, NSW, ShAmtNonZero); // Minimum shift low bits are known zero. - if (const APInt *ShMinAmt = - getValidMinimumShiftAmountConstant(Op, DemandedElts)) - Known.Zero.setLowBits(ShMinAmt->getZExtValue()); + if (std::optional ShMinAmt = + getValidMinimumShiftAmount(Op, DemandedElts, Depth + 1)) + Known.Zero.setLowBits(*ShMinAmt); break; } case ISD::SRL: @@ -3581,9 +3595,9 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts, Op->getFlags().hasExact()); // Minimum shift high bits are known zero. - if (const APInt *ShMinAmt = - getValidMinimumShiftAmountConstant(Op, DemandedElts)) - Known.Zero.setHighBits(ShMinAmt->getZExtValue()); + if (std::optional ShMinAmt = + getValidMinimumShiftAmount(Op, DemandedElts, Depth + 1)) + Known.Zero.setHighBits(*ShMinAmt); break; case ISD::SRA: Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1); @@ -4587,17 +4601,17 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts, case ISD::SRA: Tmp = ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1); // SRA X, C -> adds C sign bits. - if (const APInt *ShAmt = - getValidMinimumShiftAmountConstant(Op, DemandedElts)) - Tmp = std::min(Tmp + ShAmt->getZExtValue(), VTBits); + if (std::optional ShAmt = + getValidMinimumShiftAmount(Op, DemandedElts, Depth + 1)) + Tmp = std::min(Tmp + *ShAmt, VTBits); return Tmp; case ISD::SHL: - if (const APInt *ShAmt = - getValidMaximumShiftAmountConstant(Op, DemandedElts)) { + if (std::optional ShAmt = + getValidMaximumShiftAmount(Op, DemandedElts, Depth + 1)) { // shl destroys sign bits, ensure it doesn't shift out all sign bits. Tmp = ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1); - if (ShAmt->ult(Tmp)) - return Tmp - ShAmt->getZExtValue(); + if (*ShAmt < Tmp) + return Tmp - *ShAmt; } break; case ISD::AND: @@ -5270,7 +5284,7 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts, case ISD::SRL: case ISD::SRA: // If the max shift amount isn't in range, then the shift can create poison. - return !getValidMaximumShiftAmountConstant(Op, DemandedElts); + return !getValidMaximumShiftAmount(Op, DemandedElts, Depth + 1); case ISD::SCALAR_TO_VECTOR: // Check if we demand any upper (undef) elements. diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 623b6343994a..f856c8a51984 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -796,10 +796,10 @@ SDValue TargetLowering::SimplifyMultipleUseDemandedBits( case ISD::SHL: { // If we are only demanding sign bits then we can use the shift source // directly. - if (const APInt *MaxSA = - DAG.getValidMaximumShiftAmountConstant(Op, DemandedElts)) { + if (std::optional MaxSA = + DAG.getValidMaximumShiftAmount(Op, DemandedElts, Depth + 1)) { SDValue Op0 = Op.getOperand(0); - unsigned ShAmt = MaxSA->getZExtValue(); + unsigned ShAmt = *MaxSA; unsigned NumSignBits = DAG.ComputeNumSignBits(Op0, DemandedElts, Depth + 1); unsigned UpperDemandedBits = BitWidth - DemandedBits.countr_zero(); @@ -1736,9 +1736,9 @@ bool TargetLowering::SimplifyDemandedBits( SDValue Op1 = Op.getOperand(1); EVT ShiftVT = Op1.getValueType(); - KnownBits KnownSA = TLO.DAG.computeKnownBits(Op1, DemandedElts, Depth + 1); - if (KnownSA.isConstant() && KnownSA.getConstant().ult(BitWidth)) { - unsigned ShAmt = KnownSA.getConstant().getZExtValue(); + if (std::optional KnownSA = + TLO.DAG.getValidShiftAmount(Op, DemandedElts, Depth + 1)) { + unsigned ShAmt = *KnownSA; if (ShAmt == 0) return TLO.CombineTo(Op, Op0); @@ -1748,10 +1748,9 @@ bool TargetLowering::SimplifyDemandedBits( // TODO - support non-uniform vector amounts. if (Op0.getOpcode() == ISD::SRL) { if (!DemandedBits.intersects(APInt::getLowBitsSet(BitWidth, ShAmt))) { - KnownBits InnerSA = TLO.DAG.computeKnownBits(Op0.getOperand(1), - DemandedElts, Depth + 1); - if (InnerSA.isConstant() && InnerSA.getConstant().ult(BitWidth)) { - unsigned C1 = InnerSA.getConstant().getZExtValue(); + if (std::optional InnerSA = + TLO.DAG.getValidShiftAmount(Op0, DemandedElts, Depth + 2)) { + unsigned C1 = *InnerSA; unsigned Opc = ISD::SHL; int Diff = ShAmt - C1; if (Diff < 0) { @@ -1789,9 +1788,9 @@ bool TargetLowering::SimplifyDemandedBits( // TODO - support non-uniform vector amounts. if (InnerOp.getOpcode() == ISD::SRL && Op0.hasOneUse() && InnerOp.hasOneUse()) { - if (const APInt *SA2 = - TLO.DAG.getValidShiftAmountConstant(InnerOp, DemandedElts)) { - unsigned InnerShAmt = SA2->getZExtValue(); + if (std::optional SA2 = TLO.DAG.getValidShiftAmount( + InnerOp, DemandedElts, Depth + 2)) { + unsigned InnerShAmt = *SA2; if (InnerShAmt < ShAmt && InnerShAmt < InnerBits && DemandedBits.getActiveBits() <= (InnerBits - InnerShAmt + ShAmt) && @@ -1918,9 +1917,9 @@ bool TargetLowering::SimplifyDemandedBits( // If we are only demanding sign bits then we can use the shift source // directly. - if (const APInt *MaxSA = - TLO.DAG.getValidMaximumShiftAmountConstant(Op, DemandedElts)) { - unsigned ShAmt = MaxSA->getZExtValue(); + if (std::optional MaxSA = + TLO.DAG.getValidMaximumShiftAmount(Op, DemandedElts, Depth + 1)) { + unsigned ShAmt = *MaxSA; unsigned NumSignBits = TLO.DAG.ComputeNumSignBits(Op0, DemandedElts, Depth + 1); unsigned UpperDemandedBits = BitWidth - DemandedBits.countr_zero(); @@ -1934,9 +1933,9 @@ bool TargetLowering::SimplifyDemandedBits( SDValue Op1 = Op.getOperand(1); EVT ShiftVT = Op1.getValueType(); - KnownBits KnownSA = TLO.DAG.computeKnownBits(Op1, DemandedElts, Depth + 1); - if (KnownSA.isConstant() && KnownSA.getConstant().ult(BitWidth)) { - unsigned ShAmt = KnownSA.getConstant().getZExtValue(); + if (std::optional KnownSA = + TLO.DAG.getValidShiftAmount(Op, DemandedElts, Depth + 1)) { + unsigned ShAmt = *KnownSA; if (ShAmt == 0) return TLO.CombineTo(Op, Op0); @@ -1946,10 +1945,9 @@ bool TargetLowering::SimplifyDemandedBits( // TODO - support non-uniform vector amounts. if (Op0.getOpcode() == ISD::SHL) { if (!DemandedBits.intersects(APInt::getHighBitsSet(BitWidth, ShAmt))) { - KnownBits InnerSA = TLO.DAG.computeKnownBits(Op0.getOperand(1), - DemandedElts, Depth + 1); - if (InnerSA.isConstant() && InnerSA.getConstant().ult(BitWidth)) { - unsigned C1 = InnerSA.getConstant().getZExtValue(); + if (std::optional InnerSA = + TLO.DAG.getValidShiftAmount(Op0, DemandedElts, Depth + 2)) { + unsigned C1 = *InnerSA; unsigned Opc = ISD::SRL; int Diff = ShAmt - C1; if (Diff < 0) { @@ -2042,25 +2040,24 @@ bool TargetLowering::SimplifyDemandedBits( if (DemandedBits.isOne()) return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, VT, Op0, Op1)); - KnownBits KnownSA = TLO.DAG.computeKnownBits(Op1, DemandedElts, Depth + 1); - if (KnownSA.isConstant() && KnownSA.getConstant().ult(BitWidth)) { - unsigned ShAmt = KnownSA.getConstant().getZExtValue(); + if (std::optional KnownSA = + TLO.DAG.getValidShiftAmount(Op, DemandedElts, Depth + 1)) { + unsigned ShAmt = *KnownSA; if (ShAmt == 0) return TLO.CombineTo(Op, Op0); // fold (sra (shl x, c1), c1) -> sext_inreg for some c1 and target // supports sext_inreg. if (Op0.getOpcode() == ISD::SHL) { - KnownBits InnerSA = TLO.DAG.computeKnownBits(Op0.getOperand(1), - DemandedElts, Depth + 1); - if (InnerSA.isConstant() && InnerSA.getConstant().ult(BitWidth)) { + if (std::optional InnerSA = + TLO.DAG.getValidShiftAmount(Op0, DemandedElts, Depth + 2)) { unsigned LowBits = BitWidth - ShAmt; EVT ExtVT = EVT::getIntegerVT(*TLO.DAG.getContext(), LowBits); if (VT.isVector()) ExtVT = EVT::getVectorVT(*TLO.DAG.getContext(), ExtVT, VT.getVectorElementCount()); - if (InnerSA.getConstant() == ShAmt) { + if (*InnerSA == ShAmt) { if (!TLO.LegalOperations() || getOperationAction(ISD::SIGN_EXTEND_INREG, ExtVT) == Legal) return TLO.CombineTo( @@ -2598,11 +2595,11 @@ bool TargetLowering::SimplifyDemandedBits( break; if (Src.getNode()->hasOneUse()) { - const APInt *ShAmtC = - TLO.DAG.getValidShiftAmountConstant(Src, DemandedElts); - if (!ShAmtC || ShAmtC->uge(BitWidth)) + std::optional ShAmtC = + TLO.DAG.getValidShiftAmount(Src, DemandedElts, Depth + 2); + if (!ShAmtC || *ShAmtC >= BitWidth) break; - uint64_t ShVal = ShAmtC->getZExtValue(); + uint64_t ShVal = *ShAmtC; APInt HighBits = APInt::getHighBitsSet(OperandBitWidth, OperandBitWidth - BitWidth); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 7b9e6c0a0027..0e377dd53b74 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -20519,7 +20519,7 @@ static SDValue matchTruncateWithPACK(unsigned &PackOpcode, EVT DstVT, // the truncation then we can use PACKSS by converting the srl to a sra. // SimplifyDemandedBits often relaxes sra to srl so we need to reverse it. if (In.getOpcode() == ISD::SRL && In->hasOneUse()) - if (const APInt *ShAmt = DAG.getValidShiftAmountConstant(In)) { + if (std::optional ShAmt = DAG.getValidShiftAmount(In)) { if (*ShAmt == MinSignBits) { PackOpcode = X86ISD::PACKSS; return DAG.getNode(ISD::SRA, DL, SrcVT, In->ops()); diff --git a/llvm/test/CodeGen/PowerPC/pr44183.ll b/llvm/test/CodeGen/PowerPC/pr44183.ll index 4d2c81c35b7f..dc3e12992297 100644 --- a/llvm/test/CodeGen/PowerPC/pr44183.ll +++ b/llvm/test/CodeGen/PowerPC/pr44183.ll @@ -12,13 +12,12 @@ define void @_ZN1m1nEv(ptr %this) local_unnamed_addr nounwind align 2 { ; CHECK-NEXT: mflr r0 ; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill ; CHECK-NEXT: stdu r1, -48(r1) -; CHECK-NEXT: std r0, 64(r1) ; CHECK-NEXT: mr r30, r3 -; CHECK-NEXT: ld r3, 8(r3) +; CHECK-NEXT: std r0, 64(r1) +; CHECK-NEXT: lwz r3, 8(r3) ; CHECK-NEXT: lwz r4, 36(r30) -; CHECK-NEXT: rldicl r3, r3, 60, 4 +; CHECK-NEXT: rlwinm r3, r3, 27, 0, 0 ; CHECK-NEXT: clrlwi r4, r4, 31 -; CHECK-NEXT: slwi r3, r3, 31 ; CHECK-NEXT: rlwimi r4, r3, 0, 0, 0 ; CHECK-NEXT: bl _ZN1llsE1d ; CHECK-NEXT: nop -- GitLab From 86bb5c8427346aafaafa42fbf96e405ae4ca07bf Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sat, 1 Jun 2024 11:52:55 -0400 Subject: [PATCH 011/678] Create annotations to better explain restarter decision --- .github/workflows/restart-preempted-libcxx-jobs.yaml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/restart-preempted-libcxx-jobs.yaml b/.github/workflows/restart-preempted-libcxx-jobs.yaml index 71e27ff2abb9..5f41c8446921 100644 --- a/.github/workflows/restart-preempted-libcxx-jobs.yaml +++ b/.github/workflows/restart-preempted-libcxx-jobs.yaml @@ -35,6 +35,9 @@ jobs: const failure_regex = /Process completed with exit code 1./ const preemption_regex = /The runner has received a shutdown signal/ + const wf_run = context.payload.workflow_run + core.notice(`Running on "${wf_run.display_title}" by @${wf_run.actor.login} (event: ${wf_run.event})\nWorkflow run URL: ${wf_run.html_url}`) + console.log('Listing check runs for suite') const check_suites = await github.rest.checks.listForSuite({ owner: context.repo.owner, @@ -83,19 +86,19 @@ jobs: if (failure_match != null) { // We only want to restart the workflow if all of the failures were due to preemption. // We don't want to restart the workflow if there were other failures. - console.log('Choosing not to rerun workflow because we found a non-preemption failure'); - console.log('Failure message: ' + annotation.message); + core.notice('Choosing not to rerun workflow because we found a non-preemption failure' + + 'Failure message: "' + annotation.message + '"'); return; } } } if (!has_preempted_job) { - console.log('No preempted jobs found. Not restarting workflow.'); + core.notice('No preempted jobs found. Not restarting workflow.'); return; } - console.log("Restarted workflow: " + context.payload.workflow_run.id); + core.notice("Restarted workflow: " + context.payload.workflow_run.id); await github.rest.actions.reRunWorkflowFailedJobs({ owner: context.repo.owner, repo: context.repo.repo, -- GitLab From e9057c30a48cb502864063540a43d755dacd3b1c Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sat, 1 Jun 2024 12:22:26 -0400 Subject: [PATCH 012/678] Create check run on workflow run to better display result. In order to make the behavior of the libc++ restarter more visible to users, this change creates a check run on the considered workflow to let users know what action, if any, was taken --- .../restart-preempted-libcxx-jobs.yaml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/restart-preempted-libcxx-jobs.yaml b/.github/workflows/restart-preempted-libcxx-jobs.yaml index 5f41c8446921..77ac48aac63e 100644 --- a/.github/workflows/restart-preempted-libcxx-jobs.yaml +++ b/.github/workflows/restart-preempted-libcxx-jobs.yaml @@ -38,6 +38,27 @@ jobs: const wf_run = context.payload.workflow_run core.notice(`Running on "${wf_run.display_title}" by @${wf_run.actor.login} (event: ${wf_run.event})\nWorkflow run URL: ${wf_run.html_url}`) + + async function create_check_run(conclusion, message) { + // Create a check run on the given workflow run to indicate if + // we are restarting the workflow or not. + if (conclusion != 'success' && conclusion != 'skipped' && conclusion != 'neutral') { + core.setFailed('Invalid conclusion: ' + conclusion) + } + await github.rest.checks.create({ + owner: context.repo.owner, + repo: context.repo.repo, + name: 'Restart Preempted Job', + head_sha: wf_run.head_sha, + status: 'completed', + conclusion: conclusion, + output: { + title: 'Restarted Preempted Job', + summary: message + } + }) + } + console.log('Listing check runs for suite') const check_suites = await github.rest.checks.listForSuite({ owner: context.repo.owner, @@ -88,6 +109,8 @@ jobs: // We don't want to restart the workflow if there were other failures. core.notice('Choosing not to rerun workflow because we found a non-preemption failure' + 'Failure message: "' + annotation.message + '"'); + await create_check_run('skipped', 'Choosing not to rerun workflow because we found a non-preemption failure\n' + + 'Failure message: ' + annotation.message) return; } } @@ -95,6 +118,7 @@ jobs: if (!has_preempted_job) { core.notice('No preempted jobs found. Not restarting workflow.'); + await create_check_run('neutral', 'No preempted jobs found. Not restarting workflow.') return; } @@ -104,5 +128,6 @@ jobs: repo: context.repo.repo, run_id: context.payload.workflow_run.id }) + await create_check_run('success', 'Restarted workflow run due to preempted job') -- GitLab From 661d64bc20d58c4970b378dd3e87ee594d2b4150 Mon Sep 17 00:00:00 2001 From: Alex MacLean Date: Sat, 1 Jun 2024 09:28:56 -0700 Subject: [PATCH 013/678] [NVPTX] disable combine-mad test for newer ptxas (#93919) --- llvm/test/CodeGen/NVPTX/combine-mad.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/NVPTX/combine-mad.ll b/llvm/test/CodeGen/NVPTX/combine-mad.ll index fba389afdca3..0637bc916ea4 100644 --- a/llvm/test/CodeGen/NVPTX/combine-mad.ll +++ b/llvm/test/CodeGen/NVPTX/combine-mad.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc < %s -mtriple=nvptx -mcpu=sm_20 -O1 | FileCheck %s ; RUN: llc < %s -mtriple=nvptx64 -mcpu=sm_20 -O1 | FileCheck %s -; RUN: %if ptxas %{ llc < %s -mtriple=nvptx -mcpu=sm_20 -O1 | %ptxas-verify %} +; RUN: %if ptxas && !ptxas-12.0 %{ llc < %s -mtriple=nvptx -mcpu=sm_20 -O1 | %ptxas-verify %} ; RUN: %if ptxas %{ llc < %s -mtriple=nvptx64 -mcpu=sm_20 -O1 | %ptxas-verify %} define i32 @test1(i32 %n, i32 %m) { -- GitLab From 867c9f67132799d9f422866bc4b8790257118c47 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sat, 1 Jun 2024 12:30:02 -0400 Subject: [PATCH 014/678] Fix permissions on restarter workflow --- .github/workflows/restart-preempted-libcxx-jobs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/restart-preempted-libcxx-jobs.yaml b/.github/workflows/restart-preempted-libcxx-jobs.yaml index 77ac48aac63e..4e96e1048861 100644 --- a/.github/workflows/restart-preempted-libcxx-jobs.yaml +++ b/.github/workflows/restart-preempted-libcxx-jobs.yaml @@ -24,7 +24,7 @@ jobs: name: "Restart Job" permissions: statuses: read - checks: read + checks: write actions: write runs-on: ubuntu-latest steps: -- GitLab From ee8e0f3365c6b27c8a82fafa1dd4af10e16384f5 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 1 Jun 2024 09:32:24 -0700 Subject: [PATCH 015/678] Fix order of include flags for the target & regular include paths. (#93547) The target include directory should always come first, since the regular includes are dependent on it --- libcxx/test/configs/llvm-libc++-android-ndk.cfg.in | 2 +- libcxx/test/configs/llvm-libc++-mingw.cfg.in | 2 +- libcxx/test/configs/llvm-libc++-shared-clangcl.cfg.in | 2 +- libcxx/test/configs/llvm-libc++-shared-gcc.cfg.in | 2 +- libcxx/test/configs/llvm-libc++-shared.cfg.in | 2 +- libcxx/test/configs/llvm-libc++-static-clangcl.cfg.in | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libcxx/test/configs/llvm-libc++-android-ndk.cfg.in b/libcxx/test/configs/llvm-libc++-android-ndk.cfg.in index d5f1cccba3b7..31a07f647165 100644 --- a/libcxx/test/configs/llvm-libc++-android-ndk.cfg.in +++ b/libcxx/test/configs/llvm-libc++-android-ndk.cfg.in @@ -16,7 +16,7 @@ config.substitutions.append(('%{flags}', '--sysroot @CMAKE_SYSROOT@' if '@CMAKE_SYSROOT@' else '' )) -compile_flags = '-nostdinc++ -I %{include-dir} -I %{target-include-dir} -I %{libcxx-dir}/test/support' +compile_flags = '-nostdinc++ -I %{target-include-dir} -I %{include-dir} -I %{libcxx-dir}/test/support' if re.match(r'i686-linux-android(21|22|23)$', config.target_triple): # 32-bit x86 Android has a bug where the stack is sometimes misaligned. # The problem appears limited to versions before Android N (API 24) and only diff --git a/libcxx/test/configs/llvm-libc++-mingw.cfg.in b/libcxx/test/configs/llvm-libc++-mingw.cfg.in index 8a0cc96763a1..650b60c6536a 100644 --- a/libcxx/test/configs/llvm-libc++-mingw.cfg.in +++ b/libcxx/test/configs/llvm-libc++-mingw.cfg.in @@ -5,7 +5,7 @@ lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') config.substitutions.append(('%{flags}', '')) config.substitutions.append(('%{compile_flags}', - '-nostdinc++ -I %{include-dir} -I %{target-include-dir} -I %{libcxx-dir}/test/support' + '-nostdinc++ -I %{target-include-dir} -I %{include-dir} -I %{libcxx-dir}/test/support' )) config.substitutions.append(('%{link_flags}', '-nostdlib++ -L %{lib-dir} -lc++' diff --git a/libcxx/test/configs/llvm-libc++-shared-clangcl.cfg.in b/libcxx/test/configs/llvm-libc++-shared-clangcl.cfg.in index cca88c8151c6..163123fffb75 100644 --- a/libcxx/test/configs/llvm-libc++-shared-clangcl.cfg.in +++ b/libcxx/test/configs/llvm-libc++-shared-clangcl.cfg.in @@ -5,7 +5,7 @@ lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') config.substitutions.append(('%{flags}', '--driver-mode=g++')) config.substitutions.append(('%{compile_flags}', - '-fms-runtime-lib=' + config.fms_runtime_lib + ' -nostdinc++ -I %{include-dir} -I %{target-include-dir} -I %{libcxx-dir}/test/support -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_STDIO_ISO_WIDE_SPECIFIERS -DNOMINMAX' + config.dbg_include + '-fms-runtime-lib=' + config.fms_runtime_lib + ' -nostdinc++ -I %{target-include-dir} -I %{include-dir} -I %{libcxx-dir}/test/support -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_STDIO_ISO_WIDE_SPECIFIERS -DNOMINMAX' + config.dbg_include )) config.substitutions.append(('%{link_flags}', '-nostdlib -L %{lib-dir} -lc++ -l' + config.cxx_lib diff --git a/libcxx/test/configs/llvm-libc++-shared-gcc.cfg.in b/libcxx/test/configs/llvm-libc++-shared-gcc.cfg.in index 7d107c8ffc16..649bd318543a 100644 --- a/libcxx/test/configs/llvm-libc++-shared-gcc.cfg.in +++ b/libcxx/test/configs/llvm-libc++-shared-gcc.cfg.in @@ -6,7 +6,7 @@ lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') config.substitutions.append(('%{flags}', '-pthread')) config.substitutions.append(('%{compile_flags}', - '-nostdinc++ -I %{include-dir} -I %{target-include-dir} -I %{libcxx-dir}/test/support' + '-nostdinc++ -I %{target-include-dir} -I %{include-dir} -I %{libcxx-dir}/test/support' )) config.substitutions.append(('%{link_flags}', '-nostdlib++ -L %{lib-dir} -Wl,-rpath,%{lib-dir} -lc++ -lm' diff --git a/libcxx/test/configs/llvm-libc++-shared.cfg.in b/libcxx/test/configs/llvm-libc++-shared.cfg.in index 5199f64f551b..0c059f0c7ff3 100644 --- a/libcxx/test/configs/llvm-libc++-shared.cfg.in +++ b/libcxx/test/configs/llvm-libc++-shared.cfg.in @@ -7,7 +7,7 @@ config.substitutions.append(('%{flags}', '-pthread' + (' -isysroot {}'.format('@CMAKE_OSX_SYSROOT@') if '@CMAKE_OSX_SYSROOT@' else '') )) config.substitutions.append(('%{compile_flags}', - '-nostdinc++ -I %{include-dir} -I %{target-include-dir} -I %{libcxx-dir}/test/support' + '-nostdinc++ -I %{target-include-dir} -I %{include-dir} -I %{libcxx-dir}/test/support' )) config.substitutions.append(('%{link_flags}', '-nostdlib++ -L %{lib-dir} -Wl,-rpath,%{lib-dir} -lc++' diff --git a/libcxx/test/configs/llvm-libc++-static-clangcl.cfg.in b/libcxx/test/configs/llvm-libc++-static-clangcl.cfg.in index 7c700bff32b9..58ca3f27c713 100644 --- a/libcxx/test/configs/llvm-libc++-static-clangcl.cfg.in +++ b/libcxx/test/configs/llvm-libc++-static-clangcl.cfg.in @@ -5,7 +5,7 @@ lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') config.substitutions.append(('%{flags}', '--driver-mode=g++')) config.substitutions.append(('%{compile_flags}', - '-fms-runtime-lib=' + config.fms_runtime_lib + ' -nostdinc++ -I %{include-dir} -I %{target-include-dir} -I %{libcxx-dir}/test/support -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_STDIO_ISO_WIDE_SPECIFIERS -DNOMINMAX' + config.dbg_include + '-fms-runtime-lib=' + config.fms_runtime_lib + ' -nostdinc++ -I %{target-include-dir} -I %{include-dir} -I %{libcxx-dir}/test/support -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_STDIO_ISO_WIDE_SPECIFIERS -DNOMINMAX' + config.dbg_include )) config.substitutions.append(('%{link_flags}', '-nostdlib -L %{lib-dir} -llibc++ -l' + config.cxx_lib -- GitLab From 8256c593f67018e8d73dce714bedc3f4e6869db9 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sat, 1 Jun 2024 18:15:40 +0100 Subject: [PATCH 016/678] Fix GCC Wparentheses warning. NFC. --- .../Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp index 0f89fa557cd5..31f77be20f34 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp @@ -560,9 +560,9 @@ void applyExtUaddvToUaddlv(MachineInstr &MI, MachineRegisterInfo &MRI, // i32 add(i32 ext i8, i32 ext i8) => i32 ext(i16 add(i16 ext i8, i16 ext i8)) bool matchPushAddSubExt(MachineInstr &MI, MachineRegisterInfo &MRI, Register DstReg, Register SrcReg1, Register SrcReg2) { - assert(MI.getOpcode() == TargetOpcode::G_ADD || - MI.getOpcode() == TargetOpcode::G_SUB && - "Expected a G_ADD or G_SUB instruction\n"); + assert((MI.getOpcode() == TargetOpcode::G_ADD || + MI.getOpcode() == TargetOpcode::G_SUB) && + "Expected a G_ADD or G_SUB instruction\n"); // Deal with vector types only LLT DstTy = MRI.getType(DstReg); -- GitLab From 2a1ea151cccba3de21edb950099a75ca8d3ea604 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sat, 1 Jun 2024 10:36:05 -0700 Subject: [PATCH 017/678] Use StringRef::starts_with (NFC) (#94112) --- lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp | 2 +- lldb/source/Utility/UriParser.cpp | 2 +- llvm/lib/MC/MCExpr.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 5f0684163328..06c827c2543f 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -152,7 +152,7 @@ static bool IsTrivialBasename(const llvm::StringRef &basename) { // because it is significantly more efficient then using the general purpose // regular expression library. size_t idx = 0; - if (basename.size() > 0 && basename[0] == '~') + if (basename.starts_with('~')) idx = 1; if (basename.size() <= idx) diff --git a/lldb/source/Utility/UriParser.cpp b/lldb/source/Utility/UriParser.cpp index 432b046d008b..1932e11acb4c 100644 --- a/lldb/source/Utility/UriParser.cpp +++ b/lldb/source/Utility/UriParser.cpp @@ -47,7 +47,7 @@ std::optional URI::Parse(llvm::StringRef uri) { ((path_pos != std::string::npos) ? path_pos : uri.size()) - host_pos); // Extract hostname - if (!host_port.empty() && host_port[0] == '[') { + if (host_port.starts_with('[')) { // hostname is enclosed with square brackets. pos = host_port.rfind(']'); if (pos == std::string::npos) diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index bbee2a64032a..b065d03651c4 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -76,7 +76,7 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const { // Parenthesize names that start with $ so that they don't look like // absolute names. bool UseParens = MAI && MAI->useParensForDollarSignNames() && !InParens && - !Sym.getName().empty() && Sym.getName()[0] == '$'; + Sym.getName().starts_with('$'); if (UseParens) { OS << '('; -- GitLab From 9e22c7a0ea87228dffcdfd7ab62724f72e0b3e30 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sat, 1 Jun 2024 19:05:11 +0100 Subject: [PATCH 018/678] [DAG] canCreateUndefOrPoison - only compute shift amount knownbits when not poison Since #93182 we can now call computeKnownBits inside getValidMaximumShiftAmount to determine the bounds of the shift amount ensuring that it wasn't poison, meaning if we did freeze the ahift amount, isGuaranteedNotToBeUndefOrPoison would then fail as we can't call computeKnownBits through FREEZE for potentially poison values. I'm still reducing a decent test case but wanted to get the buildbot fix ASAP. --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 0ea33c1c699b..3def51c49f3a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5283,8 +5283,11 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts, case ISD::SHL: case ISD::SRL: case ISD::SRA: - // If the max shift amount isn't in range, then the shift can create poison. - return !getValidMaximumShiftAmount(Op, DemandedElts, Depth + 1); + // If the max shift amount isn't in range, then the shift can + // create poison. + return !isGuaranteedNotToBeUndefOrPoison(Op.getOperand(1), DemandedElts, + Depth + 1) || + !getValidMaximumShiftAmount(Op, DemandedElts, Depth + 1); case ISD::SCALAR_TO_VECTOR: // Check if we demand any upper (undef) elements. -- GitLab From 2b2ce50fe843b5b550806a0ab15b06cd5c405d48 Mon Sep 17 00:00:00 2001 From: Abhishek Varma Date: Sat, 1 Jun 2024 18:23:41 +0000 Subject: [PATCH 019/678] [MLIR][SCF] Add an API to fuse consumer to a producer within scf loop (#88712) This commit adds an API (`tileAndFuseConsumerOfSlice`) to fuse consumer to a producer within scf.for/scf.forall loop. To support this two new methods are added to the `TilingInterface` - `getIterationDomainTileFromOperandTile` - `getTiledImplementationFromOperandTile`. Consumer operations that implement this method can be used to be fused with tiled producer operands in a manner similar to (but essentially the inverse of) the fusion of an untiled producer with a tiled consumer. Note that this only does one `tiled producer` -> `consumer` fusion. This could be called repeatedly for fusing multiple consumers. The current implementation also is conservative in when this kicks in (like single use of the value returned by the inter-tile loops that surround the tiled producer, etc.) These can be relaxed over time. Signed-off-by: Abhishek Varma --------- Signed-off-by: Abhishek Varma Signed-off-by: Abhishek Varma Co-authored-by: cxy --- .../SCF/Transforms/TileUsingInterface.h | 14 + .../Dialect/Tensor/Transforms/Transforms.h | 10 +- .../mlir/Interfaces/TilingInterface.td | 66 ++- .../Linalg/Transforms/TilingInterfaceImpl.cpp | 104 +++-- .../SCF/Transforms/TileUsingInterface.cpp | 408 ++++++++++++++++++ .../Tensor/IR/TensorTilingInterfaceImpl.cpp | 100 +++++ .../SwapExtractSliceWithProducerPatterns.cpp | 23 + .../tile-and-fuse-consumer.mlir | 317 ++++++++++++++ .../TestTilingInterfaceTransformOps.cpp | 53 +++ .../TestTilingInterfaceTransformOps.td | 19 + 10 files changed, 1085 insertions(+), 29 deletions(-) create mode 100644 mlir/test/Interfaces/TilingInterface/tile-and-fuse-consumer.mlir diff --git a/mlir/include/mlir/Dialect/SCF/Transforms/TileUsingInterface.h b/mlir/include/mlir/Dialect/SCF/Transforms/TileUsingInterface.h index 6d567171e185..dac79111af3c 100644 --- a/mlir/include/mlir/Dialect/SCF/Transforms/TileUsingInterface.h +++ b/mlir/include/mlir/Dialect/SCF/Transforms/TileUsingInterface.h @@ -14,6 +14,7 @@ #include "mlir/IR/PatternMatch.h" #include "mlir/Interfaces/LoopLikeInterface.h" #include "mlir/Interfaces/TilingInterface.h" +#include "mlir/Interfaces/ViewLikeInterface.h" #include @@ -239,6 +240,19 @@ tileConsumerAndFuseProducersUsingSCF(RewriterBase &rewriter, TilingInterface consumer, const SCFTileAndFuseOptions &options); +/// Fuse the consumer of the source of `candidateSliceOp` by computing the +/// required slice of the consumer in-place. Note that the method +/// replaces the uses of `candidateSliceOp` with the tiled and fused consumer +/// value but does not delete the slice operation. +struct SCFFuseConsumerOfSliceResult { + OpOperand *origConsumerOperand; // Original untiled consumer's operand. + OpOperand + *tiledAndFusedConsumerOperand; // Tiled and fused consumer's operand. + SmallVector tiledOps; +}; +FailureOr +tileAndFuseConsumerOfSlice(RewriterBase &rewriter, Operation *candidateSliceOp); + /// Method to lower an `op` that implements the `TilingInterface` to /// loops/scalars. FailureOr> diff --git a/mlir/include/mlir/Dialect/Tensor/Transforms/Transforms.h b/mlir/include/mlir/Dialect/Tensor/Transforms/Transforms.h index dd6b0e868256..7dabc266c023 100644 --- a/mlir/include/mlir/Dialect/Tensor/Transforms/Transforms.h +++ b/mlir/include/mlir/Dialect/Tensor/Transforms/Transforms.h @@ -11,6 +11,7 @@ #include "mlir/Dialect/Tensor/IR/Tensor.h" #include "mlir/IR/PatternMatch.h" +#include "mlir/Interfaces/ViewLikeInterface.h" namespace mlir { @@ -22,7 +23,7 @@ namespace tensor { // Patterns //===----------------------------------------------------------------------===// -/// Pattern to swap an `tensor.extract_slice` with its producer when the +/// Method to swap an `tensor.extract_slice` with its producer when the /// producer implements the `TilingInterface`. The pattern itself does not /// provide a mechanism to control where the application happens. With use of /// transform dialect that control is done within the transform dialect. Other @@ -30,6 +31,13 @@ namespace tensor { FailureOr replaceExtractSliceWithTiledProducer( OpBuilder &builder, tensor::ExtractSliceOp sliceOp, OpResult producerOp); +/// Method to swap an `tensor.insert_slice` with its consumer when the +/// consumer implements the `TilingInterface`. +FailureOr +replaceInsertSliceWithTiledConsumer(OpBuilder &builder, + OffsetSizeAndStrideOpInterface sliceOp, + OpOperand &consumerOp); + //===----------------------------------------------------------------------===// // Populate functions. //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Interfaces/TilingInterface.td b/mlir/include/mlir/Interfaces/TilingInterface.td index 14d775d986d2..bc83c81c0086 100644 --- a/mlir/include/mlir/Interfaces/TilingInterface.td +++ b/mlir/include/mlir/Interfaces/TilingInterface.td @@ -63,7 +63,7 @@ def TilingInterface : OpInterface<"TilingInterface"> { The method returns the operation that is the tiled implementation. }], - /*retType=*/"FailureOr", + /*retType=*/"FailureOr<::mlir::TilingResult>", /*methodName=*/"getTiledImplementation", /*args=*/(ins "OpBuilder &":$b, @@ -82,7 +82,7 @@ def TilingInterface : OpInterface<"TilingInterface"> { by the tiled implementation. Expects the same `offsets` and `sizes` as used to obtain the tiled implementation of the operation. }], - /*retType=*/"LogicalResult", + /*retType=*/"::mlir::LogicalResult", /*methodName=*/"getResultTilePosition", /*args=*/(ins "OpBuilder &":$b, @@ -96,6 +96,25 @@ def TilingInterface : OpInterface<"TilingInterface"> { return failure(); }] >, + InterfaceMethod< + /*desc=*/[{ + Method to return the tile of the iteration domain where + values from the given tile of the operand are used. + }], + /*retType=*/"::mlir::LogicalResult", + /*methodName=*/"getIterationDomainTileFromOperandTile", + /*args=*/(ins + "OpBuilder &":$b, + "unsigned":$operandNumber, + "ArrayRef ":$offsets, + "ArrayRef ":$sizes, + "SmallVectorImpl &":$iterDomainOffsets, + "SmallVectorImpl &":$iterDomainSizes), + /*methodBody=*/"", + /*defaultImplementation=*/[{ + return failure(); + }] + >, InterfaceMethod< /*desc=*/[{ Method to generate the code that produces a tile of the result. @@ -119,7 +138,7 @@ def TilingInterface : OpInterface<"TilingInterface"> { iteration space). - `sizes` provides the size of the tile. }], - /*retType=*/"FailureOr", + /*retType=*/"FailureOr<::mlir::TilingResult>", /*methodName=*/"generateResultTileValue", /*args=*/(ins "OpBuilder &":$b, @@ -131,6 +150,45 @@ def TilingInterface : OpInterface<"TilingInterface"> { return failure(); }] >, + InterfaceMethod< + /*desc=*/[{ + Method to generate the tiled implementation of an operation from + operand tile position. + + NOTE: For most operations, this should be a trivial composition of + getIterationDomainTileFromOperandTile and getTiledImplementation. + + Generates the IR that computes the tiled implementation of an + operation from operand tile. The `offsets` and `sizes` + describe the tile of the operand required. This is different from + `getTiledImplementation` which generates the tiled + implementation of the operation given a tile of the + iteration space. This method generates a tiled + implementation of the operation based on the tile of the + operand required. This method enables consumer fusion by using + tile and fuse. The method returns failure if the operation + can't be tiled to generate the operand tile. In practical terms + this implies it cannot be tiled and fused with its producers. + + - `offsets` provides the offset of the tile in the coordinate system + of the original iteration space, i.e., if an iteration space + dimension had non-zero offset, it must be included in the offset + provided here (as opposed to zero-based offset "relative" to the + iteration space). + - `sizes` provides the size of the tile. + }], + /*retType=*/"FailureOr<::mlir::TilingResult>", + /*methodName=*/"getTiledImplementationFromOperandTile", + /*args=*/(ins + "OpBuilder &":$b, + "unsigned":$operandNumber, + "ArrayRef":$offsets, + "ArrayRef":$sizes), + /*methodBody=*/"", + /*defaultImplementation=*/[{ + return failure(); + }] + >, InterfaceMethod< /*desc=*/[{ Generates the scalar implementation of the operation. @@ -142,7 +200,7 @@ def TilingInterface : OpInterface<"TilingInterface"> { transformations are done, this method can be used to lower to scalar code that can then be lowered to LLVM or SPIR-V dialects. }], - /*retType=*/"LogicalResult", + /*retType=*/"::mlir::LogicalResult", /*methodName=*/"generateScalarImplementation", /*args=*/(ins "OpBuilder &":$b, diff --git a/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp b/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp index f512be46cc13..c3ab3cecfada 100644 --- a/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp @@ -110,7 +110,7 @@ struct LinalgOpTilingInterface })); } - // Instantiate the tiled implementation of the operation. + /// Instantiate the tiled implementation of the operation. FailureOr getTiledImplementation(Operation *op, OpBuilder &b, ArrayRef offsets, @@ -132,8 +132,63 @@ struct LinalgOpTilingInterface return TilingResult{{tiledOp}, SmallVector(tiledOp->getResults())}; } - // Return the details of the output tile generated by the tiled - // implementation. + /// Utility to fetch the offsets and sizes when applied as per the indexing + /// map of the linalg op. This helps in fusing the linalg op as a consumer of + /// a given slice op. + void + getMappedOffsetAndSize(LinalgOp linalgOp, OpBuilder &b, AffineMap indexingMap, + ArrayRef offsets, + ArrayRef sizes, + SmallVectorImpl &mappedOffsets, + SmallVectorImpl &mappedSizes) const { + unsigned numLoops = linalgOp.getNumLoops(); + auto tilingInterfaceOp = cast(linalgOp.getOperation()); + mappedOffsets.resize(numLoops); + mappedSizes.resize(numLoops); + if (!indexingMap.isPermutation()) { + SmallVector iterationDomain = + tilingInterfaceOp.getIterationDomain(b); + for (const auto &&[index, value] : llvm::enumerate(iterationDomain)) { + mappedOffsets[index] = value.offset; + mappedSizes[index] = value.size; + } + } + for (const auto &&[index, value] : + llvm::enumerate(indexingMap.getResults())) { + unsigned dimPosition = cast(value).getPosition(); + mappedOffsets[dimPosition] = offsets[index]; + mappedSizes[dimPosition] = sizes[index]; + } + } + + /// Method to return the position of the result tile computed by the tiled + /// operation. + LogicalResult getIterationDomainTileFromOperandTile( + Operation *op, OpBuilder &b, unsigned operandNumber, + ArrayRef offsets, ArrayRef sizes, + SmallVectorImpl &iterDomainOffsets, + SmallVectorImpl &iterDomainSizes) const { + auto linalgOp = cast(op); + + // Check that the indexing map used for the operand is a projected + // permutation. This could be relaxed with a more general approach that can + // map the offsets and sizes from the operand to iteration space tiles + // (filling in full extent for dimensions not used to access the result). + AffineMap indexingMap = + linalgOp.getMatchingIndexingMap(&op->getOpOperand(operandNumber)); + if (!indexingMap.isProjectedPermutation()) { + return op->emitError() + << "unhandled get iter domain position when operand is not " + "accessed using a permuted projection"; + } + + getMappedOffsetAndSize(linalgOp, b, indexingMap, offsets, sizes, + iterDomainOffsets, iterDomainSizes); + return success(); + } + + /// Return the details of the output tile generated by the tiled + /// implementation. LogicalResult getResultTilePosition(Operation *op, OpBuilder &b, unsigned resultNumber, ArrayRef offsets, @@ -177,29 +232,16 @@ struct LinalgOpTilingInterface "unhandled tiled implementation generation when result is not " "accessed using a permuted projection"); } - - auto numLoops = linalgOp.getNumLoops(); + SmallVector mappedOffsets, mappedSizes; + getMappedOffsetAndSize(linalgOp, b, indexingMap, offsets, sizes, + mappedOffsets, mappedSizes); auto tilingInterfaceOp = cast(op); - SmallVector iterationTileOffsets(numLoops), - iterationTileSizes(numLoops); - if (!indexingMap.isPermutation()) { - SmallVector iterationDomain = - tilingInterfaceOp.getIterationDomain(b); - for (const auto &range : llvm::enumerate(iterationDomain)) { - iterationTileOffsets[range.index()] = range.value().offset; - iterationTileSizes[range.index()] = range.value().size; - } - } - for (const auto &resultExpr : llvm::enumerate(indexingMap.getResults())) { - unsigned dimPosition = - cast(resultExpr.value()).getPosition(); - iterationTileOffsets[dimPosition] = offsets[resultExpr.index()]; - iterationTileSizes[dimPosition] = sizes[resultExpr.index()]; - } - FailureOr tilingResult = - tilingInterfaceOp.getTiledImplementation(b, iterationTileOffsets, - iterationTileSizes); + tilingInterfaceOp.getTiledImplementation(b, mappedOffsets, mappedSizes); + + if (failed(tilingResult)) + return failure(); + if (tilingResult->tiledOps.size() != 1) return op->emitOpError("failed to generate tiled implementation"); @@ -208,6 +250,20 @@ struct LinalgOpTilingInterface SmallVector{tilingResult->tiledValues[resultNumber]}}; } + /// Method to generate the tiled implementation of an operation from the tile + /// of the operand. + FailureOr getTiledImplementationFromOperandTile( + Operation *op, OpBuilder &b, unsigned operandNumber, + ArrayRef offsets, ArrayRef sizes) const { + SmallVector mappedOffsets, mappedSizes; + if (failed(getIterationDomainTileFromOperandTile( + op, b, operandNumber, offsets, sizes, mappedOffsets, + mappedSizes))) { + return failure(); + } + return getTiledImplementation(op, b, mappedOffsets, mappedSizes); + } + LogicalResult generateScalarImplementation(Operation *op, OpBuilder &builder, Location loc, ValueRange ivs) const { diff --git a/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp b/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp index a72dafe72517..a54edf5e72e7 100644 --- a/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp +++ b/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp @@ -16,9 +16,11 @@ #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/Arith/Utils/Utils.h" #include "mlir/Dialect/Func/IR/FuncOps.h" +#include "mlir/Dialect/Linalg/IR/Linalg.h" #include "mlir/Dialect/SCF/Utils/Utils.h" #include "mlir/Dialect/Tensor/IR/Tensor.h" #include "mlir/Dialect/Utils/IndexingUtils.h" +#include "mlir/IR/Dominance.h" #include "mlir/IR/Matchers.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Interfaces/DestinationStyleOpInterface.h" @@ -1098,6 +1100,412 @@ mlir::scf::tileConsumerAndFuseProducersUsingSCF( replacements}; } +//===----------------------------------------------------------------------===// +// tileAndFuseConsumerUsingSCF implementation. +//===----------------------------------------------------------------------===// + +/// A utility function that checks whether the only use of the result of a +/// tensor.insert_slice op is in a scf.yield op. +static LogicalResult +checkAssumptionForFusingConsumer(tensor::InsertSliceOp candidateSliceOp) { + Value result = candidateSliceOp.getResult(); + Value::use_range uses = result.getUses(); + if (!llvm::hasSingleElement(uses)) { + LLVM_DEBUG(llvm::dbgs() << "Too many uses of the candidate slice op\n"); + return failure(); + } + OpOperand &operandUse = (*uses.begin()); + Operation *userOp = operandUse.getOwner(); + if (!isa(userOp)) { + LLVM_DEBUG(llvm::dbgs() + << "Expected scf.yield to be the only user, but got -> " + << (*userOp)); + return failure(); + } + if (result.getDefiningOp()->getBlock() != userOp->getBlock()) { + LLVM_DEBUG(llvm::dbgs() << "Expected tensor.insert_slice and scf.yield to " + "be in the same block\n"); + return failure(); + } + return success(); +} + +/// Fetches the OpOperand of the only user (and use) of the value `val` which +/// implements `TilingInterface` and `DestinationStyleOpInterface`. Returns +/// failure otherwise. +static FailureOr getConsumerFromUses(Value val, + Block *containingOpBlock) { + // Step 1. Check that the value has exactly one use. + if (!llvm::hasSingleElement(val.getUses())) + return failure(); + // Step 2. Get uses. + OpOperand &operand = (*val.getUses().begin()); + Operation *consumerOp = operand.getOwner(); + // TODO: We have to init result of consumer before scf.for, use + // DestinationStyleOpInterface to get result shape from init for now. + // Add support for other op such as op has InferTypeOpInterface. + if (!isa(consumerOp) || + !isa(consumerOp)) + return failure(); + if (containingOpBlock != consumerOp->getBlock()) + return failure(); + return &operand; +} + +/// Fetch the untiled consumer of a scf.for's result which is yielded by a +/// tensor.insert_slice. This function makes the following assumptions : +/// 1. tensor.insert_slice has scf.yield as its only user. +/// 2. scf.for's corresponding result has only one use. +static FailureOr +getUntiledConsumerFromSlice(tensor::InsertSliceOp candidateSliceOp) { + if (failed(checkAssumptionForFusingConsumer(candidateSliceOp))) + return failure(); + Value sliceResult = candidateSliceOp.getResult(); + // Step 1. Fetch the corresponding output. + OpOperand &yieldOpOperand = (*sliceResult.getUses().begin()); + unsigned resultNumber = yieldOpOperand.getOperandNumber(); + // Step 2. Check containing op is scf.for. + Operation *containingOp = candidateSliceOp->getParentOp(); + auto forOp = dyn_cast(containingOp); + if (!forOp) + return failure(); + Value resultingValue = forOp->getResult(resultNumber); + + return getConsumerFromUses(resultingValue, containingOp->getBlock()); +} + +/// Fetch the first untiled consumer of a scf.forall's result which is yielded +/// by a tensor.parallel_insert_slice. +static FailureOr +getUntiledConsumerFromSlice(tensor::ParallelInsertSliceOp candidateSliceOp) { + // Step 1. Fetch the corresponding output + Value sliceDest = candidateSliceOp.getDest(); + auto iterArg = dyn_cast(sliceDest); + if (!iterArg) + return failure(); + Operation *containingOp = iterArg.getOwner()->getParentOp(); + if (containingOp != candidateSliceOp->getParentOp()->getParentOp()) + return failure(); + // Step 2. Check that the containing op is scf.forall. + auto forallOp = dyn_cast(containingOp); + if (!forallOp) + return failure(); + Value resultingValue = + forallOp.getTiedOpResult(forallOp.getTiedOpOperand(iterArg)); + + return getConsumerFromUses(resultingValue, containingOp->getBlock()); +} + +/// This utility currently checks whether the loop either :- +/// 1. Yields exactly one result. +/// 2. Has consumer op as its first user and other users to be in the same +/// containing block as that of consumer op's. Currently we clone the loop op +/// right before the consumer op in order to maintain a valid def-use chain. +/// This utility thus helps ensuring that no invalid IR is formed due to the +/// same. +static LogicalResult checkAssumptionForLoop(Operation *loopOp, + Operation *consumerOp) { + // Check if the loop op yields one result. + if (loopOp->getNumResults() == 1) + return success(); + // Check if the consumerOp is the first user of the loopOp and if other users + // are in the same containing block as that of consumer op's. + Block *parentBlock = consumerOp->getBlock(); + for (Operation *userOp : loopOp->getUsers()) { + if (userOp == consumerOp) + continue; + if (parentBlock != userOp->getBlock() || + !consumerOp->isBeforeInBlock(userOp)) + return failure(); + } + return success(); +} + +/// A utility to fetch an untiled consumer of +/// tensor.insert_slice/tensor.parallel_insert_slice. +static FailureOr getUntiledConsumerFromSlice(Operation *sliceOp) { + if (auto insertSlice = dyn_cast(sliceOp)) { + return getUntiledConsumerFromSlice(insertSlice); + } else if (auto parallelInsertSlice = + dyn_cast(sliceOp)) { + return getUntiledConsumerFromSlice(parallelInsertSlice); + } else { + return failure(); + } +} + +/// After fusing consumer into scf.for we want to modify the scf.yield operation +/// to reflect the same by returning the values yielded by the tiled consumer. +static void +fixTerminatorSCFYield(RewriterBase &rewriter, scf::ForOp newForOp, + TilingResult &tilingResult, + ArrayRef> &resultOffsets, + ArrayRef> &resultSizes, + ArrayRef bbArgs) { + scf::YieldOp oldTerminatorOp = + cast(newForOp.getBody()->getTerminator()); + unsigned totalOldResults = oldTerminatorOp->getNumResults(); + unsigned totalTiledResults = tilingResult.tiledOps[0]->getNumResults(); + SmallVector newYieldOperands; + newYieldOperands.reserve(totalOldResults + totalTiledResults); + for (auto oldResult : oldTerminatorOp.getResults()) { + newYieldOperands.push_back(oldResult); + } + rewriter.setInsertionPointAfter(oldTerminatorOp); + Location loc = newForOp.getLoc(); + for (auto [tiledResult, bbArg, resultOffset, resultSize] : + llvm::zip_equal(tilingResult.tiledOps[0]->getResults(), bbArgs, + resultOffsets, resultSizes)) { + SmallVector strides(resultOffset.size(), + rewriter.getIndexAttr(1)); + Value newInsertSliceOp = rewriter.create( + loc, tiledResult, bbArg, resultOffset, resultSize, strides); + newYieldOperands.push_back(newInsertSliceOp); + } + rewriter.create(loc, newYieldOperands); + rewriter.eraseOp(oldTerminatorOp); +} + +/// After fusing consumer into scf.forall we want to yield each of the resulting +/// values by the tiled consumer within scf.forall.in_parallel region. +static void +fixTerminatorSCFInParallel(RewriterBase &rewriter, scf::ForallOp newForallOp, + SmallVector tiledResults, + ArrayRef> &resultOffsets, + ArrayRef> &resultSizes, + ArrayRef bbArgs) { + scf::InParallelOp newTerminatorOp = newForallOp.getTerminator(); + rewriter.setInsertionPointToStart(newTerminatorOp.getBody()); + Location firstYieldOpLoc = + (*(newTerminatorOp.getYieldingOps().begin())).getLoc(); + for (auto [tiledResult, bbArg, resultOffset, resultSize] : + llvm::zip_equal(tiledResults, bbArgs, resultOffsets, resultSizes)) { + SmallVector strides(resultOffset.size(), + rewriter.getIndexAttr(1)); + rewriter.create( + firstYieldOpLoc, tiledResult, bbArg, resultOffset, resultSize, strides); + } +} + +/// Implementation of fusing consumer of a single slice by computing the +/// slice of the consumer in-place for scf loop. +FailureOr +mlir::scf::tileAndFuseConsumerOfSlice(RewriterBase &rewriter, + Operation *candidateSliceOp) { + if (!isa( + candidateSliceOp)) + return failure(); + + bool isInsertSliceOp = isa(candidateSliceOp); + + // 1. Get the consumer of scf.for for the result yielded by + // tensor.insert_slice/parallel_insert_slice. + FailureOr maybeConsumerOpOperand = + getUntiledConsumerFromSlice(candidateSliceOp); + if (failed(maybeConsumerOpOperand)) { + return rewriter.notifyMatchFailure(candidateSliceOp, + "could not fetch consumer to fuse"); + } + OpOperand *consumerOpOperand = *maybeConsumerOpOperand; + Operation *consumerOp = consumerOpOperand->getOwner(); + unsigned operandNumber = consumerOpOperand->getOperandNumber(); + unsigned resultNumber = 0; + if (auto producerResult = dyn_cast(consumerOpOperand->get())) { + resultNumber = producerResult.getResultNumber(); + } else { + return rewriter.notifyMatchFailure( + consumerOp, "consumer op's operand doesn't seem to be an OpResult"); + } + + Operation *oldLoopOp = nullptr; + SmallVector newOuts; + Block *oldLoopBody = nullptr; + unsigned initSize = 0; + unsigned rank = 1; + if (isInsertSliceOp) { + auto forOp = candidateSliceOp->getParentOfType(); + oldLoopOp = forOp; + llvm::append_range(newOuts, forOp.getInits()); + oldLoopBody = forOp.getBody(); + initSize = forOp.getInits().size(); + } else { + auto forallOp = candidateSliceOp->getParentOfType(); + oldLoopOp = forallOp; + llvm::append_range(newOuts, forallOp.getOutputs()); + oldLoopBody = forallOp.getBody(); + initSize = forallOp.getOutputs().size(); + rank = forallOp.getRank(); + } + + if (failed(checkAssumptionForLoop(oldLoopOp, consumerOp))) { + return rewriter.notifyMatchFailure( + oldLoopOp, "containing loop op should either yield just one value or " + "have the consumer op as its first user"); + } + + OpBuilder::InsertionGuard g(rewriter); + + // 2. Check consumer is not using scf loop's output as init. + auto dstOp = cast(consumerOp); + SmallVector dpsInits = + llvm::map_to_vector(dstOp.getDpsInits(), [](Value v) { return v; }); + if (llvm::is_contained(dpsInits, oldLoopOp->getResult(resultNumber))) { + return rewriter.notifyMatchFailure( + consumerOp, + "consumer op taking the result of scf.for as init is not supported"); + } + newOuts.append(dpsInits); + + Location loc = oldLoopOp->getLoc(); + + // 3. Create new scf loop op. + rewriter.setInsertionPoint(consumerOp); + Operation *newLoopOp = nullptr; + Block *newLoopBody = nullptr; + if (isInsertSliceOp) { + auto forOp = cast(oldLoopOp); + auto newForOp = rewriter.create(loc, forOp.getLowerBound(), + forOp.getUpperBound(), + forOp.getStep(), newOuts); + newLoopOp = newForOp; + newLoopBody = newForOp.getBody(); + } else { + auto forallOp = cast(oldLoopOp); + auto newForallOp = rewriter.create( + loc, forallOp.getMixedLowerBound(), forallOp.getMixedUpperBound(), + forallOp.getMixedStep(), newOuts, forallOp.getMapping()); + newLoopOp = newForallOp; + rewriter.eraseOp(newForallOp.getTerminator()); + newLoopBody = newForallOp.getBody(); + } + + // 4. Move the loop body to the new op. + unsigned oldNumArguments = oldLoopBody->getNumArguments(); + rewriter.mergeBlocks(oldLoopBody, newLoopBody, + newLoopBody->getArguments().take_front(oldNumArguments)); + + // 5. Set insertion point before terminator op of the loop and create a new + // tensor.insert_slice. In the scf.for case this is a clone of the + // candidateSliceOp whereas in the scf.forall case this is created from the + // operands of tensor.parallel_insert_slice. + tensor::InsertSliceOp clonedInsertSliceOp; + if (auto sliceOp = + dyn_cast(candidateSliceOp)) { + auto newForallOp = cast(newLoopOp); + rewriter.setInsertionPoint(newForallOp.getTerminator()); + clonedInsertSliceOp = rewriter.create( + loc, sliceOp.getSource(), sliceOp.getDest(), sliceOp.getMixedOffsets(), + sliceOp.getMixedSizes(), sliceOp.getMixedStrides()); + } else { + rewriter.setInsertionPoint(candidateSliceOp); + clonedInsertSliceOp = + cast(rewriter.clone(*candidateSliceOp)); + } + + // 6.a. Clone consumer op. + auto newForOpBlockArgsForConsumerDest = + newLoopBody->getArguments().drop_front(oldNumArguments); + auto clonedConsumerOp = cast(cloneOpAndUpdateDestinationArgs( + rewriter, consumerOp, newForOpBlockArgsForConsumerDest)); + + // 6.b. Replace all uses of the loop result with the result of the cloned + // tensor.insert_slice. + OpOperand &operandToReplace = clonedConsumerOp->getOpOperand(operandNumber); + rewriter.modifyOpInPlace(clonedConsumerOp, [&]() { + operandToReplace.set(clonedInsertSliceOp.getResult()); + }); + + // 7 - Perform tiling of the cloned consumer and replace the operand at + // `operandNumber` with the source of the cloned tensor.insert_slice op. + auto ossSliceOp = + cast(clonedInsertSliceOp.getOperation()); + FailureOr tileAndFuseResult = + tensor::replaceInsertSliceWithTiledConsumer( + rewriter, ossSliceOp, clonedConsumerOp->getOpOperand(operandNumber)); + if (failed(tileAndFuseResult)) { + return failure(); + } + rewriter.replaceAllUsesWith( + tileAndFuseResult->tiledOps[0]->getOperand(operandNumber), + clonedInsertSliceOp.getSource()); + + // 8 - Extract offset/sizes/strides required to create the + // tensor.insert_slice/parallel_insert_slice for each result of the consumer. + SmallVector offsets = ossSliceOp.getMixedOffsets(); + SmallVector sizes = ossSliceOp.getMixedSizes(); + SmallVector strides = ossSliceOp.getMixedStrides(); + + // 9. Check all insert stride is 1. + if (llvm::any_of(strides, [](OpFoldResult stride) { + return !isConstantIntValue(stride, 1); + })) { + return rewriter.notifyMatchFailure( + candidateSliceOp, "containingOp's result yield with stride"); + } + + // 10. Try to get iter domain position from input position. + SmallVector iterDomainOffsets, iterDomainSizes; + if (failed(clonedConsumerOp.getIterationDomainTileFromOperandTile( + rewriter, operandNumber, offsets, sizes, iterDomainOffsets, + iterDomainSizes))) { + return rewriter.notifyMatchFailure( + clonedConsumerOp, "can't get iter domain position from input position"); + } + + // 11. Try to fetch the offset and size for all results of the cloned + // consumer. This would then be used to form the corresponding + // tensor.insert_slice/parallel_insert_slice later. + unsigned totalNumResultsOfConsumer = clonedConsumerOp->getNumResults(); + SmallVector> resultOffsets( + totalNumResultsOfConsumer); + SmallVector> resultSizes(totalNumResultsOfConsumer); + for (auto [idx, v] : llvm::enumerate(clonedConsumerOp->getResults())) { + if (failed(clonedConsumerOp.getResultTilePosition( + rewriter, idx, iterDomainOffsets, iterDomainSizes, + resultOffsets[idx], resultSizes[idx]))) { + return rewriter.notifyMatchFailure( + clonedConsumerOp, + "can't get result domain position from iter domain position"); + } + } + + auto arrayRefOffsets = ArrayRef>(resultOffsets); + auto arrayRefSizes = ArrayRef>(resultSizes); + if (isInsertSliceOp) { + auto newForOp = cast(newLoopOp); + fixTerminatorSCFYield( + rewriter, newForOp, *tileAndFuseResult, arrayRefOffsets, arrayRefSizes, + newForOp.getBody()->getArguments().drop_front(1 + initSize)); + } else { + auto newForallOp = cast(newLoopOp); + fixTerminatorSCFInParallel( + rewriter, newForallOp, tileAndFuseResult->tiledOps[0]->getResults(), + arrayRefOffsets, arrayRefSizes, + newForallOp.getBody()->getArguments().drop_front(rank + initSize)); + } + + // 12. Replace the result of scf loop and consumer op with new loop's results. + for (auto &&[oldResult, newResult] : + llvm::zip_first(oldLoopOp->getResults(), newLoopOp->getResults())) { + rewriter.replaceAllUsesWith(oldResult, newResult); + } + + for (auto &&[oldResult, newResult] : + llvm::zip(consumerOp->getResults(), + newLoopOp->getResults().drop_front(initSize))) { + rewriter.replaceAllUsesWith(oldResult, newResult); + } + + // 13. Need to erase the old scf loop and the cloned consumer op. + rewriter.eraseOp(oldLoopOp); + rewriter.eraseOp(clonedConsumerOp); + + return scf::SCFFuseConsumerOfSliceResult{ + consumerOpOperand, + &(tileAndFuseResult->tiledOps[0]->getOpOperand(operandNumber)), + tileAndFuseResult->tiledOps}; +} + //===----------------------------------------------------------------------===// // lowerToLoopsUsingSCFForOp implementation. //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/Tensor/IR/TensorTilingInterfaceImpl.cpp b/mlir/lib/Dialect/Tensor/IR/TensorTilingInterfaceImpl.cpp index d25efcf50ec5..9b2a97eb2b00 100644 --- a/mlir/lib/Dialect/Tensor/IR/TensorTilingInterfaceImpl.cpp +++ b/mlir/lib/Dialect/Tensor/IR/TensorTilingInterfaceImpl.cpp @@ -469,6 +469,106 @@ struct UnPackOpTiling return failure(); return tilingResult.value(); } + + /// Method to return the position of iteration domain tile computed by the + /// tiled operation. + LogicalResult getIterationDomainTileFromOperandTile( + Operation *op, OpBuilder &b, unsigned operandNumber, + ArrayRef offsets, ArrayRef sizes, + SmallVectorImpl &resultOffsets, + SmallVectorImpl &resultSizes) const { + auto unPackOp = cast(op); + Location loc = unPackOp.getLoc(); + + int64_t numTiles = unPackOp.getInnerDimsPos().size(); + auto destOffsets = offsets.drop_back(numTiles); + auto destSizes = sizes.drop_back(numTiles); + // The tiling is applied on interchanged dimensions. We have to undo the + // interchange to map sizes and offsets to the original input. + int64_t outputRank = unPackOp.getDestRank(); + SmallVector origOffsets(destOffsets.begin(), + destOffsets.end()); + SmallVector origSizes(destSizes.begin(), destSizes.end()); + applyPermToRange(origOffsets, origSizes, + invertPermutationVector(unPackOp.getOuterDimsPerm())); + + DenseMap dimAndTileMapping = + unPackOp.getDimAndTileMapping(); + + for (auto dim : llvm::seq(0, outputRank)) { + using AV = affine::AffineValueExpr; + affine::AffineBuilder ab(b, loc); + AffineExpr dim0, dim1, sym; + bindDims(b.getContext(), dim0, dim1); + bindSymbols(b.getContext(), sym); + if (dimAndTileMapping.count(dim)) { + // If the data dimension is tiled, the i-th index is the product of + // offset_i and tile_i, and the i-th size is the product of sizes_i and + // tile_i. + auto avOffset = AV(dim0).bind(origOffsets[dim]); + auto avSize = AV(dim0).bind(origSizes[dim]); + auto avTileSize = AV(sym).bind(dimAndTileMapping[dim]); + resultOffsets.push_back(ab.mul(avOffset, avTileSize)); + resultSizes.push_back(ab.mul(avSize, avTileSize)); + } else { + resultOffsets.push_back(origOffsets[dim]); + resultSizes.push_back(origSizes[dim]); + } + } + return success(); + } + + /// Method to return the tiled implementation of tensor.unpack as a consumer. + FailureOr getTiledImplementationFromOperandTile( + Operation *op, OpBuilder &b, unsigned operandNumber, + ArrayRef offsets, ArrayRef sizes) const { + auto unPackOp = cast(op); + // tensor.unpack op is fusible (as a consumer) only if inner dims are not + // tiled. + int64_t numTiles = unPackOp.getInnerDimsPos().size(); + for (auto iter : + llvm::zip_equal(unPackOp.getMixedTiles(), sizes.take_back(numTiles))) { + if (!isEqualConstantIntOrValue(std::get<0>(iter), std::get<1>(iter))) + return failure(); + } + + Location loc = unPackOp.getLoc(); + + // Fetch offset/size for creating the slice of the dest operand of + // unpack op. + SmallVector outputOffsets, outputSizes; + if (failed(getIterationDomainTileFromOperandTile( + op, b, /*operandNumber=*/0, offsets, sizes, outputOffsets, + outputSizes))) + return failure(); + + auto oneAttr = b.getI64IntegerAttr(1); + int64_t outputRank = unPackOp.getDestRank(); + SmallVector strides(outputRank, oneAttr); + + SmallVector tiledOperands; + // Create slice of the dest operand. + auto extractDestSlice = b.create( + loc, unPackOp.getDest(), outputOffsets, outputSizes, strides); + tiledOperands.push_back(extractDestSlice); + + SmallVector inputOffsets, inputSizes; + strides.append(unPackOp.getSourceRank() - outputRank, oneAttr); + // Create slice of the source operand. + auto extractSourceSlice = b.create( + loc, unPackOp.getSource(), offsets, sizes, strides); + tiledOperands.insert(tiledOperands.begin(), extractSourceSlice); + for (auto tile : unPackOp.getInnerTiles()) + tiledOperands.push_back(tile); + + // Create tiled unpack op. + Operation *tiledUnPackOp = + b.create(loc, TypeRange{extractDestSlice.getType()}, + tiledOperands, op->getAttrs()); + + return TilingResult{{tiledUnPackOp}, + SmallVector(tiledUnPackOp->getResults())}; + } }; } // namespace diff --git a/mlir/lib/Dialect/Tensor/Transforms/SwapExtractSliceWithProducerPatterns.cpp b/mlir/lib/Dialect/Tensor/Transforms/SwapExtractSliceWithProducerPatterns.cpp index 40d79c205381..858adfc43616 100644 --- a/mlir/lib/Dialect/Tensor/Transforms/SwapExtractSliceWithProducerPatterns.cpp +++ b/mlir/lib/Dialect/Tensor/Transforms/SwapExtractSliceWithProducerPatterns.cpp @@ -40,3 +40,26 @@ FailureOr tensor::replaceExtractSliceWithTiledProducer( return *tiledResult; } + +FailureOr tensor::replaceInsertSliceWithTiledConsumer( + OpBuilder &builder, OffsetSizeAndStrideOpInterface sliceOp, + OpOperand &consumer) { + auto consumerOp = dyn_cast(consumer.getOwner()); + if (!consumerOp) + return failure(); + + // `TilingInterface` currently only supports strides being 1. + if (llvm::any_of(sliceOp.getMixedStrides(), [](OpFoldResult ofr) { + return !isConstantIntValue(ofr, 1); + })) + return failure(); + + FailureOr tiledResult = + consumerOp.getTiledImplementationFromOperandTile( + builder, consumer.getOperandNumber(), sliceOp.getMixedOffsets(), + sliceOp.getMixedSizes()); + if (failed(tiledResult)) + return failure(); + + return *tiledResult; +} diff --git a/mlir/test/Interfaces/TilingInterface/tile-and-fuse-consumer.mlir b/mlir/test/Interfaces/TilingInterface/tile-and-fuse-consumer.mlir new file mode 100644 index 000000000000..400b558e37fc --- /dev/null +++ b/mlir/test/Interfaces/TilingInterface/tile-and-fuse-consumer.mlir @@ -0,0 +1,317 @@ +// RUN: mlir-opt --transform-interpreter --cse --split-input-file %s | FileCheck %s + +#map = affine_map<(d0) -> (d0)> +module { + func.func @fuse_tileable_consumer_scf_for(%arg0: tensor<32xf32>, %arg1: tensor<32xf32>, %arg2: tensor<64xf32>) -> tensor<64xf32> { + %c4 = arith.constant 4 : index + %c64 = arith.constant 64 : index + %c0 = arith.constant 0 : index + %1:2 = scf.for %arg3 = %c0 to %c64 step %c4 iter_args(%arg4 = %arg2, %arg5 = %arg2) -> (tensor<64xf32>, tensor<64xf32>) { + %extracted_slice = tensor.extract_slice %arg4[%arg3] [32] [1] : tensor<64xf32> to tensor<32xf32> + %3 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = ["parallel"]} ins(%arg0, %arg1 : tensor<32xf32>, tensor<32xf32>) outs(%extracted_slice : tensor<32xf32>) { + ^bb0(%in: f32, %in_16: f32, %out: f32): + %13 = arith.mulf %in, %in_16 : f32 + %14 = arith.addf %out, %13 : f32 + linalg.yield %14 : f32 + } -> tensor<32xf32> + %4 = tensor.insert_slice %3 into %arg4[%arg3] [32] [1] : tensor<32xf32> into tensor<64xf32> + scf.yield %arg5, %4 : tensor<64xf32>, tensor<64xf32> + } + %in_operand_2 = tensor.empty() : tensor<64xf32> + %out_operand_3 = tensor.empty() : tensor<64xf32> + %2 = linalg.elemwise_binary {fun = #linalg.binary_fn} ins(%1#1, %in_operand_2 : tensor<64xf32>, tensor<64xf32>) outs(%out_operand_3 : tensor<64xf32>) -> tensor<64xf32> + return %2 : tensor<64xf32> + } +} + +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) { + %yield = transform.structured.match ops{["tensor.insert_slice"]} in %arg1 + : (!transform.any_op) -> !transform.any_op + %a, %b = transform.test.fuse_consumer %yield + : (!transform.any_op) -> (!transform.any_op, !transform.any_op) + transform.yield + } +} +// CHECK: func.func @fuse_tileable_consumer_scf_for( +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]]: tensor<32xf32> +// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]: tensor<32xf32> +// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]+]]: tensor<64xf32>) +// CHECK: %[[C0:.*]] = arith.constant 0 : index +// CHECK: %0 = tensor.empty() : tensor<64xf32> +// CHECK: %[[FINAL_RESULT:.*]]:3 = scf.for %[[IV:.*]] = %[[C0]] +// CHECK-SAME: iter_args(%[[FIRST_OUT_ARG:.*]] = %[[ARG2]], %[[SECOND_OUT_ARG:.*]] = %[[ARG2]], %[[ELEM_OUT_ARG:.*]] = %0) +// CHECK-SAME: { +// CHECK: %[[MAT_OUT_SLICE:.*]] = tensor.extract_slice %[[FIRST_OUT_ARG]][%[[IV]]] [32] [1] +// CHECK: %[[MAT_OUT:.*]] = linalg.generic +// CHECK-SAME: outs(%[[MAT_OUT_SLICE]] : tensor<32xf32>) +// CHECK: %[[INSERT_MAT:.*]] = tensor.insert_slice %[[MAT_OUT]] into %[[FIRST_OUT_ARG]][%[[IV]]] [32] [1] +// CHECK: %[[SLICE_OPERAND2:.*]] = tensor.extract_slice %0[%[[IV]]] [32] [1] +// CHECK: %[[SLICE_OUT:.*]] = tensor.extract_slice %[[ELEM_OUT_ARG]][%[[IV]]] [32] [1] +// CHECK: %[[ELEM_OUT:.*]] = linalg.elemwise_binary {fun = #linalg.binary_fn} +// CHECK-SAME: ins(%[[MAT_OUT]], %[[SLICE_OPERAND2]] : +// CHECK-SAME: outs(%[[SLICE_OUT]] : +// CHECK: %[[INSERT_ELEM:.*]] = tensor.insert_slice %[[ELEM_OUT]] into %[[ELEM_OUT_ARG]][%[[IV]]] [32] [1] +// CHECK: scf.yield %[[SECOND_OUT_ARG]], %[[INSERT_MAT]], %[[INSERT_ELEM]] : +// CHECK: } +// CHECK: return %[[FINAL_RESULT]]#2 : + +// ----- + +module { + func.func @fuse_tileable_consumer_scf_forall(%arg0: tensor<32x32xf32>, %arg1: tensor<32x32xf32>, %arg2: tensor<64x64xf32>) -> tensor<64x64xf32> { + %c4 = arith.constant 4 : index + %c64 = arith.constant 64 : index + %c0 = arith.constant 0 : index + %1:2 = scf.forall (%arg3, %arg4) in (2, 2) shared_outs(%arg5 = %arg2, %arg6 = %arg2) -> (tensor<64x64xf32>, tensor<64x64xf32>) { + %extracted_slice = tensor.extract_slice %arg5[%arg3, %arg4] [32, 32] [1, 1] : tensor<64x64xf32> to tensor<32x32xf32> + %extracted_slice_1 = tensor.extract_slice %arg6[%arg3, %arg4] [32, 32] [1, 1] : tensor<64x64xf32> to tensor<32x32xf32> + %3 = linalg.matmul ins(%arg0, %arg1 : tensor<32x32xf32>, tensor<32x32xf32>) outs(%extracted_slice : tensor<32x32xf32>) -> tensor<32x32xf32> + scf.forall.in_parallel { + tensor.parallel_insert_slice %3 into %arg6[%arg3, %arg4] [32, 32] [1, 1] : tensor<32x32xf32> into tensor<64x64xf32> + tensor.parallel_insert_slice %extracted_slice_1 into %arg5[%arg3, %arg4] [32, 32] [1, 1] : tensor<32x32xf32> into tensor<64x64xf32> + } + } + %in_operand_2 = tensor.empty() : tensor<64x64xf32> + %out_operand_3 = tensor.empty() : tensor<64x64xf32> + %2 = linalg.elemwise_binary {fun = #linalg.binary_fn} ins(%1#1, %in_operand_2 : tensor<64x64xf32>, tensor<64x64xf32>) outs(%out_operand_3 : tensor<64x64xf32>) -> tensor<64x64xf32> + return %2 : tensor<64x64xf32> + } +} + +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) { + %slice_ops = transform.structured.match ops{["tensor.parallel_insert_slice"]} in %arg1 + : (!transform.any_op) -> !transform.any_op + %first_slice_op, %second_slice_op = transform.split_handle %slice_ops + : (!transform.any_op) + -> (!transform.any_op, !transform.any_op) + %a, %b = transform.test.fuse_consumer %first_slice_op + : (!transform.any_op) -> (!transform.any_op, !transform.any_op) + transform.yield + } +} +// CHECK: func.func @fuse_tileable_consumer_scf_forall( +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]]: tensor<32x32xf32> +// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]: tensor<32x32xf32> +// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]+]]: tensor<64x64xf32>) +// CHECK: %[[OUT_INIT:.*]] = tensor.empty() : tensor<64x64xf32> +// CHECK: %[[FINAL_RESULT:.*]]:3 = scf.forall (%[[IV1:.*]], %[[IV2:.*]]) in (2, 2) +// CHECK-SAME: shared_outs(%[[FIRST_OUT_ARG:.*]] = %[[ARG2]], %[[SECOND_OUT_ARG:.*]] = %[[ARG2]], %[[ELEM_OUT_ARG:.*]] = %[[OUT_INIT]]) +// CHECK-SAME: { +// CHECK: %[[MAT_OUT_SLICE:.*]] = tensor.extract_slice %[[FIRST_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: %[[SECOND_ARG_SLICE:.*]] = tensor.extract_slice %[[SECOND_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: %[[MAT_OUT:.*]] = linalg.matmul +// CHECK-SAME: outs(%[[MAT_OUT_SLICE]] : +// CHECK: %[[SLICE_OPERAND2:.*]] = tensor.extract_slice %[[OUT_INIT]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: %[[SLICE_OUT:.*]] = tensor.extract_slice %[[ELEM_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: %[[ELEM_OUT:.*]] = linalg.elemwise_binary {fun = #linalg.binary_fn} +// CHECK-SAME: ins(%[[MAT_OUT]], %[[SLICE_OPERAND2]] : +// CHECK-SAME: outs(%[[SLICE_OUT]] : +// CHECK: scf.forall.in_parallel { +// CHECK: tensor.parallel_insert_slice %[[ELEM_OUT]] into %[[ELEM_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: tensor.parallel_insert_slice %[[MAT_OUT]] into %[[SECOND_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: tensor.parallel_insert_slice %[[SECOND_ARG_SLICE]] into %[[FIRST_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: } +// CHECK: } +// CHECK: return %[[FINAL_RESULT]]#2 : + +// ----- + +#map = affine_map<(d0) -> (d0)> +module { + func.func @fuse_tileable_consumer_scf_for_multi_yielding_consumer(%arg0: tensor<32xf32>, %arg1: tensor<32xf32>, %arg2: tensor<64xf32>) -> tensor<64xf32> { + %c4 = arith.constant 4 : index + %c64 = arith.constant 64 : index + %c0 = arith.constant 0 : index + %1:2 = scf.for %arg3 = %c0 to %c64 step %c4 iter_args(%arg4 = %arg2, %arg5 = %arg2) -> (tensor<64xf32>, tensor<64xf32>) { + %extracted_slice = tensor.extract_slice %arg4[%arg3] [32] [1] : tensor<64xf32> to tensor<32xf32> + %3 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = ["parallel"]} ins(%arg0, %arg1 : tensor<32xf32>, tensor<32xf32>) outs(%extracted_slice : tensor<32xf32>) { + ^bb0(%in: f32, %in_16: f32, %out: f32): + %13 = arith.mulf %in, %in_16 : f32 + %14 = arith.addf %out, %13 : f32 + linalg.yield %14 : f32 + } -> tensor<32xf32> + %4 = tensor.insert_slice %3 into %arg4[%arg3] [32] [1] : tensor<32xf32> into tensor<64xf32> + scf.yield %arg5, %4 : tensor<64xf32>, tensor<64xf32> + } + %in_operand_2 = tensor.empty() : tensor<64xf32> + %out_operand_3 = tensor.empty() : tensor<64xf32> + %out_operand_4 = tensor.empty() : tensor<64xf32> + %2:2 = linalg.generic {indexing_maps = [#map, #map, #map, #map], iterator_types = ["parallel"]} ins(%1#1, %in_operand_2 : tensor<64xf32>, tensor<64xf32>) outs(%out_operand_3, %out_operand_4 : tensor<64xf32>, tensor<64xf32>) { + ^bb0(%in: f32, %in_16: f32, %out_0: f32, %out_1: f32): + %13 = arith.mulf %in, %in_16 : f32 + %14 = arith.subf %out_0, %13 : f32 + %15 = arith.addf %out_1, %in : f32 + linalg.yield %14, %15 : f32, f32 + } -> (tensor<64xf32>, tensor<64xf32>) + return %2#1 : tensor<64xf32> + } +} + +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) { + %yield = transform.structured.match ops{["tensor.insert_slice"]} in %arg1 + : (!transform.any_op) -> !transform.any_op + %a, %b = transform.test.fuse_consumer %yield + : (!transform.any_op) -> (!transform.any_op, !transform.any_op) + transform.yield + } +} +// CHECK: func.func @fuse_tileable_consumer_scf_for_multi_yielding_consumer( +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]]: tensor<32xf32> +// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]: tensor<32xf32> +// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]+]]: tensor<64xf32>) +// CHECK: %[[C0:.*]] = arith.constant 0 : index +// CHECK: %0 = tensor.empty() : tensor<64xf32> +// CHECK: %[[FINAL_RESULT:.*]]:4 = scf.for %[[IV:.*]] = %[[C0]] +// CHECK-SAME: iter_args(%[[FIRST_OUT_ARG:.*]] = %[[ARG2]], %[[SECOND_OUT_ARG:.*]] = %[[ARG2]], %[[ELEM_OUT_ARG_0:.*]] = %0, %[[ELEM_OUT_ARG_1:.*]] = %0) +// CHECK-SAME: { +// CHECK: %[[MAT_OUT_SLICE:.*]] = tensor.extract_slice %[[FIRST_OUT_ARG]][%[[IV]]] [32] [1] +// CHECK: %[[MAT_OUT:.*]] = linalg.generic +// CHECK-SAME: outs(%[[MAT_OUT_SLICE]] : tensor<32xf32>) +// CHECK: %[[INSERT_MAT:.*]] = tensor.insert_slice %[[MAT_OUT]] into %[[FIRST_OUT_ARG]][%[[IV]]] [32] [1] +// CHECK: %[[SLICE_OPERAND2:.*]] = tensor.extract_slice %0[%[[IV]]] [32] [1] +// CHECK: %[[SLICE_OUT_0:.*]] = tensor.extract_slice %[[ELEM_OUT_ARG_0]][%[[IV]]] [32] [1] +// CHECK: %[[SLICE_OUT_1:.*]] = tensor.extract_slice %[[ELEM_OUT_ARG_1]][%[[IV]]] [32] [1] +// CHECK: %[[ELEM_OUT:.*]]:2 = linalg.generic +// CHECK-SAME: ins(%[[MAT_OUT]], %[[SLICE_OPERAND2]] : +// CHECK-SAME: outs(%[[SLICE_OUT_0]], %[[SLICE_OUT_1]] : +// CHECK: %[[INSERT_ELEM_0:.*]] = tensor.insert_slice %[[ELEM_OUT]]#0 into %[[ELEM_OUT_ARG_0]][%[[IV]]] [32] [1] +// CHECK: %[[INSERT_ELEM_1:.*]] = tensor.insert_slice %[[ELEM_OUT]]#1 into %[[ELEM_OUT_ARG_1]][%[[IV]]] [32] [1] +// CHECK: scf.yield %[[SECOND_OUT_ARG]], %[[INSERT_MAT]], %[[INSERT_ELEM_0]], %[[INSERT_ELEM_1]] : +// CHECK: } +// CHECK: return %[[FINAL_RESULT]]#3 : + +// ----- + +#map = affine_map<(d0, d1) -> (d0, d1)> +module { + func.func @fuse_tileable_consumer_scf_forall_multi_yielding_consumer(%arg0: tensor<32x32xf32>, %arg1: tensor<32x32xf32>, %arg2: tensor<64x64xf32>, %arg3: tensor<64x32xf32>) -> (tensor<64x64xf32>, tensor<2048xf32>) { + %c4 = arith.constant 4 : index + %c64 = arith.constant 64 : index + %c0 = arith.constant 0 : index + %0:2 = scf.forall (%arg4, %arg5) in (2, 2) shared_outs(%arg6 = %arg3, %arg7 = %arg2) -> (tensor<64x32xf32>, tensor<64x64xf32>) { + %extracted_slice = tensor.extract_slice %arg6[%arg4, %arg5] [32, 32] [1, 1] : tensor<64x32xf32> to tensor<32x32xf32> + %extracted_slice_0 = tensor.extract_slice %arg7[%arg4, %arg5] [32, 32] [1, 1] : tensor<64x64xf32> to tensor<32x32xf32> + %6 = linalg.matmul ins(%arg0, %arg1 : tensor<32x32xf32>, tensor<32x32xf32>) outs(%extracted_slice : tensor<32x32xf32>) -> tensor<32x32xf32> + scf.forall.in_parallel { + tensor.parallel_insert_slice %6 into %arg7[%arg4, %arg5] [32, 32] [1, 1] : tensor<32x32xf32> into tensor<64x64xf32> + tensor.parallel_insert_slice %extracted_slice_0 into %arg6[%arg4, %arg5] [32, 32] [1, 1] : tensor<32x32xf32> into tensor<64x32xf32> + } + } + %1 = tensor.empty() : tensor<64x64xf32> + %2 = tensor.empty() : tensor<64x64xf32> + %3 = tensor.empty() : tensor<64x64xf32> + %4:2 = linalg.generic {indexing_maps = [#map, #map, #map, #map], iterator_types = ["parallel", "parallel"]} ins(%0#1, %1 : tensor<64x64xf32>, tensor<64x64xf32>) outs(%2, %3 : tensor<64x64xf32>, tensor<64x64xf32>) { + ^bb0(%in: f32, %in_0: f32, %out: f32, %out_1: f32): + %6 = arith.mulf %in, %in_0 : f32 + %7 = arith.subf %out, %6 : f32 + %8 = arith.addf %out_1, %in : f32 + linalg.yield %7, %8 : f32, f32 + } -> (tensor<64x64xf32>, tensor<64x64xf32>) + %5 = tensor.empty() : tensor<2048xf32> + %unpack = tensor.unpack %0#0 outer_dims_perm = [0] inner_dims_pos = [0] inner_tiles = [32] into %5 : tensor<64x32xf32> -> tensor<2048xf32> + return %4#1, %unpack : tensor<64x64xf32>, tensor<2048xf32> + } +} + +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) { + %slice_ops = transform.structured.match ops{["tensor.parallel_insert_slice"]} in %arg1 + : (!transform.any_op) -> !transform.any_op + %first_slice_op, %second_slice_op = transform.split_handle %slice_ops + : (!transform.any_op) + -> (!transform.any_op, !transform.any_op) + %a, %b = transform.test.fuse_consumer %first_slice_op + : (!transform.any_op) -> (!transform.any_op, !transform.any_op) + transform.yield + } +} +// CHECK: func.func @fuse_tileable_consumer_scf_forall_multi_yielding_consumer( +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]]: tensor<32x32xf32> +// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]: tensor<32x32xf32> +// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]+]]: tensor<64x64xf32> +// CHECK-SAME: %[[ARG3:[a-zA-Z0-9]+]]: tensor<64x32xf32>) +// CHECK: %[[OUT_INIT:.*]] = tensor.empty() : tensor<64x64xf32> +// CHECK: %[[FINAL_RESULT:.*]]:4 = scf.forall (%[[IV1:.*]], %[[IV2:.*]]) in (2, 2) +// CHECK-SAME: shared_outs(%[[FIRST_OUT_ARG:.*]] = %[[ARG3]], %[[SECOND_OUT_ARG:.*]] = %[[ARG2]], %[[ELEM_OUT_ARG_0:.*]] = %[[OUT_INIT]], %[[ELEM_OUT_ARG_1:.*]] = %[[OUT_INIT]]) +// CHECK-SAME: { +// CHECK: %[[MAT_OUT_SLICE:.*]] = tensor.extract_slice %[[FIRST_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: %[[SECOND_ARG_SLICE:.*]] = tensor.extract_slice %[[SECOND_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: %[[MAT_OUT:.*]] = linalg.matmul +// CHECK-SAME: outs(%[[MAT_OUT_SLICE]] : +// CHECK: %[[SLICE_OPERAND2:.*]] = tensor.extract_slice %[[OUT_INIT]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: %[[SLICE_OUT_0:.*]] = tensor.extract_slice %[[ELEM_OUT_ARG_0]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: %[[SLICE_OUT_1:.*]] = tensor.extract_slice %[[ELEM_OUT_ARG_1]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: %[[ELEM_OUT:.*]]:2 = linalg.generic +// CHECK-SAME: ins(%[[MAT_OUT]], %[[SLICE_OPERAND2]] : +// CHECK-SAME: outs(%[[SLICE_OUT_0]], %[[SLICE_OUT_1]] : +// CHECK: scf.forall.in_parallel { +// CHECK: tensor.parallel_insert_slice %[[ELEM_OUT]]#0 into %[[ELEM_OUT_ARG_0]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: tensor.parallel_insert_slice %[[ELEM_OUT]]#1 into %[[ELEM_OUT_ARG_1]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: tensor.parallel_insert_slice %[[MAT_OUT]] into %[[SECOND_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: tensor.parallel_insert_slice %[[SECOND_ARG_SLICE]] into %[[FIRST_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: } +// CHECK: } +// CHECK: %[[UNPACK:.*]] = tensor.unpack %[[FINAL_RESULT]]#0 outer_dims_perm = [0] inner_dims_pos = [0] inner_tiles = [32] into %{{.*}} : tensor<64x32xf32> -> tensor<2048xf32> +// CHECK: return %[[FINAL_RESULT]]#3, %[[UNPACK]] : + +// ----- + +#map = affine_map<(d0, d1) -> (d0, d1)> +module { + func.func @fuse_unpack_consumer_into_scf_forall(%arg0: tensor<32x32xf32>, %arg1: tensor<32x32xf32>, %arg2: tensor<64x32xf32>) -> tensor<2048xf32> { + %c4 = arith.constant 4 : index + %c64 = arith.constant 64 : index + %c0 = arith.constant 0 : index + %1 = scf.forall (%arg3, %arg4) in (2, 2) shared_outs(%arg5 = %arg2) -> (tensor<64x32xf32>) { + %extracted_slice = tensor.extract_slice %arg5[%arg3, %arg4] [32, 32] [1, 1] : tensor<64x32xf32> to tensor<32x32xf32> + %3 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = ["parallel", "parallel"]} ins(%arg0, %arg1 : tensor<32x32xf32>, tensor<32x32xf32>) outs(%extracted_slice : tensor<32x32xf32>) { + ^bb0(%in: f32, %in_16: f32, %out: f32): + %13 = arith.mulf %in, %in_16 : f32 + %14 = arith.addf %out, %13 : f32 + linalg.yield %14 : f32 + } -> tensor<32x32xf32> + scf.forall.in_parallel { + tensor.parallel_insert_slice %3 into %arg5[%arg3, %arg4] [32, 32] [1, 1] : tensor<32x32xf32> into tensor<64x32xf32> + } + } + %output = tensor.empty() : tensor<2048xf32> + %unpack = tensor.unpack %1 outer_dims_perm = [0] inner_dims_pos = [0] inner_tiles = [32] into %output : tensor<64x32xf32> -> tensor<2048xf32> + return %unpack : tensor<2048xf32> + } +} + +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) { + %slice_op = transform.structured.match ops{["tensor.parallel_insert_slice"]} in %arg1 + : (!transform.any_op) -> !transform.any_op + %a, %b = transform.test.fuse_consumer %slice_op + : (!transform.any_op) -> (!transform.any_op, !transform.any_op) + transform.yield + } +} +// CHECK: #[[UNPACK_RESULT_MAP:.*]] = affine_map<(d0) -> (d0 * 32)> +// CHECK: func.func @fuse_unpack_consumer_into_scf_forall( +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]]: tensor<32x32xf32> +// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]: tensor<32x32xf32> +// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]+]]: tensor<64x32xf32>) +// CHECK: %[[OUT_INIT:.*]] = tensor.empty() : tensor<2048xf32> +// CHECK: %[[FINAL_RESULT:.*]]:2 = scf.forall (%[[IV1:.*]], %[[IV2:.*]]) in (2, 2) +// CHECK-SAME: shared_outs(%[[FIRST_OUT_ARG:.*]] = %[[ARG2]], %[[UNPACK_OUT_ARG:.*]] = %[[OUT_INIT]]) +// CHECK-SAME: { +// CHECK: %[[GENERIC_OUT_SLICE:.*]] = tensor.extract_slice %[[FIRST_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: %[[GENERIC_OUT:.*]] = linalg.generic +// CHECK-SAME: outs(%[[GENERIC_OUT_SLICE]] : +// CHECK: %[[UNPACK_RESULT_OFFSET:.*]] = affine.apply #[[UNPACK_RESULT_MAP]](%[[IV1]]) +// CHECK: %[[TILED_UNPACK_DEST:.*]] = tensor.extract_slice %[[UNPACK_OUT_ARG]][%[[UNPACK_RESULT_OFFSET]]] [1024] [1] +// CHECK: %[[TILED_UNPACK_OUT:.*]] = tensor.unpack %[[GENERIC_OUT]] +// CHECK-SAME: outer_dims_perm = [0] inner_dims_pos = [0] inner_tiles = [32] +// CHECK-SAME: into %[[TILED_UNPACK_DEST]] +// CHECK: scf.forall.in_parallel { +// CHECK: tensor.parallel_insert_slice %[[TILED_UNPACK_OUT]] into %[[UNPACK_OUT_ARG]][%[[UNPACK_RESULT_OFFSET]]] [1024] [1] +// CHECK: tensor.parallel_insert_slice %[[GENERIC_OUT]] into %[[FIRST_OUT_ARG]][%[[IV1]], %[[IV2]]] [32, 32] [1, 1] +// CHECK: } +// CHECK: } +// CHECK: return %[[FINAL_RESULT]]#1 : diff --git a/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp b/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp index 335db1a61f47..833fb3cc65b8 100644 --- a/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp +++ b/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp @@ -160,6 +160,59 @@ transform::TestFuseAndYieldOp::apply(TransformRewriter &rewriter, : DiagnosedSilenceableFailure::success(); } +//===----------------------------------------------------------------------===// +// TestFuseConsumerOp +//===----------------------------------------------------------------------===// + +/// Apply fusing of consumer transformation to all payload ops and store both +/// the original consumer operation as well as the fused consumer operation. +template +static LogicalResult +applyFuseConsumer(RewriterBase &rewriter, Operation *transformOp, + Range &&payloadOps, TransformResults &transformResults) { + SmallVector originalConsumerOps; + SmallVector fusedConsumerOps; + + for (Operation *target : payloadOps) { + rewriter.setInsertionPoint(target); + + FailureOr fuseConsumerResults = + scf::tileAndFuseConsumerOfSlice(rewriter, target); + + if (failed(fuseConsumerResults)) + return failure(); + + // Report back the relevant handles to the transform op. + originalConsumerOps.push_back( + fuseConsumerResults->origConsumerOperand->getOwner()); + fusedConsumerOps.push_back( + fuseConsumerResults->tiledAndFusedConsumerOperand->getOwner()); + } + + transformResults.set(transformOp->getOpResult(0), originalConsumerOps); + transformResults.set(transformOp->getOpResult(1), fusedConsumerOps); + return success(); +} + +DiagnosedSilenceableFailure +transform::TestFuseConsumerOp::apply(TransformRewriter &rewriter, + TransformResults &transformResults, + TransformState &state) { + LogicalResult result = + applyFuseConsumer(rewriter, getOperation(), + state.getPayloadOps(getTarget()), transformResults); + return failed(result) ? DiagnosedSilenceableFailure::definiteFailure() + : DiagnosedSilenceableFailure::success(); +} + +void transform::TestFuseConsumerOp::getEffects( + SmallVectorImpl &effects) { + consumesHandle(getTarget(), effects); + producesHandle(getConsumer(), effects); + producesHandle(getFusedConsumer(), effects); + modifiesPayload(effects); +} + //===----------------------------------------------------------------------===// // TestTileUsingForallOp //===----------------------------------------------------------------------===// diff --git a/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.td b/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.td index ef42375e5286..d55d746bd6aa 100644 --- a/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.td +++ b/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.td @@ -49,6 +49,25 @@ def TestFuseAndYieldOp : Op, + DeclareOpInterfaceMethods, + ReportTrackingListenerFailuresOpTrait]> { + let description = [{ + Fuses the consumer of the operation pointed to by the target handle + using the options provided as attributes. + }]; + + let arguments = + (ins TransformHandleTypeInterface:$target); + let results = (outs TransformHandleTypeInterface:$consumer, + TransformHandleTypeInterface:$fused_consumer); + + let assemblyFormat = [{ + $target attr-dict `:` functional-type(operands, results) + }]; +} + def TestTileUsingForallOp : Op, DeclareOpInterfaceMethods, -- GitLab From 6e22b538da4b09efb10a59582a3f43d8128ae7d1 Mon Sep 17 00:00:00 2001 From: Hui Date: Sat, 1 Jun 2024 21:12:04 +0100 Subject: [PATCH 020/678] [libc++] Fix `std::atomic::wait` ulock wait UL_COMPARE_AND_WAIT64 (#92783) in `atomic::wait`, when we call the platform wait ulock_wait , we are using UL_COMPARE_AND_WAIT. But we should use UL_COMPARE_AND_WAIT64 instead as the address we are waiting for is a 64 bit integer. fixes https://github.com/llvm/llvm-project/issues/85107 It is rather hard to test directly because in `atomic::wait`, before calling into the platform wait, our c++ code has some poll logic which checks the value not changing. Thus in this patch, the test is using the internal function. --- libcxx/src/atomic.cpp | 9 ++++-- .../libcxx/atomics/atomics.syn/wait.pass.cpp | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 libcxx/test/libcxx/atomics/atomics.syn/wait.pass.cpp diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp index 44100d4414e0..7142f38c9609 100644 --- a/libcxx/src/atomic.cpp +++ b/libcxx/src/atomic.cpp @@ -69,17 +69,20 @@ extern "C" int __ulock_wait( uint32_t operation, void* addr, uint64_t value, uint32_t timeout); /* timeout is specified in microseconds */ extern "C" int __ulock_wake(uint32_t operation, void* addr, uint64_t wake_value); -# define UL_COMPARE_AND_WAIT 1 +// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/ulock.h#L82 +# define UL_COMPARE_AND_WAIT64 5 # define ULF_WAKE_ALL 0x00000100 static void __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) { - __ulock_wait(UL_COMPARE_AND_WAIT, const_cast<__cxx_atomic_contention_t*>(__ptr), __val, 0); + static_assert(sizeof(__cxx_atomic_contention_t) == 8, "Waiting on 8 bytes value"); + __ulock_wait(UL_COMPARE_AND_WAIT64, const_cast<__cxx_atomic_contention_t*>(__ptr), __val, 0); } static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) { + static_assert(sizeof(__cxx_atomic_contention_t) == 8, "Waking up on 8 bytes value"); __ulock_wake( - UL_COMPARE_AND_WAIT | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<__cxx_atomic_contention_t*>(__ptr), 0); + UL_COMPARE_AND_WAIT64 | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<__cxx_atomic_contention_t*>(__ptr), 0); } #elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8 diff --git a/libcxx/test/libcxx/atomics/atomics.syn/wait.pass.cpp b/libcxx/test/libcxx/atomics/atomics.syn/wait.pass.cpp new file mode 100644 index 000000000000..f29dc6eb463f --- /dev/null +++ b/libcxx/test/libcxx/atomics/atomics.syn/wait.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-threads +// This bug was first fixed in LLVM 19 +// UNSUPPORTED: using-built-library-before-llvm-19 +// XFAIL: availability-synchronization_library-missing + +#include +#include + +void test_85107() { + if constexpr (sizeof(std::__cxx_contention_t) == 8 && sizeof(long) > 4) { + // https://github.com/llvm/llvm-project/issues/85107 + // [libc++] atomic_wait uses UL_COMPARE_AND_WAIT when it should use UL_COMPARE_AND_WAIT64 on Darwin + constexpr std::__cxx_contention_t old_val = 0; + constexpr std::__cxx_contention_t new_val = old_val + (1ll << 32); + std::__cxx_atomic_contention_t ct(new_val); + std::__libcpp_atomic_wait(&ct, old_val); // this will hang forever if the bug is present + } +} + +int main(int, char**) { + test_85107(); + + return 0; +} -- GitLab From e7e6e1ecadc59677b422044f514c2eb379ee719b Mon Sep 17 00:00:00 2001 From: MaheshRavishankar <1663364+MaheshRavishankar@users.noreply.github.com> Date: Sat, 1 Jun 2024 15:33:49 -0700 Subject: [PATCH 021/678] [mlir][bazel] Add bazel build support for https://github.com/llvm/llvm-project/commit/2b2ce50fe843b5b550806a0ab15b06cd5c405d48 (#94126) Also drop errant header include from `Linalg` dialect into `Dialect/SCF/Transforms/TileUsingInterface.cpp` --- mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp | 1 - utils/bazel/llvm-project-overlay/mlir/BUILD.bazel | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp b/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp index a54edf5e72e7..f3d6b7a53011 100644 --- a/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp +++ b/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp @@ -16,7 +16,6 @@ #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/Arith/Utils/Utils.h" #include "mlir/Dialect/Func/IR/FuncOps.h" -#include "mlir/Dialect/Linalg/IR/Linalg.h" #include "mlir/Dialect/SCF/Utils/Utils.h" #include "mlir/Dialect/Tensor/IR/Tensor.h" #include "mlir/Dialect/Utils/IndexingUtils.h" diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel index ded718ae9950..dcd8125f34b9 100644 --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -2831,6 +2831,7 @@ cc_library( ":TensorTransforms", ":TilingInterface", ":TransformUtils", + ":ViewLikeInterface", "//llvm:Support", ], ) @@ -7525,6 +7526,7 @@ cc_library( ":TilingInterface", ":TransformUtils", ":ValueBoundsOpInterface", + ":ViewLikeInterface", ":VectorDialect", ":VectorUtils", "//llvm:Support", -- GitLab From c877eb3754ad1a61db2717530141eded580c3533 Mon Sep 17 00:00:00 2001 From: Noah Goldstein Date: Thu, 30 May 2024 10:01:29 -0500 Subject: [PATCH 022/678] [InstCombine] Add tests for folding `(add X, (sext/zext (icmp eq X, C)))`; NFC --- .../InstCombine/fold-ext-eq-c-with-op.ll | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 llvm/test/Transforms/InstCombine/fold-ext-eq-c-with-op.ll diff --git a/llvm/test/Transforms/InstCombine/fold-ext-eq-c-with-op.ll b/llvm/test/Transforms/InstCombine/fold-ext-eq-c-with-op.ll new file mode 100644 index 000000000000..848b0d189497 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/fold-ext-eq-c-with-op.ll @@ -0,0 +1,61 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +declare void @use.i8(i8) +define i8 @fold_add_zext_eq_0(i8 %x) { +; CHECK-LABEL: @fold_add_zext_eq_0( +; CHECK-NEXT: [[X_EQ:%.*]] = icmp eq i8 [[X:%.*]], 0 +; CHECK-NEXT: [[X_EQ_EXT:%.*]] = zext i1 [[X_EQ]] to i8 +; CHECK-NEXT: [[R:%.*]] = add i8 [[X_EQ_EXT]], [[X]] +; CHECK-NEXT: ret i8 [[R]] +; + %x_eq = icmp eq i8 %x, 0 + %x_eq_ext = zext i1 %x_eq to i8 + %r = add i8 %x, %x_eq_ext + ret i8 %r +} + +define <2 x i8> @fold_add_sext_eq_4_6(<2 x i6> %xx) { +; CHECK-LABEL: @fold_add_sext_eq_4_6( +; CHECK-NEXT: [[X:%.*]] = zext <2 x i6> [[XX:%.*]] to <2 x i8> +; CHECK-NEXT: [[X_EQ:%.*]] = icmp eq <2 x i8> [[X]], +; CHECK-NEXT: [[X_EQ_EXT:%.*]] = sext <2 x i1> [[X_EQ]] to <2 x i8> +; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i8> [[X_EQ_EXT]], [[X]] +; CHECK-NEXT: ret <2 x i8> [[R]] +; + %x = zext <2 x i6> %xx to <2 x i8> + %x_eq = icmp eq <2 x i8> %x, + %x_eq_ext = sext <2 x i1> %x_eq to <2 x i8> + %r = add <2 x i8> %x_eq_ext, %x + ret <2 x i8> %r +} + +define i8 @fold_add_zext_eq_0_fail_multiuse_exp(i8 %x) { +; CHECK-LABEL: @fold_add_zext_eq_0_fail_multiuse_exp( +; CHECK-NEXT: [[X_EQ:%.*]] = icmp eq i8 [[X:%.*]], 0 +; CHECK-NEXT: [[X_EQ_EXT:%.*]] = zext i1 [[X_EQ]] to i8 +; CHECK-NEXT: [[R:%.*]] = add i8 [[X_EQ_EXT]], [[X]] +; CHECK-NEXT: call void @use.i8(i8 [[X_EQ_EXT]]) +; CHECK-NEXT: ret i8 [[R]] +; + %x_eq = icmp eq i8 %x, 0 + %x_eq_ext = zext i1 %x_eq to i8 + %r = add i8 %x, %x_eq_ext + call void @use.i8(i8 %x_eq_ext) + ret i8 %r +} + +define i8 @fold_add_sext_eq_4_fail_wrong_cond(i8 %x, i8 %y) { +; CHECK-LABEL: @fold_add_sext_eq_4_fail_wrong_cond( +; CHECK-NEXT: [[X_EQ:%.*]] = icmp eq i8 [[Y:%.*]], 4 +; CHECK-NEXT: [[X_EQ_EXT:%.*]] = sext i1 [[X_EQ]] to i8 +; CHECK-NEXT: [[R:%.*]] = add i8 [[X_EQ_EXT]], [[X:%.*]] +; CHECK-NEXT: call void @use.i8(i8 [[X_EQ_EXT]]) +; CHECK-NEXT: ret i8 [[R]] +; + %x_eq = icmp eq i8 %y, 4 + %x_eq_ext = sext i1 %x_eq to i8 + %r = add i8 %x, %x_eq_ext + call void @use.i8(i8 %x_eq_ext) + ret i8 %r +} -- GitLab From 0310f7f2d0c56a5697710251cec9803cbf7b4d56 Mon Sep 17 00:00:00 2001 From: Noah Goldstein Date: Thu, 30 May 2024 10:01:33 -0500 Subject: [PATCH 023/678] [InstCombine] Fold `(add X, (sext/zext (icmp eq X, C)))` We can convert this to a select based on the `(icmp eq X, C)`, then constant fold the addition the true arm begin `(add C, (sext/zext 1))` and the false arm being `(add X, 0)` e.g - `(select (icmp eq X, C), (add C, (sext/zext 1)), (add X, 0))`. This is essentially a specialization of the only case that sees to actually show up from #89020 Closes #93840 --- .../InstCombine/InstCombineAddSub.cpp | 18 ++++++++++++++++++ .../test/Transforms/InstCombine/apint-shift.ll | 17 +++++------------ .../InstCombine/fold-ext-eq-c-with-op.ll | 7 ++----- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index bff09f567668..8205b49dfbe2 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1694,6 +1694,24 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) { return BinaryOperator::CreateOr(LHS, Zext); } + { + Value *Cond, *Ext; + Constant *C; + // (add X, (sext/zext (icmp eq X, C))) + // -> (select (icmp eq X, C), (add C, (sext/zext 1)), X) + auto CondMatcher = m_CombineAnd( + m_Value(Cond), m_ICmp(Pred, m_Deferred(A), m_ImmConstant(C))); + + if (match(&I, + m_c_Add(m_Value(A), + m_CombineAnd(m_Value(Ext), m_ZExtOrSExt(CondMatcher)))) && + Pred == ICmpInst::ICMP_EQ && Ext->hasOneUse()) { + Value *Add = isa(Ext) ? InstCombiner::AddOne(C) + : InstCombiner::SubOne(C); + return replaceInstUsesWith(I, Builder.CreateSelect(Cond, Add, A)); + } + } + if (Instruction *Ashr = foldAddToAshr(I)) return Ashr; diff --git a/llvm/test/Transforms/InstCombine/apint-shift.ll b/llvm/test/Transforms/InstCombine/apint-shift.ll index 05c3db70ce1c..ecf9c4e9c4e6 100644 --- a/llvm/test/Transforms/InstCombine/apint-shift.ll +++ b/llvm/test/Transforms/InstCombine/apint-shift.ll @@ -240,8 +240,8 @@ define i23 @test11(i23 %x) { define i47 @test12(i47 %X) { ; CHECK-LABEL: @test12( -; CHECK-NEXT: [[SH2:%.*]] = and i47 [[X:%.*]], -256 -; CHECK-NEXT: ret i47 [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = and i47 [[X:%.*]], -256 +; CHECK-NEXT: ret i47 [[SH1]] ; %sh1 = ashr i47 %X, 8 %sh2 = shl i47 %sh1, 8 @@ -250,8 +250,8 @@ define i47 @test12(i47 %X) { define <2 x i47> @test12_splat_vec(<2 x i47> %X) { ; CHECK-LABEL: @test12_splat_vec( -; CHECK-NEXT: [[SH2:%.*]] = and <2 x i47> [[X:%.*]], -; CHECK-NEXT: ret <2 x i47> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = and <2 x i47> [[X:%.*]], +; CHECK-NEXT: ret <2 x i47> [[SH1]] ; %sh1 = ashr <2 x i47> %X, %sh2 = shl <2 x i47> %sh1, @@ -564,14 +564,7 @@ define i40 @test26(i40 %A) { ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9880 define i177 @ossfuzz_9880(i177 %X) { ; CHECK-LABEL: @ossfuzz_9880( -; CHECK-NEXT: [[A:%.*]] = alloca i177, align 8 -; CHECK-NEXT: [[L1:%.*]] = load i177, ptr [[A]], align 4 -; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L1]], -1 -; CHECK-NEXT: [[B5_NEG:%.*]] = sext i1 [[TMP1]] to i177 -; CHECK-NEXT: [[B14:%.*]] = add i177 [[L1]], [[B5_NEG]] -; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i177 [[B14]], -1 -; CHECK-NEXT: [[B1:%.*]] = zext i1 [[TMP2]] to i177 -; CHECK-NEXT: ret i177 [[B1]] +; CHECK-NEXT: ret i177 0 ; %A = alloca i177 %L1 = load i177, ptr %A diff --git a/llvm/test/Transforms/InstCombine/fold-ext-eq-c-with-op.ll b/llvm/test/Transforms/InstCombine/fold-ext-eq-c-with-op.ll index 848b0d189497..4d02d492d2aa 100644 --- a/llvm/test/Transforms/InstCombine/fold-ext-eq-c-with-op.ll +++ b/llvm/test/Transforms/InstCombine/fold-ext-eq-c-with-op.ll @@ -4,9 +4,7 @@ declare void @use.i8(i8) define i8 @fold_add_zext_eq_0(i8 %x) { ; CHECK-LABEL: @fold_add_zext_eq_0( -; CHECK-NEXT: [[X_EQ:%.*]] = icmp eq i8 [[X:%.*]], 0 -; CHECK-NEXT: [[X_EQ_EXT:%.*]] = zext i1 [[X_EQ]] to i8 -; CHECK-NEXT: [[R:%.*]] = add i8 [[X_EQ_EXT]], [[X]] +; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 1) ; CHECK-NEXT: ret i8 [[R]] ; %x_eq = icmp eq i8 %x, 0 @@ -19,8 +17,7 @@ define <2 x i8> @fold_add_sext_eq_4_6(<2 x i6> %xx) { ; CHECK-LABEL: @fold_add_sext_eq_4_6( ; CHECK-NEXT: [[X:%.*]] = zext <2 x i6> [[XX:%.*]] to <2 x i8> ; CHECK-NEXT: [[X_EQ:%.*]] = icmp eq <2 x i8> [[X]], -; CHECK-NEXT: [[X_EQ_EXT:%.*]] = sext <2 x i1> [[X_EQ]] to <2 x i8> -; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i8> [[X_EQ_EXT]], [[X]] +; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[X_EQ]], <2 x i8> , <2 x i8> [[X]] ; CHECK-NEXT: ret <2 x i8> [[R]] ; %x = zext <2 x i6> %xx to <2 x i8> -- GitLab From d2cdc8ab45d74f8691f73cb5a2b8c431585cd449 Mon Sep 17 00:00:00 2001 From: paperchalice Date: Sun, 2 Jun 2024 09:12:33 +0800 Subject: [PATCH 024/678] [NewPM][CodeGen] Port selection dag isel to new pass manager (#83567) Port selection dag isel to new pass manager. Only `AMDGPU` and `X86` support new pass version. `-verify-machineinstrs` in new pass manager belongs to verify instrumentation, it is enabled by default. --- llvm/include/llvm/CodeGen/SelectionDAG.h | 12 + llvm/include/llvm/CodeGen/SelectionDAGISel.h | 43 +++- llvm/include/llvm/CodeGen/StackProtector.h | 2 + llvm/include/llvm/Passes/CodeGenPassBuilder.h | 9 +- .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 230 +++++++++++++----- llvm/lib/Target/AArch64/AArch64.h | 2 +- .../Target/AArch64/AArch64ISelDAGToDAG.cpp | 19 +- .../Target/AArch64/AArch64TargetMachine.cpp | 2 +- llvm/lib/Target/AMDGPU/AMDGPU.h | 2 +- .../AMDGPU/AMDGPUCodeGenPassBuilder.cpp | 8 +- llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp | 31 ++- llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h | 24 +- llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def | 6 + .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 3 +- llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp | 13 +- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 19 +- llvm/lib/Target/ARC/ARC.h | 2 +- llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp | 18 +- llvm/lib/Target/ARC/ARCTargetMachine.cpp | 2 +- llvm/lib/Target/ARM/ARM.h | 2 +- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 18 +- llvm/lib/Target/ARM/ARMTargetMachine.cpp | 2 +- llvm/lib/Target/AVR/AVR.h | 2 +- llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp | 16 +- llvm/lib/Target/AVR/AVRTargetMachine.cpp | 2 +- llvm/lib/Target/BPF/BPF.h | 2 +- llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp | 15 +- llvm/lib/Target/BPF/BPFTargetMachine.cpp | 2 +- llvm/lib/Target/CSKY/CSKY.h | 2 +- llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp | 19 +- llvm/lib/Target/CSKY/CSKYTargetMachine.cpp | 2 +- llvm/lib/Target/Hexagon/Hexagon.h | 2 +- .../Target/Hexagon/HexagonISelDAGToDAG.cpp | 11 +- llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h | 12 +- .../Target/Hexagon/HexagonTargetMachine.cpp | 2 +- llvm/lib/Target/Lanai/Lanai.h | 2 +- llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp | 19 +- llvm/lib/Target/Lanai/LanaiTargetMachine.cpp | 2 +- llvm/lib/Target/LoongArch/LoongArch.h | 2 +- .../LoongArch/LoongArchISelDAGToDAG.cpp | 11 +- .../Target/LoongArch/LoongArchISelDAGToDAG.h | 8 +- .../LoongArch/LoongArchTargetMachine.cpp | 2 +- llvm/lib/Target/M68k/M68k.h | 2 +- llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp | 17 +- llvm/lib/Target/M68k/M68kTargetMachine.cpp | 2 +- llvm/lib/Target/MSP430/MSP430.h | 2 +- llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 18 +- .../lib/Target/MSP430/MSP430TargetMachine.cpp | 2 +- llvm/lib/Target/Mips/Mips.h | 2 +- llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp | 6 +- llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h | 5 + llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 12 +- llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 13 +- llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 10 +- llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 8 +- llvm/lib/Target/Mips/MipsTargetMachine.cpp | 2 +- llvm/lib/Target/NVPTX/NVPTX.h | 2 +- llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp | 13 +- llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h | 9 +- llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp | 2 +- llvm/lib/Target/PowerPC/PPC.h | 2 +- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 18 +- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp | 2 +- llvm/lib/Target/RISCV/RISCV.h | 2 +- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 11 +- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 11 +- llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 2 +- llvm/lib/Target/Sparc/Sparc.h | 2 +- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp | 18 +- llvm/lib/Target/Sparc/SparcTargetMachine.cpp | 2 +- llvm/lib/Target/SystemZ/SystemZ.h | 2 +- .../Target/SystemZ/SystemZISelDAGToDAG.cpp | 19 +- .../Target/SystemZ/SystemZTargetMachine.cpp | 2 +- llvm/lib/Target/VE/VE.h | 2 +- llvm/lib/Target/VE/VEISelDAGToDAG.cpp | 17 +- llvm/lib/Target/VE/VETargetMachine.cpp | 2 +- llvm/lib/Target/WebAssembly/WebAssembly.h | 2 +- .../WebAssembly/WebAssemblyISelDAGToDAG.cpp | 20 +- .../WebAssembly/WebAssemblyTargetMachine.cpp | 2 +- llvm/lib/Target/X86/X86.h | 2 +- llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 11 +- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 28 ++- llvm/lib/Target/X86/X86ISelDAGToDAG.h | 25 ++ llvm/lib/Target/X86/X86PassRegistry.def | 19 ++ llvm/lib/Target/X86/X86TargetMachine.cpp | 2 +- llvm/lib/Target/X86/X86TargetMachine.h | 3 + llvm/lib/Target/XCore/XCore.h | 2 +- llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp | 19 +- llvm/lib/Target/XCore/XCoreTargetMachine.cpp | 2 +- llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp | 25 +- .../AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll | 4 + .../AMDGPU/buffer-atomic-fadd.f32-rtn.ll | 5 +- .../CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll | 2 + .../AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll | 3 + .../AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll | 2 + .../AMDGPU/buffer-intrinsics-mmo-offsets.ll | 1 + .../CodeGen/AMDGPU/bug-v4f64-subvector.ll | 1 + .../test/CodeGen/AMDGPU/carryout-selection.ll | 1 + .../CodeGen/AMDGPU/dagcombine-fma-crash.ll | 1 + .../CodeGen/AMDGPU/divergence-driven-abs.ll | 2 + .../AMDGPU/divergence-driven-bitreverse.ll | 1 + .../AMDGPU/divergence-driven-ctlz-cttz.ll | 1 + .../CodeGen/AMDGPU/divergence-driven-ctpop.ll | 1 + .../AMDGPU/divergence-driven-min-max.ll | 1 + .../divergence-driven-negsubinlineconst.ll | 2 + .../AMDGPU/divergence-driven-not-isel.ll | 1 + .../CodeGen/AMDGPU/divergence-driven-xnor.ll | 2 + .../AMDGPU/extract_subvector_vec4_vec3.ll | 1 + .../CodeGen/AMDGPU/flat-atomic-fadd.f32.ll | 2 + .../CodeGen/AMDGPU/flat-atomic-fadd.f64.ll | 2 + .../fneg-fabs-divergence-driven-isel.ll | 2 + .../AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll | 3 + .../AMDGPU/global-atomic-fadd.v2f16-rtn.ll | 2 + llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll | 1 + llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll | 1 + .../AMDGPU/legalize-fp-load-invariant.ll | 1 + .../AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll | 1 + llvm/test/CodeGen/X86/apx/no-rex2-general.ll | 2 + .../CodeGen/X86/apx/no-rex2-pseudo-amx.ll | 1 + .../CodeGen/X86/apx/no-rex2-pseudo-x87.ll | 1 + llvm/test/CodeGen/X86/apx/no-rex2-special.ll | 1 + llvm/test/tools/llc/new-pm/start-stop.ll | 4 +- 122 files changed, 783 insertions(+), 280 deletions(-) create mode 100644 llvm/lib/Target/X86/X86ISelDAGToDAG.h create mode 100644 llvm/lib/Target/X86/X86PassRegistry.def diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 6d28273029bd..48cb0cdf851c 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -29,6 +29,7 @@ #include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineMemOperand.h" +#include "llvm/CodeGen/MachinePassManager.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGenTypes/MachineValueType.h" @@ -230,6 +231,7 @@ class SelectionDAG { const TargetLibraryInfo *LibInfo = nullptr; const FunctionVarLocs *FnVarLocs = nullptr; MachineFunction *MF; + MachineFunctionAnalysisManager *MFAM = nullptr; Pass *SDAGISelPass = nullptr; LLVMContext *Context; CodeGenOptLevel OptLevel; @@ -459,6 +461,15 @@ public: UniformityInfo *UA, ProfileSummaryInfo *PSIin, BlockFrequencyInfo *BFIin, FunctionVarLocs const *FnVarLocs); + void init(MachineFunction &NewMF, OptimizationRemarkEmitter &NewORE, + MachineFunctionAnalysisManager &AM, + const TargetLibraryInfo *LibraryInfo, UniformityInfo *UA, + ProfileSummaryInfo *PSIin, BlockFrequencyInfo *BFIin, + FunctionVarLocs const *FnVarLocs) { + init(NewMF, NewORE, nullptr, LibraryInfo, UA, PSIin, BFIin, FnVarLocs); + MFAM = &AM; + } + void setFunctionLoweringInfo(FunctionLoweringInfo * FuncInfo) { FLI = FuncInfo; } @@ -469,6 +480,7 @@ public: MachineFunction &getMachineFunction() const { return *MF; } const Pass *getPass() const { return SDAGISelPass; } + MachineFunctionAnalysisManager *getMFAM() { return MFAM; } CodeGenOptLevel getOptLevel() const { return OptLevel; } const DataLayout &getDataLayout() const { return MF->getDataLayout(); } diff --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h index 837f8bf7263e..fe655543a470 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h @@ -15,6 +15,7 @@ #define LLVM_CODEGEN_SELECTIONDAGISEL_H #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachinePassManager.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/IR/BasicBlock.h" #include @@ -24,6 +25,7 @@ class AAResults; class AssumptionCache; class TargetInstrInfo; class TargetMachine; +class SSPLayoutInfo; class SelectionDAGBuilder; class SDValue; class MachineRegisterInfo; @@ -31,6 +33,7 @@ class MachineFunction; class OptimizationRemarkEmitter; class TargetLowering; class TargetLibraryInfo; +class TargetTransformInfo; class FunctionLoweringInfo; class SwiftErrorValueTracking; class GCFunctionInfo; @@ -38,7 +41,7 @@ class ScheduleDAGSDNodes; /// SelectionDAGISel - This is the common base class used for SelectionDAG-based /// pattern-matching instruction selectors. -class SelectionDAGISel : public MachineFunctionPass { +class SelectionDAGISel { public: TargetMachine &TM; const TargetLibraryInfo *LibInfo; @@ -51,6 +54,10 @@ public: AAResults *AA = nullptr; AssumptionCache *AC = nullptr; GCFunctionInfo *GFI = nullptr; + SSPLayoutInfo *SP = nullptr; +#ifndef NDEBUG + TargetTransformInfo *TTI = nullptr; +#endif CodeGenOptLevel OptLevel; const TargetInstrInfo *TII; const TargetLowering *TLI; @@ -67,16 +74,18 @@ public: /// functions. Storing the filter result here so that we only need to do the /// filtering once. bool MatchFilterFuncName = false; + StringRef FuncName; - explicit SelectionDAGISel(char &ID, TargetMachine &tm, + explicit SelectionDAGISel(TargetMachine &tm, CodeGenOptLevel OL = CodeGenOptLevel::Default); - ~SelectionDAGISel() override; + ~SelectionDAGISel(); const TargetLowering *getTargetLowering() const { return TLI; } - void getAnalysisUsage(AnalysisUsage &AU) const override; + void initializeAnalysisResults(MachineFunctionAnalysisManager &MFAM); + void initializeAnalysisResults(MachineFunctionPass &MFP); - bool runOnMachineFunction(MachineFunction &MF) override; + virtual bool runOnMachineFunction(MachineFunction &mf); virtual void emitFunctionEntryCode() {} @@ -517,6 +526,30 @@ private: bool isMorphNodeTo); }; +class SelectionDAGISelLegacy : public MachineFunctionPass { + std::unique_ptr Selector; + +public: + SelectionDAGISelLegacy(char &ID, std::unique_ptr S); + + ~SelectionDAGISelLegacy() override = default; + + void getAnalysisUsage(AnalysisUsage &AU) const override; + + bool runOnMachineFunction(MachineFunction &MF) override; +}; + +class SelectionDAGISelPass : public PassInfoMixin { + std::unique_ptr Selector; + +protected: + SelectionDAGISelPass(std::unique_ptr Selector) + : Selector(std::move(Selector)) {} + +public: + PreservedAnalyses run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM); +}; } #endif /* LLVM_CODEGEN_SELECTIONDAGISEL_H */ diff --git a/llvm/include/llvm/CodeGen/StackProtector.h b/llvm/include/llvm/CodeGen/StackProtector.h index eb5d9d0caebc..dfafc781067d 100644 --- a/llvm/include/llvm/CodeGen/StackProtector.h +++ b/llvm/include/llvm/CodeGen/StackProtector.h @@ -109,6 +109,8 @@ public: StackProtector(); + SSPLayoutInfo &getLayoutInfo() { return LayoutInfo; } + void getAnalysisUsage(AnalysisUsage &AU) const override; // Return true if StackProtector is supposed to be handled by SelectionDAG. diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h index 17bea5da48ce..afe066101c75 100644 --- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h +++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h @@ -140,6 +140,9 @@ public: } protected: + template + using has_required_t = decltype(std::declval().isRequired()); + template using is_module_pass_t = decltype(std::declval().run( std::declval(), std::declval())); @@ -170,8 +173,10 @@ protected: static_assert((is_detected::value || is_detected::value) && "Only module pass and function pass are supported."); - - if (!PB.runBeforeAdding(Name)) + bool Required = false; + if constexpr (is_detected::value) + Required = PassT::isRequired(); + if (!PB.runBeforeAdding(Name) && !Required) return; // Add Function Pass diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 8addaf1ae3e5..2c1e557ca109 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -341,9 +341,49 @@ void TargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, // SelectionDAGISel code //===----------------------------------------------------------------------===// -SelectionDAGISel::SelectionDAGISel(char &ID, TargetMachine &tm, - CodeGenOptLevel OL) - : MachineFunctionPass(ID), TM(tm), FuncInfo(new FunctionLoweringInfo()), +SelectionDAGISelLegacy::SelectionDAGISelLegacy( + char &ID, std::unique_ptr S) + : MachineFunctionPass(ID), Selector(std::move(S)) { + initializeGCModuleInfoPass(*PassRegistry::getPassRegistry()); + initializeBranchProbabilityInfoWrapperPassPass( + *PassRegistry::getPassRegistry()); + initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry()); + initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); +} + +bool SelectionDAGISelLegacy::runOnMachineFunction(MachineFunction &MF) { + // If we already selected that function, we do not need to run SDISel. + if (MF.getProperties().hasProperty( + MachineFunctionProperties::Property::Selected)) + return false; + + // Do some sanity-checking on the command-line options. + if (EnableFastISelAbort && !Selector->TM.Options.EnableFastISel) + report_fatal_error("-fast-isel-abort > 0 requires -fast-isel"); + + // Decide what flavour of variable location debug-info will be used, before + // we change the optimisation level. + MF.setUseDebugInstrRef(MF.shouldUseDebugInstrRef()); + + // Reset the target options before resetting the optimization + // level below. + // FIXME: This is a horrible hack and should be processed via + // codegen looking at the optimization level explicitly when + // it wants to look at it. + Selector->TM.resetTargetOptions(MF.getFunction()); + // Reset OptLevel to None for optnone functions. + CodeGenOptLevel NewOptLevel = skipFunction(MF.getFunction()) + ? CodeGenOptLevel::None + : Selector->OptLevel; + + Selector->MF = &MF; + OptLevelChanger OLC(*Selector, NewOptLevel); + Selector->initializeAnalysisResults(*this); + return Selector->runOnMachineFunction(MF); +} + +SelectionDAGISel::SelectionDAGISel(TargetMachine &tm, CodeGenOptLevel OL) + : TM(tm), FuncInfo(new FunctionLoweringInfo()), SwiftError(new SwiftErrorValueTracking()), CurDAG(new SelectionDAG(tm, OL)), SDB(std::make_unique(*CurDAG, *FuncInfo, *SwiftError, @@ -361,14 +401,17 @@ SelectionDAGISel::~SelectionDAGISel() { delete SwiftError; } -void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { +void SelectionDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const { + CodeGenOptLevel OptLevel = Selector->OptLevel; if (OptLevel != CodeGenOptLevel::None) AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addPreserved(); AU.addRequired(); +#ifndef NDEBUG AU.addRequired(); +#endif AU.addRequired(); if (UseMBPI && OptLevel != CodeGenOptLevel::None) AU.addRequired(); @@ -406,65 +449,129 @@ static void computeUsesMSVCFloatingPoint(const Triple &TT, const Function &F, } } -bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { +PreservedAnalyses +SelectionDAGISelPass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM) { // If we already selected that function, we do not need to run SDISel. - if (mf.getProperties().hasProperty( + if (MF.getProperties().hasProperty( MachineFunctionProperties::Property::Selected)) - return false; - // Do some sanity-checking on the command-line options. - assert((!EnableFastISelAbort || TM.Options.EnableFastISel) && - "-fast-isel-abort > 0 requires -fast-isel"); - - const Function &Fn = mf.getFunction(); - MF = &mf; + return PreservedAnalyses::all(); -#ifndef NDEBUG - StringRef FuncName = Fn.getName(); - MatchFilterFuncName = isFunctionInPrintList(FuncName); -#else - (void)MatchFilterFuncName; -#endif + // Do some sanity-checking on the command-line options. + if (EnableFastISelAbort && !Selector->TM.Options.EnableFastISel) + report_fatal_error("-fast-isel-abort > 0 requires -fast-isel"); // Decide what flavour of variable location debug-info will be used, before // we change the optimisation level. - bool InstrRef = mf.shouldUseDebugInstrRef(); - mf.setUseDebugInstrRef(InstrRef); + MF.setUseDebugInstrRef(MF.shouldUseDebugInstrRef()); // Reset the target options before resetting the optimization // level below. // FIXME: This is a horrible hack and should be processed via // codegen looking at the optimization level explicitly when // it wants to look at it. - TM.resetTargetOptions(Fn); + Selector->TM.resetTargetOptions(MF.getFunction()); + // Reset OptLevel to None for optnone functions. + // TODO: Add a function analysis to handle this. + Selector->MF = &MF; // Reset OptLevel to None for optnone functions. - CodeGenOptLevel NewOptLevel = OptLevel; - if (OptLevel != CodeGenOptLevel::None && skipFunction(Fn)) - NewOptLevel = CodeGenOptLevel::None; - OptLevelChanger OLC(*this, NewOptLevel); + CodeGenOptLevel NewOptLevel = MF.getFunction().hasOptNone() + ? CodeGenOptLevel::None + : Selector->OptLevel; + + OptLevelChanger OLC(*Selector, NewOptLevel); + Selector->initializeAnalysisResults(MFAM); + Selector->runOnMachineFunction(MF); + + return getMachineFunctionPassPreservedAnalyses(); +} + +void SelectionDAGISel::initializeAnalysisResults( + MachineFunctionAnalysisManager &MFAM) { + auto &FAM = MFAM.getResult(*MF) + .getManager(); + auto &MAMP = MFAM.getResult(*MF); + Function &Fn = MF->getFunction(); +#ifndef NDEBUG + FuncName = Fn.getName(); + MatchFilterFuncName = isFunctionInPrintList(FuncName); +#else + (void)MatchFilterFuncName; +#endif TII = MF->getSubtarget().getInstrInfo(); TLI = MF->getSubtarget().getTargetLowering(); RegInfo = &MF->getRegInfo(); - LibInfo = &getAnalysis().getTLI(Fn); - GFI = Fn.hasGC() ? &getAnalysis().getFunctionInfo(Fn) : nullptr; + LibInfo = &FAM.getResult(Fn); + GFI = Fn.hasGC() ? &FAM.getResult(Fn) : nullptr; ORE = std::make_unique(&Fn); - AC = &getAnalysis().getAssumptionCache(mf.getFunction()); - auto *PSI = &getAnalysis().getPSI(); + AC = &FAM.getResult(Fn); + auto *PSI = MAMP.getCachedResult(*Fn.getParent()); BlockFrequencyInfo *BFI = nullptr; + FAM.getResult(Fn); if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOptLevel::None) - BFI = &getAnalysis().getBFI(); + BFI = &FAM.getResult(Fn); FunctionVarLocs const *FnVarLocs = nullptr; if (isAssignmentTrackingEnabled(*Fn.getParent())) - FnVarLocs = getAnalysis().getResults(); + FnVarLocs = &FAM.getResult(Fn); - ISEL_DUMP(dbgs() << "\n\n\n=== " << FuncName << "\n"); + auto *UA = FAM.getCachedResult(Fn); + CurDAG->init(*MF, *ORE, MFAM, LibInfo, UA, PSI, BFI, FnVarLocs); + SwiftError->setFunction(*MF); + + // Now get the optional analyzes if we want to. + // This is based on the possibly changed OptLevel (after optnone is taken + // into account). That's unfortunate but OK because it just means we won't + // ask for passes that have been required anyway. + + if (UseMBPI && OptLevel != CodeGenOptLevel::None) + FuncInfo->BPI = &FAM.getResult(Fn); + else + FuncInfo->BPI = nullptr; + + if (OptLevel != CodeGenOptLevel::None) + AA = &FAM.getResult(Fn); + else + AA = nullptr; + + SP = &FAM.getResult(Fn); + +#ifndef NDEBUG + TTI = &FAM.getResult(Fn); +#endif +} + +void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) { + Function &Fn = MF->getFunction(); +#ifndef NDEBUG + FuncName = Fn.getName(); + MatchFilterFuncName = isFunctionInPrintList(FuncName); +#else + (void)MatchFilterFuncName; +#endif + + TII = MF->getSubtarget().getInstrInfo(); + TLI = MF->getSubtarget().getTargetLowering(); + RegInfo = &MF->getRegInfo(); + LibInfo = &MFP.getAnalysis().getTLI(Fn); + GFI = Fn.hasGC() ? &MFP.getAnalysis().getFunctionInfo(Fn) + : nullptr; + ORE = std::make_unique(&Fn); + AC = &MFP.getAnalysis().getAssumptionCache(Fn); + auto *PSI = &MFP.getAnalysis().getPSI(); + BlockFrequencyInfo *BFI = nullptr; + if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOptLevel::None) + BFI = &MFP.getAnalysis().getBFI(); + + FunctionVarLocs const *FnVarLocs = nullptr; + if (isAssignmentTrackingEnabled(*Fn.getParent())) + FnVarLocs = MFP.getAnalysis().getResults(); UniformityInfo *UA = nullptr; - if (auto *UAPass = getAnalysisIfAvailable()) + if (auto *UAPass = MFP.getAnalysisIfAvailable()) UA = &UAPass->getUniformityInfo(); - CurDAG->init(*MF, *ORE, this, LibInfo, UA, PSI, BFI, FnVarLocs); - FuncInfo->set(Fn, *MF, CurDAG); + CurDAG->init(*MF, *ORE, &MFP, LibInfo, UA, PSI, BFI, FnVarLocs); SwiftError->setFunction(*MF); // Now get the optional analyzes if we want to. @@ -473,15 +580,32 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { // ask for passes that have been required anyway. if (UseMBPI && OptLevel != CodeGenOptLevel::None) - FuncInfo->BPI = &getAnalysis().getBPI(); + FuncInfo->BPI = + &MFP.getAnalysis().getBPI(); else FuncInfo->BPI = nullptr; if (OptLevel != CodeGenOptLevel::None) - AA = &getAnalysis().getAAResults(); + AA = &MFP.getAnalysis().getAAResults(); else AA = nullptr; + SP = &MFP.getAnalysis().getLayoutInfo(); + +#ifndef NDEBUG + TTI = &MFP.getAnalysis().getTTI(Fn); +#endif +} + +bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { + const Function &Fn = mf.getFunction(); + + bool InstrRef = mf.shouldUseDebugInstrRef(); + + FuncInfo->set(MF->getFunction(), *MF, CurDAG); + + ISEL_DUMP(dbgs() << "\n\n\n=== " << FuncName << '\n'); + SDB->init(GFI, AA, AC, LibInfo); MF->setHasInlineAsm(false); @@ -776,11 +900,8 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { StringRef GroupName = "sdag"; StringRef GroupDescription = "Instruction Selection and Scheduling"; std::string BlockName; - bool MatchFilterBB = false; (void)MatchFilterBB; -#ifndef NDEBUG - TargetTransformInfo &TTI = - getAnalysis().getTTI(*FuncInfo->Fn); -#endif + bool MatchFilterBB = false; + (void)MatchFilterBB; // Pre-type legalization allow creation of any node types. CurDAG->NewNodesMustHaveLegalTypes = false; @@ -805,7 +926,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI.hasBranchDivergence()) + if (TTI->hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -825,7 +946,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI.hasBranchDivergence()) + if (TTI->hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -847,7 +968,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI.hasBranchDivergence()) + if (TTI->hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -871,7 +992,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI.hasBranchDivergence()) + if (TTI->hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif } @@ -889,7 +1010,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI.hasBranchDivergence()) + if (TTI->hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -905,7 +1026,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI.hasBranchDivergence()) + if (TTI->hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -925,7 +1046,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI.hasBranchDivergence()) + if (TTI->hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif } @@ -945,7 +1066,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI.hasBranchDivergence()) + if (TTI->hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -965,7 +1086,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI.hasBranchDivergence()) + if (TTI->hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -1553,7 +1674,6 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { } // Iterate over all basic blocks in the function. - StackProtector &SP = getAnalysis(); for (const BasicBlock *LLVMBB : RPOT) { if (OptLevel != CodeGenOptLevel::None) { bool AllPredsVisited = true; @@ -1729,7 +1849,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { FastIS->recomputeInsertPt(); } - if (SP.shouldEmitSDCheck(*LLVMBB)) { + if (SP->shouldEmitSDCheck(*LLVMBB)) { bool FunctionBasedInstrumentation = TLI->getSSPStackGuardCheck(*Fn.getParent()); SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->MBBMap[LLVMBB], @@ -1766,7 +1886,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { if (Fn.getParent()->getModuleFlag("eh-asynch")) reportIPToStateForBlocks(MF); - SP.copyToMachineFrameInfo(MF->getFrameInfo()); + SP->copyToMachineFrameInfo(MF->getFrameInfo()); SwiftError->propagateVRegs(); diff --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h index b70fbe42fe5f..0f0a22ec8293 100644 --- a/llvm/lib/Target/AArch64/AArch64.h +++ b/llvm/lib/Target/AArch64/AArch64.h @@ -85,7 +85,7 @@ void initializeAArch64CompressJumpTablesPass(PassRegistry&); void initializeAArch64CondBrTuningPass(PassRegistry &); void initializeAArch64ConditionOptimizerPass(PassRegistry&); void initializeAArch64ConditionalComparesPass(PassRegistry &); -void initializeAArch64DAGToDAGISelPass(PassRegistry &); +void initializeAArch64DAGToDAGISelLegacyPass(PassRegistry &); void initializeAArch64DeadRegisterDefinitionsPass(PassRegistry&); void initializeAArch64ExpandPseudoPass(PassRegistry &); void initializeAArch64GlobalsTaggingPass(PassRegistry &); diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 8fd58f4698d2..248778f98f4c 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -44,13 +44,11 @@ class AArch64DAGToDAGISel : public SelectionDAGISel { const AArch64Subtarget *Subtarget; public: - static char ID; - AArch64DAGToDAGISel() = delete; explicit AArch64DAGToDAGISel(AArch64TargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, tm, OptLevel), Subtarget(nullptr) {} + : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override { Subtarget = &MF.getSubtarget(); @@ -507,11 +505,20 @@ private: bool SelectAllActivePredicate(SDValue N); bool SelectAnyPredicate(SDValue N); }; + +class AArch64DAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit AArch64DAGToDAGISelLegacy(AArch64TargetMachine &tm, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(tm, OptLevel)) {} +}; } // end anonymous namespace -char AArch64DAGToDAGISel::ID = 0; +char AArch64DAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(AArch64DAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(AArch64DAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) /// isIntImmediate - This method tests to see if the node is a constant /// operand. If so Imm will receive the 32-bit value. @@ -6867,7 +6874,7 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) { /// AArch64-specific DAG, ready for instruction scheduling. FunctionPass *llvm::createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel) { - return new AArch64DAGToDAGISel(TM, OptLevel); + return new AArch64DAGToDAGISelLegacy(TM, OptLevel); } /// When \p PredVT is a scalable vector predicate in the form diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 945ab5cf1f30..30f0ceaf674c 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -258,7 +258,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target() { initializeAArch64StackTaggingPass(*PR); initializeAArch64StackTaggingPreRAPass(*PR); initializeAArch64LowerHomogeneousPrologEpilogPass(*PR); - initializeAArch64DAGToDAGISelPass(*PR); + initializeAArch64DAGToDAGISelLegacyPass(*PR); initializeAArch64GlobalsTaggingPass(*PR); } diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.h b/llvm/lib/Target/AMDGPU/AMDGPU.h index 6016bd5187d8..46cc5f349555 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPU.h +++ b/llvm/lib/Target/AMDGPU/AMDGPU.h @@ -81,7 +81,7 @@ struct AMDGPUUseNativeCallsPass : PassInfoMixin { PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -void initializeAMDGPUDAGToDAGISelPass(PassRegistry&); +void initializeAMDGPUDAGToDAGISelLegacyPass(PassRegistry &); void initializeAMDGPUMachineCFGStructurizerPass(PassRegistry&); extern char &AMDGPUMachineCFGStructurizerID; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp index 01ab61a0e407..7c353fd10284 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// #include "AMDGPUCodeGenPassBuilder.h" +#include "AMDGPUISelDAGToDAG.h" #include "AMDGPUTargetMachine.h" +#include "llvm/Analysis/UniformityAnalysis.h" using namespace llvm; @@ -25,6 +27,8 @@ AMDGPUCodeGenPassBuilder::AMDGPUCodeGenPassBuilder( void AMDGPUCodeGenPassBuilder::addPreISel(AddIRPass &addPass) const { // TODO: Add passes pre instruction selection. + // Test only, convert to real IR passes in future. + addPass(RequireAnalysisPass()); } void AMDGPUCodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass, @@ -32,7 +36,7 @@ void AMDGPUCodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass, // TODO: Add AsmPrinter. } -Error AMDGPUCodeGenPassBuilder::addInstSelector(AddMachinePass &) const { - // TODO: Add instruction selector. +Error AMDGPUCodeGenPassBuilder::addInstSelector(AddMachinePass &addPass) const { + addPass(AMDGPUISelDAGToDAGPass(TM)); return Error::success(); } diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp index e35957338da7..3e2581dc904a 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -98,8 +98,9 @@ static SDValue stripExtractLoElt(SDValue In) { } // end anonymous namespace -INITIALIZE_PASS_BEGIN(AMDGPUDAGToDAGISel, "amdgpu-isel", - "AMDGPU DAG->DAG Pattern Instruction Selection", false, false) +INITIALIZE_PASS_BEGIN(AMDGPUDAGToDAGISelLegacy, "amdgpu-isel", + "AMDGPU DAG->DAG Pattern Instruction Selection", false, + false) INITIALIZE_PASS_DEPENDENCY(AMDGPUArgumentUsageInfo) INITIALIZE_PASS_DEPENDENCY(AMDGPUPerfHintAnalysis) INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass) @@ -107,19 +108,20 @@ INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) #endif -INITIALIZE_PASS_END(AMDGPUDAGToDAGISel, "amdgpu-isel", - "AMDGPU DAG->DAG Pattern Instruction Selection", false, false) +INITIALIZE_PASS_END(AMDGPUDAGToDAGISelLegacy, "amdgpu-isel", + "AMDGPU DAG->DAG Pattern Instruction Selection", false, + false) /// This pass converts a legalized DAG into a AMDGPU-specific // DAG, ready for instruction scheduling. FunctionPass *llvm::createAMDGPUISelDag(TargetMachine &TM, CodeGenOptLevel OptLevel) { - return new AMDGPUDAGToDAGISel(TM, OptLevel); + return new AMDGPUDAGToDAGISelLegacy(TM, OptLevel); } AMDGPUDAGToDAGISel::AMDGPUDAGToDAGISel(TargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, TM, OptLevel) { + : SelectionDAGISel(TM, OptLevel) { EnableLateStructurizeCFG = AMDGPUTargetMachine::EnableLateStructurizeCFG; } @@ -200,14 +202,14 @@ bool AMDGPUDAGToDAGISel::fp16SrcZerosHighBits(unsigned Opc) const { } } -void AMDGPUDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { +void AMDGPUDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequired(); #ifdef EXPENSIVE_CHECKS AU.addRequired(); AU.addRequired(); #endif - SelectionDAGISel::getAnalysisUsage(AU); + SelectionDAGISelLegacy::getAnalysisUsage(AU); } bool AMDGPUDAGToDAGISel::matchLoadD16FromBuildVector(SDNode *N) const { @@ -771,10 +773,14 @@ bool AMDGPUDAGToDAGISel::isBaseWithConstantOffset64(SDValue Addr, SDValue &LHS, return false; } -StringRef AMDGPUDAGToDAGISel::getPassName() const { +StringRef AMDGPUDAGToDAGISelLegacy::getPassName() const { return "AMDGPU DAG->DAG Pattern Instruction Selection"; } +AMDGPUISelDAGToDAGPass::AMDGPUISelDAGToDAGPass(TargetMachine &TM) + : SelectionDAGISelPass( + std::make_unique(TM, TM.getOptLevel())) {} + //===----------------------------------------------------------------------===// // Complex Patterns //===----------------------------------------------------------------------===// @@ -3607,4 +3613,9 @@ void AMDGPUDAGToDAGISel::PostprocessISelDAG() { } while (IsModified); } -char AMDGPUDAGToDAGISel::ID = 0; +AMDGPUDAGToDAGISelLegacy::AMDGPUDAGToDAGISelLegacy(TargetMachine &TM, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} + +char AMDGPUDAGToDAGISelLegacy::ID = 0; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h index 53d25b4cf4ca..b5b374b6c047 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h @@ -83,21 +83,14 @@ class AMDGPUDAGToDAGISel : public SelectionDAGISel { bool fp16SrcZerosHighBits(unsigned Opc) const; public: - static char ID; - AMDGPUDAGToDAGISel() = delete; explicit AMDGPUDAGToDAGISel(TargetMachine &TM, CodeGenOptLevel OptLevel); - ~AMDGPUDAGToDAGISel() override = default; - - void getAnalysisUsage(AnalysisUsage &AU) const override; - - bool matchLoadD16FromBuildVector(SDNode *N) const; bool runOnMachineFunction(MachineFunction &MF) override; + bool matchLoadD16FromBuildVector(SDNode *N) const; void PreprocessISelDAG() override; void Select(SDNode *N) override; - StringRef getPassName() const override; void PostprocessISelDAG() override; protected: @@ -288,4 +281,19 @@ protected: #include "AMDGPUGenDAGISel.inc" }; +class AMDGPUISelDAGToDAGPass : public SelectionDAGISelPass { +public: + AMDGPUISelDAGToDAGPass(TargetMachine &TM); +}; + +class AMDGPUDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + + AMDGPUDAGToDAGISelLegacy(TargetMachine &TM, CodeGenOptLevel OptLevel); + + void getAnalysisUsage(AnalysisUsage &AU) const override; + StringRef getPassName() const override; +}; + #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUISELDAGTODAG_H diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def b/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def index 90f36fadf359..57fc3314dd97 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def +++ b/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def @@ -71,3 +71,9 @@ FUNCTION_PASS_WITH_PARAMS( }, parseAMDGPUAtomicOptimizerStrategy, "strategy=dpp|iterative|none") #undef FUNCTION_PASS_WITH_PARAMS + +#ifndef MACHINE_FUNCTION_PASS +#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) +#endif +MACHINE_FUNCTION_PASS("amdgpu-isel", AMDGPUISelDAGToDAGPass(*this)) +#undef MACHINE_FUNCTION_PASS diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index dbbfe34a6386..9c94ca1e4708 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -19,6 +19,7 @@ #include "AMDGPUCtorDtorLowering.h" #include "AMDGPUExportClustering.h" #include "AMDGPUIGroupLP.h" +#include "AMDGPUISelDAGToDAG.h" #include "AMDGPUMacroFusion.h" #include "AMDGPURegBankSelect.h" #include "AMDGPUSplitModule.h" @@ -387,7 +388,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUTarget() { initializeR600ExpandSpecialInstrsPassPass(*PR); initializeR600VectorRegMergerPass(*PR); initializeGlobalISel(*PR); - initializeAMDGPUDAGToDAGISelPass(*PR); + initializeAMDGPUDAGToDAGISelLegacyPass(*PR); initializeGCNDPPCombinePass(*PR); initializeSILowerI1CopiesPass(*PR); initializeAMDGPUGlobalISelDivergenceLoweringPass(*PR); diff --git a/llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp index 293db13f34f6..28bcf72b3b09 100644 --- a/llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp @@ -48,6 +48,17 @@ protected: // Include the pieces autogenerated from the target description. #include "R600GenDAGISel.inc" }; + +class R600DAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit R600DAGToDAGISelLegacy(TargetMachine &TM, CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} +}; + +char R600DAGToDAGISelLegacy::ID = 0; + } // namespace bool R600DAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { @@ -184,5 +195,5 @@ bool R600DAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, // DAG, ready for instruction scheduling. FunctionPass *llvm::createR600ISelDag(TargetMachine &TM, CodeGenOptLevel OptLevel) { - return new R600DAGToDAGISel(TM, OptLevel); + return new R600DAGToDAGISelLegacy(TM, OptLevel); } diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 7cde09cc0b1c..4d8667affdb4 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -3087,9 +3087,12 @@ SDValue SITargetLowering::LowerFormalArguments( if (IsEntryFunc) allocateSystemSGPRs(CCInfo, MF, *Info, CallConv, IsGraphics); - auto &ArgUsageInfo = - DAG.getPass()->getAnalysis(); - ArgUsageInfo.setFuncArgInfo(Fn, Info->getArgInfo()); + // DAG.getPass() returns nullptr when using new pass manager. + // TODO: Use DAG.getMFAM() to access analysis result. + if (DAG.getPass()) { + auto &ArgUsageInfo = DAG.getPass()->getAnalysis(); + ArgUsageInfo.setFuncArgInfo(Fn, Info->getArgInfo()); + } unsigned StackArgSize = CCInfo.getStackSize(); Info->setBytesInStackArgArea(StackArgSize); @@ -3301,9 +3304,13 @@ void SITargetLowering::passSpecialInputs( const AMDGPUFunctionArgInfo *CalleeArgInfo = &AMDGPUArgumentUsageInfo::FixedABIFunctionInfo; if (const Function *CalleeFunc = CLI.CB->getCalledFunction()) { - auto &ArgUsageInfo = - DAG.getPass()->getAnalysis(); - CalleeArgInfo = &ArgUsageInfo.lookupFuncArgInfo(*CalleeFunc); + // DAG.getPass() returns nullptr when using new pass manager. + // TODO: Use DAG.getMFAM() to access analysis result. + if (DAG.getPass()) { + auto &ArgUsageInfo = + DAG.getPass()->getAnalysis(); + CalleeArgInfo = &ArgUsageInfo.lookupFuncArgInfo(*CalleeFunc); + } } // TODO: Unify with private memory register handling. This is complicated by diff --git a/llvm/lib/Target/ARC/ARC.h b/llvm/lib/Target/ARC/ARC.h index b81016d0cee4..459f79c6eacc 100644 --- a/llvm/lib/Target/ARC/ARC.h +++ b/llvm/lib/Target/ARC/ARC.h @@ -27,7 +27,7 @@ FunctionPass *createARCISelDag(ARCTargetMachine &TM, CodeGenOptLevel OptLevel); FunctionPass *createARCExpandPseudosPass(); FunctionPass *createARCOptAddrMode(); FunctionPass *createARCBranchFinalizePass(); -void initializeARCDAGToDAGISelPass(PassRegistry &); +void initializeARCDAGToDAGISelLegacyPass(PassRegistry &); } // end namespace llvm diff --git a/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp b/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp index 17c2d7bb13b4..5e6cfa539b6d 100644 --- a/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp @@ -41,12 +41,10 @@ namespace { class ARCDAGToDAGISel : public SelectionDAGISel { public: - static char ID; - ARCDAGToDAGISel() = delete; ARCDAGToDAGISel(ARCTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, TM, OptLevel) {} + : SelectionDAGISel(TM, OptLevel) {} void Select(SDNode *N) override; @@ -60,17 +58,25 @@ public: #include "ARCGenDAGISel.inc" }; -char ARCDAGToDAGISel::ID; +class ARCDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit ARCDAGToDAGISelLegacy(ARCTargetMachine &TM, CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} +}; + +char ARCDAGToDAGISelLegacy::ID; } // end anonymous namespace -INITIALIZE_PASS(ARCDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(ARCDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) /// This pass converts a legalized DAG into a ARC-specific DAG, ready for /// instruction scheduling. FunctionPass *llvm::createARCISelDag(ARCTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new ARCDAGToDAGISel(TM, OptLevel); + return new ARCDAGToDAGISelLegacy(TM, OptLevel); } bool ARCDAGToDAGISel::SelectAddrModeImm(SDValue Addr, SDValue &Base, diff --git a/llvm/lib/Target/ARC/ARCTargetMachine.cpp b/llvm/lib/Target/ARC/ARCTargetMachine.cpp index f50c3c0265e3..5f021cf1f442 100644 --- a/llvm/lib/Target/ARC/ARCTargetMachine.cpp +++ b/llvm/lib/Target/ARC/ARCTargetMachine.cpp @@ -97,7 +97,7 @@ MachineFunctionInfo *ARCTargetMachine::createMachineFunctionInfo( extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARCTarget() { RegisterTargetMachine X(getTheARCTarget()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeARCDAGToDAGISelPass(PR); + initializeARCDAGToDAGISelLegacyPass(PR); } TargetTransformInfo diff --git a/llvm/lib/Target/ARM/ARM.h b/llvm/lib/Target/ARM/ARM.h index b96e01822985..0b7045eadde7 100644 --- a/llvm/lib/Target/ARM/ARM.h +++ b/llvm/lib/Target/ARM/ARM.h @@ -64,7 +64,7 @@ void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, void initializeARMBlockPlacementPass(PassRegistry &); void initializeARMBranchTargetsPass(PassRegistry &); void initializeARMConstantIslandsPass(PassRegistry &); -void initializeARMDAGToDAGISelPass(PassRegistry &); +void initializeARMDAGToDAGISelLegacyPass(PassRegistry &); void initializeARMExpandPseudoPass(PassRegistry &); void initializeARMFixCortexA57AES1742098Pass(PassRegistry &); void initializeARMLoadStoreOptPass(PassRegistry &); diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp index 20dd3e7baf84..7ffc64378ef4 100644 --- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -59,12 +59,10 @@ class ARMDAGToDAGISel : public SelectionDAGISel { const ARMSubtarget *Subtarget; public: - static char ID; - ARMDAGToDAGISel() = delete; explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, tm, OptLevel) {} + : SelectionDAGISel(tm, OptLevel) {} bool runOnMachineFunction(MachineFunction &MF) override { // Reset the subtarget each time through. @@ -362,11 +360,19 @@ private: /// selected when N would have been selected. void replaceDAGValue(const SDValue &N, SDValue M); }; + +class ARMDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + ARMDAGToDAGISelLegacy(ARMBaseTargetMachine &tm, CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(tm, OptLevel)) {} +}; } -char ARMDAGToDAGISel::ID = 0; +char ARMDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(ARMDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(ARMDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) /// isInt32Immediate - This method tests to see if the node is a 32-bit constant /// operand. If so Imm will receive the 32-bit value. @@ -5886,5 +5892,5 @@ bool ARMDAGToDAGISel::SelectInlineAsmMemoryOperand( /// FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new ARMDAGToDAGISel(TM, OptLevel); + return new ARMDAGToDAGISelLegacy(TM, OptLevel); } diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp index 4ef00df57ef9..7553778c5740 100644 --- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -110,7 +110,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTarget() { initializeARMSLSHardeningPass(Registry); initializeMVELaneInterleavingPass(Registry); initializeARMFixCortexA57AES1742098Pass(Registry); - initializeARMDAGToDAGISelPass(Registry); + initializeARMDAGToDAGISelLegacyPass(Registry); } static std::unique_ptr createTLOF(const Triple &TT) { diff --git a/llvm/lib/Target/AVR/AVR.h b/llvm/lib/Target/AVR/AVR.h index 4b1336ecd661..0e67bb4eb50c 100644 --- a/llvm/lib/Target/AVR/AVR.h +++ b/llvm/lib/Target/AVR/AVR.h @@ -31,7 +31,7 @@ FunctionPass *createAVRExpandPseudoPass(); FunctionPass *createAVRFrameAnalyzerPass(); FunctionPass *createAVRBranchSelectionPass(); -void initializeAVRDAGToDAGISelPass(PassRegistry &); +void initializeAVRDAGToDAGISelLegacyPass(PassRegistry &); void initializeAVRExpandPseudoPass(PassRegistry &); void initializeAVRShiftExpandPass(PassRegistry &); diff --git a/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp b/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp index e67a1e2ed509..d6712eb0b78d 100644 --- a/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp +++ b/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp @@ -34,7 +34,7 @@ public: AVRDAGToDAGISel() = delete; AVRDAGToDAGISel(AVRTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, TM, OptLevel), Subtarget(nullptr) {} + : SelectionDAGISel(TM, OptLevel), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override; @@ -60,11 +60,19 @@ private: const AVRSubtarget *Subtarget; }; +class AVRDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + AVRDAGToDAGISelLegacy(AVRTargetMachine &TM, CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} +}; + } // namespace -char AVRDAGToDAGISel::ID = 0; +char AVRDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(AVRDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(AVRDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) bool AVRDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { Subtarget = &MF.getSubtarget(); @@ -586,5 +594,5 @@ bool AVRDAGToDAGISel::trySelect(SDNode *N) { FunctionPass *llvm::createAVRISelDag(AVRTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new AVRDAGToDAGISel(TM, OptLevel); + return new AVRDAGToDAGISelLegacy(TM, OptLevel); } diff --git a/llvm/lib/Target/AVR/AVRTargetMachine.cpp b/llvm/lib/Target/AVR/AVRTargetMachine.cpp index e0776a6cab43..a8c967f865c0 100644 --- a/llvm/lib/Target/AVR/AVRTargetMachine.cpp +++ b/llvm/lib/Target/AVR/AVRTargetMachine.cpp @@ -95,7 +95,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRTarget() { auto &PR = *PassRegistry::getPassRegistry(); initializeAVRExpandPseudoPass(PR); initializeAVRShiftExpandPass(PR); - initializeAVRDAGToDAGISelPass(PR); + initializeAVRDAGToDAGISelLegacyPass(PR); } const AVRSubtarget *AVRTargetMachine::getSubtargetImpl() const { diff --git a/llvm/lib/Target/BPF/BPF.h b/llvm/lib/Target/BPF/BPF.h index bbdbdbbde532..694d7bacf642 100644 --- a/llvm/lib/Target/BPF/BPF.h +++ b/llvm/lib/Target/BPF/BPF.h @@ -35,7 +35,7 @@ InstructionSelector *createBPFInstructionSelector(const BPFTargetMachine &, const BPFRegisterBankInfo &); void initializeBPFCheckAndAdjustIRPass(PassRegistry&); -void initializeBPFDAGToDAGISelPass(PassRegistry &); +void initializeBPFDAGToDAGISelLegacyPass(PassRegistry &); void initializeBPFMIPeepholePass(PassRegistry &); void initializeBPFMIPreEmitCheckingPass(PassRegistry&); void initializeBPFMIPreEmitPeepholePass(PassRegistry &); diff --git a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp index 7b8bcb2c5866..4cc209bf8ae8 100644 --- a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp +++ b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp @@ -51,7 +51,7 @@ public: BPFDAGToDAGISel() = delete; explicit BPFDAGToDAGISel(BPFTargetMachine &TM) - : SelectionDAGISel(ID, TM), Subtarget(nullptr) {} + : SelectionDAGISel(TM), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override { // Reset the subtarget each time through. @@ -94,11 +94,18 @@ private: // Mapping from ConstantStruct global value to corresponding byte-list values std::map cs_vals_; }; + +class BPFDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + BPFDAGToDAGISelLegacy(BPFTargetMachine &TM) + : SelectionDAGISelLegacy(ID, std::make_unique(TM)) {} +}; } // namespace -char BPFDAGToDAGISel::ID = 0; +char BPFDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(BPFDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(BPFDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) // ComplexPattern used on BPF Load/Store instructions bool BPFDAGToDAGISel::SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) { @@ -489,5 +496,5 @@ void BPFDAGToDAGISel::PreprocessTrunc(SDNode *Node, } FunctionPass *llvm::createBPFISelDag(BPFTargetMachine &TM) { - return new BPFDAGToDAGISel(TM); + return new BPFDAGToDAGISelLegacy(TM); } diff --git a/llvm/lib/Target/BPF/BPFTargetMachine.cpp b/llvm/lib/Target/BPF/BPFTargetMachine.cpp index a7bed69b0f2a..7b73c9f4a1e4 100644 --- a/llvm/lib/Target/BPF/BPFTargetMachine.cpp +++ b/llvm/lib/Target/BPF/BPFTargetMachine.cpp @@ -48,7 +48,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTarget() { initializeGlobalISel(PR); initializeBPFCheckAndAdjustIRPass(PR); initializeBPFMIPeepholePass(PR); - initializeBPFDAGToDAGISelPass(PR); + initializeBPFDAGToDAGISelLegacyPass(PR); } // DataLayout: little or big endian diff --git a/llvm/lib/Target/CSKY/CSKY.h b/llvm/lib/Target/CSKY/CSKY.h index 7ca630c9abaa..21ebf13f2064 100644 --- a/llvm/lib/Target/CSKY/CSKY.h +++ b/llvm/lib/Target/CSKY/CSKY.h @@ -27,7 +27,7 @@ FunctionPass *createCSKYISelDag(CSKYTargetMachine &TM, FunctionPass *createCSKYConstantIslandPass(); void initializeCSKYConstantIslandsPass(PassRegistry &); -void initializeCSKYDAGToDAGISelPass(PassRegistry &); +void initializeCSKYDAGToDAGISelLegacyPass(PassRegistry &); } // namespace llvm diff --git a/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp b/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp index c0c23a45d155..22da80b3eddc 100644 --- a/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp +++ b/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp @@ -28,10 +28,8 @@ class CSKYDAGToDAGISel : public SelectionDAGISel { const CSKYSubtarget *Subtarget; public: - static char ID; - explicit CSKYDAGToDAGISel(CSKYTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, TM, OptLevel) {} + : SelectionDAGISel(TM, OptLevel) {} bool runOnMachineFunction(MachineFunction &MF) override { // Reset the subtarget each time through. @@ -54,11 +52,20 @@ public: #include "CSKYGenDAGISel.inc" }; + +class CSKYDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit CSKYDAGToDAGISelLegacy(CSKYTargetMachine &TM, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} +}; } // namespace -char CSKYDAGToDAGISel::ID = 0; +char CSKYDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(CSKYDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(CSKYDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) void CSKYDAGToDAGISel::Select(SDNode *N) { // If we have a custom node, we have already selected @@ -401,5 +408,5 @@ bool CSKYDAGToDAGISel::SelectInlineAsmMemoryOperand( FunctionPass *llvm::createCSKYISelDag(CSKYTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new CSKYDAGToDAGISel(TM, OptLevel); + return new CSKYDAGToDAGISelLegacy(TM, OptLevel); } diff --git a/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp b/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp index 0bbfabe93147..a756061e307a 100644 --- a/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp +++ b/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp @@ -30,7 +30,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTarget() { PassRegistry *Registry = PassRegistry::getPassRegistry(); initializeCSKYConstantIslandsPass(*Registry); - initializeCSKYDAGToDAGISelPass(*Registry); + initializeCSKYDAGToDAGISelLegacyPass(*Registry); } static std::string computeDataLayout(const Triple &TT) { diff --git a/llvm/lib/Target/Hexagon/Hexagon.h b/llvm/lib/Target/Hexagon/Hexagon.h index 861f61a0bfd2..4a290c798c27 100644 --- a/llvm/lib/Target/Hexagon/Hexagon.h +++ b/llvm/lib/Target/Hexagon/Hexagon.h @@ -22,7 +22,7 @@ namespace llvm { /// Creates a Hexagon-specific Target Transformation Info pass. ImmutablePass *createHexagonTargetTransformInfoPass(const HexagonTargetMachine *TM); - void initializeHexagonDAGToDAGISelPass(PassRegistry &); + void initializeHexagonDAGToDAGISelLegacyPass(PassRegistry &); } // end namespace llvm; #endif diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index 6fe3fe0d36b9..febbc95ec0db 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -60,13 +60,18 @@ namespace llvm { /// Hexagon-specific DAG, ready for instruction scheduling. FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new HexagonDAGToDAGISel(TM, OptLevel); + return new HexagonDAGToDAGISelLegacy(TM, OptLevel); } } -char HexagonDAGToDAGISel::ID = 0; +HexagonDAGToDAGISelLegacy::HexagonDAGToDAGISelLegacy(HexagonTargetMachine &tm, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(tm, OptLevel)) {} -INITIALIZE_PASS(HexagonDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +char HexagonDAGToDAGISelLegacy::ID = 0; + +INITIALIZE_PASS(HexagonDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) void HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl) { SDValue Chain = LD->getChain(); diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h index 50162b107996..2d23aeecda6d 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h @@ -29,14 +29,13 @@ class HexagonDAGToDAGISel : public SelectionDAGISel { const HexagonSubtarget *HST; const HexagonInstrInfo *HII; const HexagonRegisterInfo *HRI; -public: - static char ID; +public: HexagonDAGToDAGISel() = delete; explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, tm, OptLevel), HST(nullptr), HII(nullptr), + : SelectionDAGISel(tm, OptLevel), HST(nullptr), HII(nullptr), HRI(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override { @@ -162,6 +161,13 @@ private: SDValue balanceSubTree(SDNode *N, bool Factorize = false); void rebalanceAddressTrees(); }; // end HexagonDAGToDAGISel + +class HexagonDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit HexagonDAGToDAGISelLegacy(HexagonTargetMachine &tm, + CodeGenOptLevel OptLevel); +}; } #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H diff --git a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp index 3a792ecfd03d..e4886506de19 100644 --- a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -254,7 +254,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonTarget() { initializeHexagonVectorCombineLegacyPass(PR); initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PR); initializeHexagonVExtractPass(PR); - initializeHexagonDAGToDAGISelPass(PR); + initializeHexagonDAGToDAGISelLegacyPass(PR); } HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, diff --git a/llvm/lib/Target/Lanai/Lanai.h b/llvm/lib/Target/Lanai/Lanai.h index 0f87b17b773e..72a7efc58062 100644 --- a/llvm/lib/Target/Lanai/Lanai.h +++ b/llvm/lib/Target/Lanai/Lanai.h @@ -37,7 +37,7 @@ FunctionPass *createLanaiMemAluCombinerPass(); // operations. FunctionPass *createLanaiSetflagAluCombinerPass(); -void initializeLanaiDAGToDAGISelPass(PassRegistry &); +void initializeLanaiDAGToDAGISelLegacyPass(PassRegistry &); } // namespace llvm diff --git a/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp b/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp index 6f5495ac00e1..84b57d90af89 100644 --- a/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp +++ b/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp @@ -53,11 +53,7 @@ public: LanaiDAGToDAGISel() = delete; explicit LanaiDAGToDAGISel(LanaiTargetMachine &TargetMachine) - : SelectionDAGISel(ID, TargetMachine) {} - - bool runOnMachineFunction(MachineFunction &MF) override { - return SelectionDAGISel::runOnMachineFunction(MF); - } + : SelectionDAGISel(TargetMachine) {} bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintCode, @@ -97,11 +93,18 @@ bool canBeRepresentedAsSls(const ConstantSDNode &CN) { return isInt<21>(CN.getSExtValue()) && ((CN.getSExtValue() & 0x3) == 0); } +class LanaiDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit LanaiDAGToDAGISelLegacy(LanaiTargetMachine &TM) + : SelectionDAGISelLegacy(ID, std::make_unique(TM)) {} +}; + } // namespace -char LanaiDAGToDAGISel::ID = 0; +char LanaiDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(LanaiDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(LanaiDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) // Helper functions for ComplexPattern used on LanaiInstrInfo // Used on Lanai Load/Store instructions. @@ -366,5 +369,5 @@ void LanaiDAGToDAGISel::selectFrameIndex(SDNode *Node) { // createLanaiISelDag - This pass converts a legalized DAG into a // Lanai-specific DAG, ready for instruction scheduling. FunctionPass *llvm::createLanaiISelDag(LanaiTargetMachine &TM) { - return new LanaiDAGToDAGISel(TM); + return new LanaiDAGToDAGISelLegacy(TM); } diff --git a/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp b/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp index 2357221b0120..68eb12f87d89 100644 --- a/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp +++ b/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp @@ -37,7 +37,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiTarget() { RegisterTargetMachine registered_target( getTheLanaiTarget()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeLanaiDAGToDAGISelPass(PR); + initializeLanaiDAGToDAGISelLegacyPass(PR); } static std::string computeDataLayout() { diff --git a/llvm/lib/Target/LoongArch/LoongArch.h b/llvm/lib/Target/LoongArch/LoongArch.h index 2109176d4998..0928ea31054a 100644 --- a/llvm/lib/Target/LoongArch/LoongArch.h +++ b/llvm/lib/Target/LoongArch/LoongArch.h @@ -38,7 +38,7 @@ FunctionPass *createLoongArchISelDag(LoongArchTargetMachine &TM); FunctionPass *createLoongArchOptWInstrsPass(); FunctionPass *createLoongArchPreRAExpandPseudoPass(); FunctionPass *createLoongArchExpandPseudoPass(); -void initializeLoongArchDAGToDAGISelPass(PassRegistry &); +void initializeLoongArchDAGToDAGISelLegacyPass(PassRegistry &); void initializeLoongArchExpandAtomicPseudoPass(PassRegistry &); void initializeLoongArchOptWInstrsPass(PassRegistry &); void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &); diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp index 726856bda5dc..b6ade6b978d2 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp @@ -22,9 +22,14 @@ using namespace llvm; #define DEBUG_TYPE "loongarch-isel" #define PASS_NAME "LoongArch DAG->DAG Pattern Instruction Selection" -char LoongArchDAGToDAGISel::ID; +char LoongArchDAGToDAGISelLegacy::ID; -INITIALIZE_PASS(LoongArchDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +LoongArchDAGToDAGISelLegacy::LoongArchDAGToDAGISelLegacy( + LoongArchTargetMachine &TM) + : SelectionDAGISelLegacy(ID, std::make_unique(TM)) {} + +INITIALIZE_PASS(LoongArchDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, + false) void LoongArchDAGToDAGISel::Select(SDNode *Node) { // If we have a custom node, we have already selected. @@ -414,5 +419,5 @@ bool LoongArchDAGToDAGISel::selectVSplatUimmPow2(SDValue N, // This pass converts a legalized DAG into a LoongArch-specific DAG, ready // for instruction scheduling. FunctionPass *llvm::createLoongArchISelDag(LoongArchTargetMachine &TM) { - return new LoongArchDAGToDAGISel(TM); + return new LoongArchDAGToDAGISelLegacy(TM); } diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h index 48a178bfeb95..5c199a57de48 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h @@ -29,7 +29,7 @@ public: LoongArchDAGToDAGISel() = delete; explicit LoongArchDAGToDAGISel(LoongArchTargetMachine &TM) - : SelectionDAGISel(ID, TM) {} + : SelectionDAGISel(TM) {} bool runOnMachineFunction(MachineFunction &MF) override { Subtarget = &MF.getSubtarget(); @@ -69,6 +69,12 @@ public: #include "LoongArchGenDAGISel.inc" }; +class LoongArchDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit LoongArchDAGToDAGISelLegacy(LoongArchTargetMachine &TM); +}; + } // end namespace llvm #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp index 2b2d4e478cc8..83466d53f84d 100644 --- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp @@ -36,7 +36,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() { auto *PR = PassRegistry::getPassRegistry(); initializeLoongArchOptWInstrsPass(*PR); initializeLoongArchPreRAExpandPseudoPass(*PR); - initializeLoongArchDAGToDAGISelPass(*PR); + initializeLoongArchDAGToDAGISelLegacyPass(*PR); } static cl::opt diff --git a/llvm/lib/Target/M68k/M68k.h b/llvm/lib/Target/M68k/M68k.h index 1d0f383dc5c9..5db9d796d1d3 100644 --- a/llvm/lib/Target/M68k/M68k.h +++ b/llvm/lib/Target/M68k/M68k.h @@ -46,7 +46,7 @@ InstructionSelector * createM68kInstructionSelector(const M68kTargetMachine &, const M68kSubtarget &, const M68kRegisterBankInfo &); -void initializeM68kDAGToDAGISelPass(PassRegistry &); +void initializeM68kDAGToDAGISelLegacyPass(PassRegistry &); void initializeM68kExpandPseudoPass(PassRegistry &); void initializeM68kGlobalBaseRegPass(PassRegistry &); void initializeM68kCollapseMOVEMPass(PassRegistry &); diff --git a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp index e3aa9cb50847..dc89fec8108c 100644 --- a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp +++ b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp @@ -174,12 +174,10 @@ namespace { class M68kDAGToDAGISel : public SelectionDAGISel { public: - static char ID; - M68kDAGToDAGISel() = delete; explicit M68kDAGToDAGISel(M68kTargetMachine &TM) - : SelectionDAGISel(ID, TM), Subtarget(nullptr) {} + : SelectionDAGISel(TM), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override; bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const override; @@ -316,11 +314,18 @@ private: SDNode *getGlobalBaseReg(); }; -char M68kDAGToDAGISel::ID; +class M68kDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit M68kDAGToDAGISelLegacy(M68kTargetMachine &TM) + : SelectionDAGISelLegacy(ID, std::make_unique(TM)) {} +}; + +char M68kDAGToDAGISelLegacy::ID; } // namespace -INITIALIZE_PASS(M68kDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(M68kDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) bool M68kDAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const { @@ -357,7 +362,7 @@ bool M68kDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { /// This pass converts a legalized DAG into a M68k-specific DAG, /// ready for instruction scheduling. FunctionPass *llvm::createM68kISelDag(M68kTargetMachine &TM) { - return new M68kDAGToDAGISel(TM); + return new M68kDAGToDAGISelLegacy(TM); } static bool doesDispFitFI(M68kISelAddressMode &AM) { diff --git a/llvm/lib/Target/M68k/M68kTargetMachine.cpp b/llvm/lib/Target/M68k/M68kTargetMachine.cpp index bbbcb1556ed5..b65de5e177b5 100644 --- a/llvm/lib/Target/M68k/M68kTargetMachine.cpp +++ b/llvm/lib/Target/M68k/M68kTargetMachine.cpp @@ -37,7 +37,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kTarget() { RegisterTargetMachine X(getTheM68kTarget()); auto *PR = PassRegistry::getPassRegistry(); initializeGlobalISel(*PR); - initializeM68kDAGToDAGISelPass(*PR); + initializeM68kDAGToDAGISelLegacyPass(*PR); initializeM68kExpandPseudoPass(*PR); initializeM68kGlobalBaseRegPass(*PR); initializeM68kCollapseMOVEMPass(*PR); diff --git a/llvm/lib/Target/MSP430/MSP430.h b/llvm/lib/Target/MSP430/MSP430.h index 60685b6704ba..019835908db8 100644 --- a/llvm/lib/Target/MSP430/MSP430.h +++ b/llvm/lib/Target/MSP430/MSP430.h @@ -43,7 +43,7 @@ FunctionPass *createMSP430ISelDag(MSP430TargetMachine &TM, FunctionPass *createMSP430BranchSelectionPass(); -void initializeMSP430DAGToDAGISelPass(PassRegistry &); +void initializeMSP430DAGToDAGISelLegacyPass(PassRegistry &); } // namespace llvm diff --git a/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp index efb23b1a4e3f..7be51d98d97d 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp @@ -91,12 +91,10 @@ namespace { namespace { class MSP430DAGToDAGISel : public SelectionDAGISel { public: - static char ID; - MSP430DAGToDAGISel() = delete; MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, TM, OptLevel) {} + : SelectionDAGISel(TM, OptLevel) {} private: bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); @@ -119,18 +117,26 @@ namespace { bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp); }; + + class MSP430DAGToDAGISelLegacy : public SelectionDAGISelLegacy { + public: + static char ID; + MSP430DAGToDAGISelLegacy(MSP430TargetMachine &TM, CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} + }; } // end anonymous namespace -char MSP430DAGToDAGISel::ID; +char MSP430DAGToDAGISelLegacy::ID; -INITIALIZE_PASS(MSP430DAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(MSP430DAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) /// createMSP430ISelDag - This pass converts a legalized DAG into a /// MSP430-specific DAG, ready for instruction scheduling. /// FunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM, CodeGenOptLevel OptLevel) { - return new MSP430DAGToDAGISel(TM, OptLevel); + return new MSP430DAGToDAGISelLegacy(TM, OptLevel); } /// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode. diff --git a/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp b/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp index ed0fcf7110b7..f307c3765150 100644 --- a/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp +++ b/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp @@ -26,7 +26,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430Target() { // Register the target. RegisterTargetMachine X(getTheMSP430Target()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeMSP430DAGToDAGISelPass(PR); + initializeMSP430DAGToDAGISelLegacyPass(PR); } static Reloc::Model getEffectiveRelocModel(std::optional RM) { diff --git a/llvm/lib/Target/Mips/Mips.h b/llvm/lib/Target/Mips/Mips.h index f0cf039928c1..36a17334ae3b 100644 --- a/llvm/lib/Target/Mips/Mips.h +++ b/llvm/lib/Target/Mips/Mips.h @@ -47,7 +47,7 @@ InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &, void initializeMicroMipsSizeReducePass(PassRegistry &); void initializeMipsBranchExpansionPass(PassRegistry &); -void initializeMipsDAGToDAGISelPass(PassRegistry &); +void initializeMipsDAGToDAGISelLegacyPass(PassRegistry &); void initializeMipsDelaySlotFillerPass(PassRegistry &); void initializeMipsMulMulBugFixPass(PassRegistry &); void initializeMipsPostLegalizerCombinerPass(PassRegistry &); diff --git a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp index 0be9b94187a2..b8e6dcefe622 100644 --- a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp @@ -219,7 +219,11 @@ bool Mips16DAGToDAGISel::trySelect(SDNode *Node) { return false; } +Mips16DAGToDAGISelLegacy::Mips16DAGToDAGISelLegacy(MipsTargetMachine &TM, + CodeGenOptLevel OL) + : MipsDAGToDAGISelLegacy(std::make_unique(TM, OL)) {} + FunctionPass *llvm::createMips16ISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new Mips16DAGToDAGISel(TM, OptLevel); + return new Mips16DAGToDAGISelLegacy(TM, OptLevel); } diff --git a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h index c6d3bde68806..ec6e74568c56 100644 --- a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h @@ -47,6 +47,11 @@ private: void initMips16SPAliasReg(MachineFunction &MF); }; +class Mips16DAGToDAGISelLegacy : public MipsDAGToDAGISelLegacy { +public: + explicit Mips16DAGToDAGISelLegacy(MipsTargetMachine &TM, CodeGenOptLevel OL); +}; + FunctionPass *createMips16ISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel); } diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index 01b41f3b2159..f6f32fde3b77 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -49,11 +49,11 @@ using namespace llvm; // instructions for SelectionDAG operations. //===----------------------------------------------------------------------===// -void MipsDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { +void MipsDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const { // There are multiple MipsDAGToDAGISel instances added to the pass pipeline. // We need to preserve StackProtector for the next one. AU.addPreserved(); - SelectionDAGISel::getAnalysisUsage(AU); + SelectionDAGISelLegacy::getAnalysisUsage(AU); } bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { @@ -344,6 +344,10 @@ bool MipsDAGToDAGISel::isUnneededShiftMask(SDNode *N, return (Known.Zero | RHS).countr_one() >= ShAmtBits; } -char MipsDAGToDAGISel::ID = 0; +char MipsDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(MipsDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +MipsDAGToDAGISelLegacy::MipsDAGToDAGISelLegacy( + std::unique_ptr S) + : SelectionDAGISelLegacy(ID, std::move(S)) {} + +INITIALIZE_PASS(MipsDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h index 52207d0f6284..6135f9680785 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h @@ -30,17 +30,13 @@ namespace llvm { class MipsDAGToDAGISel : public SelectionDAGISel { public: - static char ID; - MipsDAGToDAGISel() = delete; explicit MipsDAGToDAGISel(MipsTargetMachine &TM, CodeGenOptLevel OL) - : SelectionDAGISel(ID, TM, OL), Subtarget(nullptr) {} + : SelectionDAGISel(TM, OL), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override; - void getAnalysisUsage(AnalysisUsage &AU) const override; - protected: SDNode *getGlobalBaseReg(); @@ -145,6 +141,13 @@ private: std::vector &OutOps) override; bool isUnneededShiftMask(SDNode *N, unsigned ShAmtBits) const; }; + +class MipsDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + MipsDAGToDAGISelLegacy(std::unique_ptr S); + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; } #endif diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index ab39d1b661ef..7ad300c6cccd 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -44,9 +44,9 @@ bool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { return MipsDAGToDAGISel::runOnMachineFunction(MF); } -void MipsSEDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { +void MipsSEDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); - SelectionDAGISel::getAnalysisUsage(AU); + SelectionDAGISelLegacy::getAnalysisUsage(AU); } void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, @@ -1439,7 +1439,11 @@ bool MipsSEDAGToDAGISel::SelectInlineAsmMemoryOperand( return true; } +MipsSEDAGToDAGISelLegacy::MipsSEDAGToDAGISelLegacy(MipsTargetMachine &TM, + CodeGenOptLevel OL) + : MipsDAGToDAGISelLegacy(std::make_unique(TM, OL)) {} + FunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new MipsSEDAGToDAGISel(TM, OptLevel); + return new MipsSEDAGToDAGISelLegacy(TM, OptLevel); } diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index 96dc876cb753..7b843b0e0b25 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -27,8 +27,6 @@ private: bool runOnMachineFunction(MachineFunction &MF) override; - void getAnalysisUsage(AnalysisUsage &AU) const override; - void addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, MachineFunction &MF); @@ -139,6 +137,12 @@ private: std::vector &OutOps) override; }; +class MipsSEDAGToDAGISelLegacy : public MipsDAGToDAGISelLegacy { +public: + explicit MipsSEDAGToDAGISelLegacy(MipsTargetMachine &TM, CodeGenOptLevel OL); + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + FunctionPass *createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel); } diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp index 4c4bf70e22c6..9515e506c73e 100644 --- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp +++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp @@ -67,7 +67,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTarget() { initializeMipsPreLegalizerCombinerPass(*PR); initializeMipsPostLegalizerCombinerPass(*PR); initializeMipsMulMulBugFixPass(*PR); - initializeMipsDAGToDAGISelPass(*PR); + initializeMipsDAGToDAGISelLegacyPass(*PR); } static std::string computeDataLayout(const Triple &TT, StringRef CPU, diff --git a/llvm/lib/Target/NVPTX/NVPTX.h b/llvm/lib/Target/NVPTX/NVPTX.h index 07ee34968b02..5eefab59a6ab 100644 --- a/llvm/lib/Target/NVPTX/NVPTX.h +++ b/llvm/lib/Target/NVPTX/NVPTX.h @@ -194,7 +194,7 @@ enum PrmtMode { }; } } -void initializeNVPTXDAGToDAGISelPass(PassRegistry &); +void initializeNVPTXDAGToDAGISelLegacyPass(PassRegistry &); } // namespace llvm // Defines symbolic names for NVPTX registers. This defines a mapping from diff --git a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp index 2713b6859ff3..1e1cbb15e33d 100644 --- a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp @@ -38,16 +38,21 @@ static cl::opt /// NVPTX-specific DAG, ready for instruction scheduling. FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM, llvm::CodeGenOptLevel OptLevel) { - return new NVPTXDAGToDAGISel(TM, OptLevel); + return new NVPTXDAGToDAGISelLegacy(TM, OptLevel); } -char NVPTXDAGToDAGISel::ID = 0; +NVPTXDAGToDAGISelLegacy::NVPTXDAGToDAGISelLegacy(NVPTXTargetMachine &tm, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(tm, OptLevel)) {} -INITIALIZE_PASS(NVPTXDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +char NVPTXDAGToDAGISelLegacy::ID = 0; + +INITIALIZE_PASS(NVPTXDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, tm, OptLevel), TM(tm) { + : SelectionDAGISel(tm, OptLevel), TM(tm) { doMulWide = (OptLevel > CodeGenOptLevel::None); } diff --git a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h index 7a7774744bc7..c5524351f2ff 100644 --- a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h +++ b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h @@ -39,8 +39,6 @@ class LLVM_LIBRARY_VISIBILITY NVPTXDAGToDAGISel : public SelectionDAGISel { bool doRsqrtOpt() const; public: - static char ID; - NVPTXDAGToDAGISel() = delete; explicit NVPTXDAGToDAGISel(NVPTXTargetMachine &tm, CodeGenOptLevel OptLevel); @@ -101,6 +99,13 @@ private: static unsigned GetConvertOpcode(MVT DestTy, MVT SrcTy, LoadSDNode *N); }; + +class NVPTXDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit NVPTXDAGToDAGISelLegacy(NVPTXTargetMachine &tm, + CodeGenOptLevel OptLevel); +}; } // end namespace llvm #endif diff --git a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp index 2a47c16a6bce..4dc3cea4bd8e 100644 --- a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp @@ -103,7 +103,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeNVPTXTarget() { initializeNVPTXCtorDtorLoweringLegacyPass(PR); initializeNVPTXLowerAggrCopiesPass(PR); initializeNVPTXProxyRegErasurePass(PR); - initializeNVPTXDAGToDAGISelPass(PR); + initializeNVPTXDAGToDAGISelLegacyPass(PR); initializeNVPTXAAWrapperPassPass(PR); initializeNVPTXExternalAAWrapperPass(PR); } diff --git a/llvm/lib/Target/PowerPC/PPC.h b/llvm/lib/Target/PowerPC/PPC.h index eb8886dcc907..94a59d14601b 100644 --- a/llvm/lib/Target/PowerPC/PPC.h +++ b/llvm/lib/Target/PowerPC/PPC.h @@ -78,7 +78,7 @@ class ModulePass; void initializePPCMIPeepholePass(PassRegistry&); void initializePPCExpandAtomicPseudoPass(PassRegistry &); void initializePPCCTRLoopsPass(PassRegistry &); - void initializePPCDAGToDAGISelPass(PassRegistry &); + void initializePPCDAGToDAGISelLegacyPass(PassRegistry &); void initializePPCMergeStringPoolPass(PassRegistry &); extern char &PPCVSXFMAMutateID; diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 26560dc5cdeb..275b3337a276 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -147,12 +147,10 @@ namespace { unsigned GlobalBaseReg = 0; public: - static char ID; - PPCDAGToDAGISel() = delete; explicit PPCDAGToDAGISel(PPCTargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, tm, OptLevel), TM(tm) {} + : SelectionDAGISel(tm, OptLevel), TM(tm) {} bool runOnMachineFunction(MachineFunction &MF) override { // Make sure we re-emit a set of the global base reg if necessary @@ -447,11 +445,19 @@ private: void transferMemOperands(SDNode *N, SDNode *Result); }; + class PPCDAGToDAGISelLegacy : public SelectionDAGISelLegacy { + public: + static char ID; + explicit PPCDAGToDAGISelLegacy(PPCTargetMachine &tm, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(tm, OptLevel)) {} + }; } // end anonymous namespace -char PPCDAGToDAGISel::ID = 0; +char PPCDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(PPCDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(PPCDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) /// getGlobalBaseReg - Output the instructions required to put the /// base address to use for accessing globals into a register. @@ -7921,5 +7927,5 @@ void PPCDAGToDAGISel::PeepholePPC64() { /// FunctionPass *llvm::createPPCISelDag(PPCTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new PPCDAGToDAGISel(TM, OptLevel); + return new PPCDAGToDAGISelLegacy(TM, OptLevel); } diff --git a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp index 714cf69827a1..1ef891d1b677 100644 --- a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -141,7 +141,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTarget() { initializePPCExpandAtomicPseudoPass(PR); initializeGlobalISel(PR); initializePPCCTRLoopsPass(PR); - initializePPCDAGToDAGISelPass(PR); + initializePPCDAGToDAGISelLegacyPass(PR); initializePPCMergeStringPoolPass(PR); } diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h index dcf4c65c44df..8d2e1fc340c3 100644 --- a/llvm/lib/Target/RISCV/RISCV.h +++ b/llvm/lib/Target/RISCV/RISCV.h @@ -82,7 +82,7 @@ void initializeRISCVPushPopOptPass(PassRegistry &); InstructionSelector *createRISCVInstructionSelector(const RISCVTargetMachine &, RISCVSubtarget &, RISCVRegisterBankInfo &); -void initializeRISCVDAGToDAGISelPass(PassRegistry &); +void initializeRISCVDAGToDAGISelLegacyPass(PassRegistry &); FunctionPass *createRISCVPostLegalizerCombiner(); void initializeRISCVPostLegalizerCombinerPass(PassRegistry &); diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index d965dd4fc9a9..251401db3e28 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -3912,9 +3912,14 @@ bool RISCVDAGToDAGISel::doPeepholeNoRegPassThru() { // for instruction scheduling. FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new RISCVDAGToDAGISel(TM, OptLevel); + return new RISCVDAGToDAGISelLegacy(TM, OptLevel); } -char RISCVDAGToDAGISel::ID = 0; +char RISCVDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(RISCVDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +RISCVDAGToDAGISelLegacy::RISCVDAGToDAGISelLegacy(RISCVTargetMachine &TM, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} + +INITIALIZE_PASS(RISCVDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h index ece04dd7f4b7..5d70245c0c55 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h @@ -25,13 +25,11 @@ class RISCVDAGToDAGISel : public SelectionDAGISel { const RISCVSubtarget *Subtarget = nullptr; public: - static char ID; - RISCVDAGToDAGISel() = delete; explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, TargetMachine, OptLevel) {} + : SelectionDAGISel(TargetMachine, OptLevel) {} bool runOnMachineFunction(MachineFunction &MF) override { Subtarget = &MF.getSubtarget(); @@ -196,6 +194,13 @@ private: bool performCombineVMergeAndVOps(SDNode *N); }; +class RISCVDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit RISCVDAGToDAGISelLegacy(RISCVTargetMachine &TargetMachine, + CodeGenOptLevel OptLevel); +}; + namespace RISCV { struct VLSEGPseudo { uint16_t NF : 4; diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index 87ae2ee0d379..35d0b3408d09 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -123,7 +123,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { initializeRISCVInsertVSETVLIPass(*PR); initializeRISCVInsertReadWriteCSRPass(*PR); initializeRISCVInsertWriteVXRMPass(*PR); - initializeRISCVDAGToDAGISelPass(*PR); + initializeRISCVDAGToDAGISelLegacyPass(*PR); initializeRISCVMoveMergePass(*PR); initializeRISCVPushPopOptPass(*PR); } diff --git a/llvm/lib/Target/Sparc/Sparc.h b/llvm/lib/Target/Sparc/Sparc.h index fca7657871e8..33a803469603 100644 --- a/llvm/lib/Target/Sparc/Sparc.h +++ b/llvm/lib/Target/Sparc/Sparc.h @@ -31,7 +31,7 @@ FunctionPass *createSparcDelaySlotFillerPass(); void LowerSparcMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP); -void initializeSparcDAGToDAGISelPass(PassRegistry &); +void initializeSparcDAGToDAGISelLegacyPass(PassRegistry &); } // namespace llvm namespace llvm { diff --git a/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 3c9841d81b4f..253161194819 100644 --- a/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -35,12 +35,11 @@ class SparcDAGToDAGISel : public SelectionDAGISel { /// Subtarget - Keep a pointer to the Sparc Subtarget around so that we can /// make the right decision when generating code for different targets. const SparcSubtarget *Subtarget = nullptr; -public: - static char ID; +public: SparcDAGToDAGISel() = delete; - explicit SparcDAGToDAGISel(SparcTargetMachine &tm) : SelectionDAGISel(ID, tm) {} + explicit SparcDAGToDAGISel(SparcTargetMachine &tm) : SelectionDAGISel(tm) {} bool runOnMachineFunction(MachineFunction &MF) override { Subtarget = &MF.getSubtarget(); @@ -66,11 +65,18 @@ private: SDNode* getGlobalBaseReg(); bool tryInlineAsm(SDNode *N); }; + +class SparcDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit SparcDAGToDAGISelLegacy(SparcTargetMachine &tm) + : SelectionDAGISelLegacy(ID, std::make_unique(tm)) {} +}; } // end anonymous namespace -char SparcDAGToDAGISel::ID = 0; +char SparcDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(SparcDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(SparcDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) SDNode* SparcDAGToDAGISel::getGlobalBaseReg() { Register GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF); @@ -397,5 +403,5 @@ bool SparcDAGToDAGISel::SelectInlineAsmMemoryOperand( /// SPARC-specific DAG, ready for instruction scheduling. /// FunctionPass *llvm::createSparcISelDag(SparcTargetMachine &TM) { - return new SparcDAGToDAGISel(TM); + return new SparcDAGToDAGISelLegacy(TM); } diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp index 20ddafb0e43d..ea403230bea8 100644 --- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp +++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp @@ -28,7 +28,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcTarget() { RegisterTargetMachine Z(getTheSparcelTarget()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeSparcDAGToDAGISelPass(PR); + initializeSparcDAGToDAGISelLegacyPass(PR); } static cl::opt diff --git a/llvm/lib/Target/SystemZ/SystemZ.h b/llvm/lib/Target/SystemZ/SystemZ.h index d7aa9e4e18cb..8824954ce448 100644 --- a/llvm/lib/Target/SystemZ/SystemZ.h +++ b/llvm/lib/Target/SystemZ/SystemZ.h @@ -199,7 +199,7 @@ FunctionPass *createSystemZPostRewritePass(SystemZTargetMachine &TM); FunctionPass *createSystemZTDCPass(); void initializeSystemZCopyPhysRegsPass(PassRegistry &); -void initializeSystemZDAGToDAGISelPass(PassRegistry &); +void initializeSystemZDAGToDAGISelLegacyPass(PassRegistry &); void initializeSystemZElimComparePass(PassRegistry &); void initializeSystemZLDCleanupPass(PassRegistry &); void initializeSystemZLongBranchPass(PassRegistry &); diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index 1bf23c2e8e41..6c6a9b490d91 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -356,12 +356,10 @@ class SystemZDAGToDAGISel : public SelectionDAGISel { bool shouldSelectForReassoc(SDNode *N) const; public: - static char ID; - SystemZDAGToDAGISel() = delete; SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, TM, OptLevel) {} + : SelectionDAGISel(TM, OptLevel) {} bool runOnMachineFunction(MachineFunction &MF) override { const Function &F = MF.getFunction(); @@ -387,15 +385,24 @@ public: // Include the pieces autogenerated from the target description. #include "SystemZGenDAGISel.inc" }; + +class SystemZDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit SystemZDAGToDAGISelLegacy(SystemZTargetMachine &TM, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} +}; } // end anonymous namespace -char SystemZDAGToDAGISel::ID = 0; +char SystemZDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(SystemZDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(SystemZDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) FunctionPass *llvm::createSystemZISelDag(SystemZTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new SystemZDAGToDAGISel(TM, OptLevel); + return new SystemZDAGToDAGISelLegacy(TM, OptLevel); } // Return true if Val should be selected as a displacement for an address diff --git a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp index dced64d6b21a..6f76839724ee 100644 --- a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp +++ b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp @@ -47,7 +47,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZTarget() { initializeSystemZShortenInstPass(PR); initializeSystemZPostRewritePass(PR); initializeSystemZTDCPassPass(PR); - initializeSystemZDAGToDAGISelPass(PR); + initializeSystemZDAGToDAGISelLegacyPass(PR); } static std::string computeDataLayout(const Triple &TT) { diff --git a/llvm/lib/Target/VE/VE.h b/llvm/lib/Target/VE/VE.h index 6f0243010ba0..ee76c5121d36 100644 --- a/llvm/lib/Target/VE/VE.h +++ b/llvm/lib/Target/VE/VE.h @@ -29,7 +29,7 @@ class VETargetMachine; FunctionPass *createVEISelDag(VETargetMachine &TM); FunctionPass *createLVLGenPass(); -void initializeVEDAGToDAGISelPass(PassRegistry &); +void initializeVEDAGToDAGISelLegacyPass(PassRegistry &); void LowerVEMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP); diff --git a/llvm/lib/Target/VE/VEISelDAGToDAG.cpp b/llvm/lib/Target/VE/VEISelDAGToDAG.cpp index 87646bc1a12f..680bd12fb4b6 100644 --- a/llvm/lib/Target/VE/VEISelDAGToDAG.cpp +++ b/llvm/lib/Target/VE/VEISelDAGToDAG.cpp @@ -34,11 +34,9 @@ class VEDAGToDAGISel : public SelectionDAGISel { const VESubtarget *Subtarget; public: - static char ID; - VEDAGToDAGISel() = delete; - explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(ID, tm) {} + explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {} bool runOnMachineFunction(MachineFunction &MF) override { Subtarget = &MF.getSubtarget(); @@ -70,11 +68,18 @@ private: bool matchADDRrr(SDValue N, SDValue &Base, SDValue &Index); bool matchADDRri(SDValue N, SDValue &Base, SDValue &Offset); }; + +class VEDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit VEDAGToDAGISelLegacy(VETargetMachine &tm) + : SelectionDAGISelLegacy(ID, std::make_unique(tm)) {} +}; } // end anonymous namespace -char VEDAGToDAGISel::ID = 0; +char VEDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(VEDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(VEDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) bool VEDAGToDAGISel::selectADDRrri(SDValue Addr, SDValue &Base, SDValue &Index, SDValue &Offset) { @@ -336,5 +341,5 @@ SDNode *VEDAGToDAGISel::getGlobalBaseReg() { /// VE-specific DAG, ready for instruction scheduling. /// FunctionPass *llvm::createVEISelDag(VETargetMachine &TM) { - return new VEDAGToDAGISel(TM); + return new VEDAGToDAGISelLegacy(TM); } diff --git a/llvm/lib/Target/VE/VETargetMachine.cpp b/llvm/lib/Target/VE/VETargetMachine.cpp index 6f4e137e4d2f..383667bf79e1 100644 --- a/llvm/lib/Target/VE/VETargetMachine.cpp +++ b/llvm/lib/Target/VE/VETargetMachine.cpp @@ -30,7 +30,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVETarget() { RegisterTargetMachine X(getTheVETarget()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeVEDAGToDAGISelPass(PR); + initializeVEDAGToDAGISelLegacyPass(PR); } static std::string computeDataLayout(const Triple &T) { diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h index 7fc8546248f1..8f142fa0928c 100644 --- a/llvm/lib/Target/WebAssembly/WebAssembly.h +++ b/llvm/lib/Target/WebAssembly/WebAssembly.h @@ -67,7 +67,7 @@ void initializeWebAssemblyArgumentMovePass(PassRegistry &); void initializeWebAssemblyCleanCodeAfterTrapPass(PassRegistry &); void initializeWebAssemblyCFGSortPass(PassRegistry &); void initializeWebAssemblyCFGStackifyPass(PassRegistry &); -void initializeWebAssemblyDAGToDAGISelPass(PassRegistry &); +void initializeWebAssemblyDAGToDAGISelLegacyPass(PassRegistry &); void initializeWebAssemblyDebugFixupPass(PassRegistry &); void initializeWebAssemblyExceptionInfoPass(PassRegistry &); void initializeWebAssemblyExplicitLocalsPass(PassRegistry &); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp index 8833aee02a6a..0f06f54f219f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp @@ -42,13 +42,11 @@ class WebAssemblyDAGToDAGISel final : public SelectionDAGISel { const WebAssemblySubtarget *Subtarget; public: - static char ID; - WebAssemblyDAGToDAGISel() = delete; WebAssemblyDAGToDAGISel(WebAssemblyTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, TM, OptLevel), Subtarget(nullptr) {} + : SelectionDAGISel(TM, OptLevel), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override { LLVM_DEBUG(dbgs() << "********** ISelDAGToDAG **********\n" @@ -82,11 +80,21 @@ private: bool SelectAddrAddOperands(MVT OffsetType, SDValue N, SDValue &Offset, SDValue &Addr); }; + +class WebAssemblyDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + explicit WebAssemblyDAGToDAGISelLegacy(WebAssemblyTargetMachine &TM, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} +}; } // end anonymous namespace -char WebAssemblyDAGToDAGISel::ID; +char WebAssemblyDAGToDAGISelLegacy::ID; -INITIALIZE_PASS(WebAssemblyDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(WebAssemblyDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, + false) void WebAssemblyDAGToDAGISel::PreprocessISelDAG() { // Stack objects that should be allocated to locals are hoisted to WebAssembly @@ -409,5 +417,5 @@ bool WebAssemblyDAGToDAGISel::SelectAddrOperands64(SDValue Op, SDValue &Offset, /// for instruction scheduling. FunctionPass *llvm::createWebAssemblyISelDag(WebAssemblyTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new WebAssemblyDAGToDAGISel(TM, OptLevel); + return new WebAssemblyDAGToDAGISelLegacy(TM, OptLevel); } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index fd92a35c2638..23539a5f4b26 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -90,7 +90,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTarget() { initializeWebAssemblyMCLowerPrePassPass(PR); initializeWebAssemblyLowerRefTypesIntPtrConvPass(PR); initializeWebAssemblyFixBrTableDefaultsPass(PR); - initializeWebAssemblyDAGToDAGISelPass(PR); + initializeWebAssemblyDAGToDAGISelLegacyPass(PR); } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h index 21623a805f55..fdb9e4cad5e8 100644 --- a/llvm/lib/Target/X86/X86.h +++ b/llvm/lib/Target/X86/X86.h @@ -179,7 +179,7 @@ void initializeX86AvoidSFBPassPass(PassRegistry &); void initializeX86AvoidTrailingCallPassPass(PassRegistry &); void initializeX86CallFrameOptimizationPass(PassRegistry &); void initializeX86CmovConverterPassPass(PassRegistry &); -void initializeX86DAGToDAGISelPass(PassRegistry &); +void initializeX86DAGToDAGISelLegacyPass(PassRegistry &); void initializeX86DomainReassignmentPass(PassRegistry &); void initializeX86ExecutionDomainFixPass(PassRegistry &); void initializeX86ExpandPseudoPass(PassRegistry &); diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp index 7c1fb0b99f41..cc5937d0bda6 100644 --- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp +++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp @@ -10,10 +10,12 @@ /// TODO: Port CodeGen passes to new pass manager. //===----------------------------------------------------------------------===// +#include "X86ISelDAGToDAG.h" #include "X86TargetMachine.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Passes/CodeGenPassBuilder.h" +#include "llvm/Passes/PassBuilder.h" using namespace llvm; @@ -40,13 +42,20 @@ void X86CodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass, // TODO: Add AsmPrinter. } -Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &) const { +Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &addPass) const { // TODO: Add instruction selector. + addPass(X86ISelDAGToDAGPass(static_cast(TM))); return Error::success(); } } // namespace +void X86TargetMachine::registerPassBuilderCallbacks( + PassBuilder &PB, bool PopulateClassToPassNames) { +#define GET_PASS_REGISTRY "X86PassRegistry.def" +#include "llvm/Passes/TargetPassRegistry.inc" +} + Error X86TargetMachine::buildCodeGenPipeline( ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType, const CGPassBuilderOption &Opt, diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 3227bf75a43f..0bf3294af92a 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "X86ISelDAGToDAG.h" #include "X86.h" #include "X86MachineFunctionInfo.h" #include "X86RegisterInfo.h" @@ -169,12 +170,10 @@ namespace { bool IndirectTlsSegRefs; public: - static char ID; - X86DAGToDAGISel() = delete; explicit X86DAGToDAGISel(X86TargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, tm, OptLevel), Subtarget(nullptr), + : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr), OptForMinSize(false), IndirectTlsSegRefs(false) {} bool runOnMachineFunction(MachineFunction &MF) override { @@ -187,9 +186,7 @@ namespace { OptForMinSize = MF.getFunction().hasMinSize(); assert((!OptForMinSize || MF.getFunction().hasOptSize()) && "OptForMinSize implies OptForSize"); - - SelectionDAGISel::runOnMachineFunction(MF); - return true; + return SelectionDAGISel::runOnMachineFunction(MF); } void emitFunctionEntryCode() override; @@ -577,11 +574,20 @@ namespace { bool hasNoSignFlagUses(SDValue Flags) const; bool hasNoCarryFlagUses(SDValue Flags) const; }; + + class X86DAGToDAGISelLegacy : public SelectionDAGISelLegacy { + public: + static char ID; + explicit X86DAGToDAGISelLegacy(X86TargetMachine &tm, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(tm, OptLevel)) {} + }; } -char X86DAGToDAGISel::ID = 0; +char X86DAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(X86DAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(X86DAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) // Returns true if this masked compare can be implemented legally with this // type. @@ -6593,9 +6599,13 @@ bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand( return false; } +X86ISelDAGToDAGPass::X86ISelDAGToDAGPass(X86TargetMachine &TM) + : SelectionDAGISelPass( + std::make_unique(TM, TM.getOptLevel())) {} + /// This pass converts a legalized DAG into a X86-specific DAG, /// ready for instruction scheduling. FunctionPass *llvm::createX86ISelDag(X86TargetMachine &TM, CodeGenOptLevel OptLevel) { - return new X86DAGToDAGISel(TM, OptLevel); + return new X86DAGToDAGISelLegacy(TM, OptLevel); } diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.h b/llvm/lib/Target/X86/X86ISelDAGToDAG.h new file mode 100644 index 000000000000..1f30c25b502f --- /dev/null +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.h @@ -0,0 +1,25 @@ +//===-- X86ISelDAGToDAG.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_X86_X86ISELDAGTODAG_H +#define LLVM_LIB_TARGET_X86_X86ISELDAGTODAG_H + +#include "llvm/CodeGen/SelectionDAGISel.h" + +namespace llvm { + +class X86TargetMachine; + +class X86ISelDAGToDAGPass : public SelectionDAGISelPass { +public: + X86ISelDAGToDAGPass(X86TargetMachine &TM); +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_X86_X86ISELDAGTODAG_H diff --git a/llvm/lib/Target/X86/X86PassRegistry.def b/llvm/lib/Target/X86/X86PassRegistry.def new file mode 100644 index 000000000000..620526ffc1ab --- /dev/null +++ b/llvm/lib/Target/X86/X86PassRegistry.def @@ -0,0 +1,19 @@ +//===- X86PassRegistry.def - Registry of X86 specific passes ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is used as the registry of passes that are part of the X86 backend. +// +//===----------------------------------------------------------------------===// + +// NOTE: NO INCLUDE GUARD DESIRED! + +#ifndef MACHINE_FUNCTION_PASS +#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) +#endif +MACHINE_FUNCTION_PASS("x86-isel", X86ISelDAGToDAGPass(*this)) +#undef MACHINE_FUNCTION_PASS diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index ab59cf8a309a..27542e54829b 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -100,7 +100,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86Target() { initializeX86PartialReductionPass(PR); initializePseudoProbeInserterPass(PR); initializeX86ReturnThunksPass(PR); - initializeX86DAGToDAGISelPass(PR); + initializeX86DAGToDAGISelLegacyPass(PR); initializeX86ArgumentStackSlotPassPass(PR); initializeX86FixupInstTuningPassPass(PR); initializeX86FixupVectorConstantsPassPass(PR); diff --git a/llvm/lib/Target/X86/X86TargetMachine.h b/llvm/lib/Target/X86/X86TargetMachine.h index 4e7ded16729d..4a5f20fcc017 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.h +++ b/llvm/lib/Target/X86/X86TargetMachine.h @@ -58,6 +58,9 @@ public: createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override; + void registerPassBuilderCallbacks(PassBuilder &PB, + bool PopulateClassToPassNames) override; + Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &, raw_pwrite_stream *, CodeGenFileType, const CGPassBuilderOption &, diff --git a/llvm/lib/Target/XCore/XCore.h b/llvm/lib/Target/XCore/XCore.h index f019fa49f185..ad50f05a89d8 100644 --- a/llvm/lib/Target/XCore/XCore.h +++ b/llvm/lib/Target/XCore/XCore.h @@ -31,7 +31,7 @@ namespace llvm { FunctionPass *createXCoreISelDag(XCoreTargetMachine &TM, CodeGenOptLevel OptLevel); ModulePass *createXCoreLowerThreadLocalPass(); - void initializeXCoreDAGToDAGISelPass(PassRegistry &); + void initializeXCoreDAGToDAGISelLegacyPass(PassRegistry &); } // end namespace llvm; diff --git a/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp b/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp index 1535eb622da6..dcbf1145a5cc 100644 --- a/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp +++ b/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp @@ -41,12 +41,10 @@ namespace { class XCoreDAGToDAGISel : public SelectionDAGISel { public: - static char ID; - XCoreDAGToDAGISel() = delete; XCoreDAGToDAGISel(XCoreTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, TM, OptLevel) {} + : SelectionDAGISel(TM, OptLevel) {} void Select(SDNode *N) override; bool tryBRIND(SDNode *N); @@ -78,18 +76,27 @@ namespace { // Include the pieces autogenerated from the target description. #include "XCoreGenDAGISel.inc" }; + + class XCoreDAGToDAGISelLegacy : public SelectionDAGISelLegacy { + public: + static char ID; + explicit XCoreDAGToDAGISelLegacy(XCoreTargetMachine &TM, + CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} + }; } // end anonymous namespace -char XCoreDAGToDAGISel::ID = 0; +char XCoreDAGToDAGISelLegacy::ID = 0; -INITIALIZE_PASS(XCoreDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(XCoreDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) /// createXCoreISelDag - This pass converts a legalized DAG into a /// XCore-specific DAG, ready for instruction scheduling. /// FunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new XCoreDAGToDAGISel(TM, OptLevel); + return new XCoreDAGToDAGISelLegacy(TM, OptLevel); } bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base, diff --git a/llvm/lib/Target/XCore/XCoreTargetMachine.cpp b/llvm/lib/Target/XCore/XCoreTargetMachine.cpp index 374e91d01bda..bb5beefbb65e 100644 --- a/llvm/lib/Target/XCore/XCoreTargetMachine.cpp +++ b/llvm/lib/Target/XCore/XCoreTargetMachine.cpp @@ -107,7 +107,7 @@ void XCorePassConfig::addPreEmitPass() { extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXCoreTarget() { RegisterTargetMachine X(getTheXCoreTarget()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeXCoreDAGToDAGISelPass(PR); + initializeXCoreDAGToDAGISelLegacyPass(PR); } TargetTransformInfo diff --git a/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp b/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp index 5ebedefafc16..145f28503635 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp @@ -28,14 +28,8 @@ namespace { class XtensaDAGToDAGISel : public SelectionDAGISel { public: - static char ID; - XtensaDAGToDAGISel(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(ID, TM, OptLevel) {} - - StringRef getPassName() const override { - return "Xtensa DAG->DAG Pattern Instruction Selection"; - } + : SelectionDAGISel(TM, OptLevel) {} void Select(SDNode *Node) override; @@ -107,13 +101,26 @@ public: // Include the pieces autogenerated from the target description. #include "XtensaGenDAGISel.inc" }; // namespace + +class XtensaDAGToDAGISelLegacy : public SelectionDAGISelLegacy { +public: + static char ID; + + XtensaDAGToDAGISelLegacy(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel) + : SelectionDAGISelLegacy( + ID, std::make_unique(TM, OptLevel)) {} + + StringRef getPassName() const override { + return "Xtensa DAG->DAG Pattern Instruction Selection"; + } +}; } // end anonymous namespace -char XtensaDAGToDAGISel::ID = 0; +char XtensaDAGToDAGISelLegacy::ID = 0; FunctionPass *llvm::createXtensaISelDag(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new XtensaDAGToDAGISel(TM, OptLevel); + return new XtensaDAGToDAGISelLegacy(TM, OptLevel); } void XtensaDAGToDAGISel::Select(SDNode *Node) { diff --git a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll index 41eb2b7bb274..85a701b23a6c 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll @@ -3,6 +3,10 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908_GFX11 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908_GFX11 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908_GFX11 %s define amdgpu_ps void @buffer_atomic_fadd_f32_offset_no_rtn(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { ; GFX908_GFX11-LABEL: name: buffer_atomic_fadd_f32_offset_no_rtn diff --git a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-rtn.ll b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-rtn.ll index f964da2ddf40..417dee573c5d 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-rtn.ll @@ -1,7 +1,10 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s define amdgpu_ps float @buffer_atomic_fadd_f32_offset_rtn(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { ; GFX90A_GFX940-LABEL: name: buffer_atomic_fadd_f32_offset_rtn diff --git a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll index 89a29526320c..ff087715e0fc 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps void @buffer_atomic_fadd_f64_offset_no_rtn(double %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { ; GFX90A_GFX940-LABEL: name: buffer_atomic_fadd_f64_offset_no_rtn diff --git a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll index 0b62977613f1..44fddc372293 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll @@ -2,6 +2,9 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps void @buffer_atomic_fadd_v2f16_offset_no_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { ; GFX908-LABEL: name: buffer_atomic_fadd_v2f16_offset_no_rtn diff --git a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll index 8c33683c0f5e..c4ef1390a288 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps <2 x half> @buffer_atomic_fadd_v2f16_offset_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { ; GFX90A_GFX940-LABEL: name: buffer_atomic_fadd_v2f16_offset_rtn diff --git a/llvm/test/CodeGen/AMDGPU/buffer-intrinsics-mmo-offsets.ll b/llvm/test/CodeGen/AMDGPU/buffer-intrinsics-mmo-offsets.ll index f4cd19a2ffa8..a62ea8fe4606 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-intrinsics-mmo-offsets.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-intrinsics-mmo-offsets.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -verify-machineinstrs -amdgpu-atomic-optimizer-strategy=None -stop-after=amdgpu-isel -o - %s | FileCheck -check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -enable-new-pm -amdgpu-atomic-optimizer-strategy=None -stop-after=amdgpu-isel -o - %s | FileCheck -check-prefix=GCN %s define amdgpu_cs void @mmo_offsets0(ptr addrspace(6) inreg noalias align(16) dereferenceable(18446744073709551615) %arg0, i32 %arg1) { ; GCN-LABEL: name: mmo_offsets0 diff --git a/llvm/test/CodeGen/AMDGPU/bug-v4f64-subvector.ll b/llvm/test/CodeGen/AMDGPU/bug-v4f64-subvector.ll index 459913eb4f6e..2c7072b8c93b 100644 --- a/llvm/test/CodeGen/AMDGPU/bug-v4f64-subvector.ll +++ b/llvm/test/CodeGen/AMDGPU/bug-v4f64-subvector.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -start-before=amdgpu-isel -stop-after=amdgpu-isel -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK +; RUN: llc < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -stop-after=amdgpu-isel -enable-new-pm | FileCheck %s --check-prefixes=CHECK ; This caused failure in infinite cycle in Selection DAG (combine) due to missing insert_subvector. ; diff --git a/llvm/test/CodeGen/AMDGPU/carryout-selection.ll b/llvm/test/CodeGen/AMDGPU/carryout-selection.ll index 9a22635e880f..a0499ef6d0f6 100644 --- a/llvm/test/CodeGen/AMDGPU/carryout-selection.ll +++ b/llvm/test/CodeGen/AMDGPU/carryout-selection.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN-ISEL %s +; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel -enable-new-pm < %s | FileCheck -enable-var-scope -check-prefixes=GCN-ISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=verde -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=CISI %s ; RUN: llc -mtriple=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=VI %s diff --git a/llvm/test/CodeGen/AMDGPU/dagcombine-fma-crash.ll b/llvm/test/CodeGen/AMDGPU/dagcombine-fma-crash.ll index 09a1f4555760..8b1a6878136a 100644 --- a/llvm/test/CodeGen/AMDGPU/dagcombine-fma-crash.ll +++ b/llvm/test/CodeGen/AMDGPU/dagcombine-fma-crash.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx1030 -start-before=amdgpu-isel -stop-after=amdgpu-isel < %s | FileCheck %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx1030 -enable-new-pm -start-before=amdgpu-isel -stop-after=amdgpu-isel < %s | FileCheck %s define void @main(float %arg) { ; CHECK-LABEL: name: main diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-abs.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-abs.ll index c135acaaf474..4ea553b8aaad 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-abs.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-abs.ll @@ -1,5 +1,7 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX900 %s +; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX900 %s ; GCN-LABEL: name: s_abs_i32 ; GCN: S_ABS_I32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-bitreverse.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-bitreverse.ll index d5597df08aa2..85ae5f13e731 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-bitreverse.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-bitreverse.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; GCN-LABEL: name: uniform_bitreverse_i32 ; GCN: S_BREV_B32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-ctlz-cttz.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-ctlz-cttz.ll index 45cb4c623a4b..030de51abb90 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-ctlz-cttz.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-ctlz-cttz.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; GCN-LABEL: name: s_ctlz_i32 ; GCN: S_FLBIT_I32_B32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-ctpop.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-ctpop.ll index 5c5b7b3e5b9a..4a3a44d09210 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-ctpop.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-ctpop.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; GCN-LABEL: name: s_ctpop_i32 ; GCN: S_BCNT1_I32_B32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll index 2711e532fc16..45c805aa1b80 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; GCN-LABEL: name: uniform_imin ; GCN: S_MIN_I32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-negsubinlineconst.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-negsubinlineconst.ll index a7f3c18accc9..e740bb3d5eef 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-negsubinlineconst.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-negsubinlineconst.ll @@ -1,5 +1,7 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX900 %s +; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX900 %s ; GCN-LABEL: name: uniform_add_SIC ; GCN: S_SUB_I32 killed %{{[0-9]+}}, 32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-not-isel.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-not-isel.ll index f673f2f43d7f..5f0d17d08660 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-not-isel.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-not-isel.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; GCN-LABEL: name: scalar_not_i32 ; GCN: S_NOT_B32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-xnor.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-xnor.ll index ccfc908b4005..e8d8b1eb1abc 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-xnor.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-xnor.ll @@ -1,5 +1,7 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx906 -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN_DL %s +; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx906 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN_DL %s ; GCN-LABEL: name: uniform_xnor_i64 ; GCN: S_XNOR_B64 diff --git a/llvm/test/CodeGen/AMDGPU/extract_subvector_vec4_vec3.ll b/llvm/test/CodeGen/AMDGPU/extract_subvector_vec4_vec3.ll index d0c0d3acf271..1319c526868c 100644 --- a/llvm/test/CodeGen/AMDGPU/extract_subvector_vec4_vec3.ll +++ b/llvm/test/CodeGen/AMDGPU/extract_subvector_vec4_vec3.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 < %s -stop-after=amdgpu-isel | FileCheck -check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 < %s -enable-new-pm -stop-after=amdgpu-isel | FileCheck -check-prefix=GCN %s ; We want to see a BUFFER_LOAD, some register shuffling, and a BUFFER_STORE. ; Specifically, we do not want to see a BUFFER_STORE that says "store into diff --git a/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f32.ll b/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f32.ll index ce4beb8789dc..5eb8620f1ff2 100644 --- a/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f32.ll +++ b/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f32.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s define amdgpu_ps void @flat_atomic_fadd_f32_no_rtn_intrinsic(ptr %ptr, float %data) { ; GFX940-LABEL: name: flat_atomic_fadd_f32_no_rtn_intrinsic diff --git a/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f64.ll b/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f64.ll index afd38136870b..df803ad8470d 100644 --- a/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f64.ll +++ b/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f64.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps void @flat_atomic_fadd_f64_no_rtn_intrinsic(ptr %ptr, double %data) { ; GFX90A_GFX940-LABEL: name: flat_atomic_fadd_f64_no_rtn_intrinsic diff --git a/llvm/test/CodeGen/AMDGPU/fneg-fabs-divergence-driven-isel.ll b/llvm/test/CodeGen/AMDGPU/fneg-fabs-divergence-driven-isel.ll index 07f315ea6cb4..d431503643d6 100644 --- a/llvm/test/CodeGen/AMDGPU/fneg-fabs-divergence-driven-isel.ll +++ b/llvm/test/CodeGen/AMDGPU/fneg-fabs-divergence-driven-isel.ll @@ -1,5 +1,7 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefixes=GCN,SI %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -stop-after=amdgpu-isel < %s | FileCheck -check-prefixes=GCN,FP16 %s +; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefixes=GCN,SI %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefixes=GCN,FP16 %s define amdgpu_kernel void @divergent_fneg_f32(ptr addrspace(1) %out, ptr addrspace(1) %in) { diff --git a/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll b/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll index 666971618a5c..60345c0b4433 100644 --- a/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll @@ -2,6 +2,9 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps void @global_atomic_fadd_v2f16_no_rtn_intrinsic(ptr addrspace(1) %ptr, <2 x half> %data) { ; GFX908-LABEL: name: global_atomic_fadd_v2f16_no_rtn_intrinsic diff --git a/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-rtn.ll b/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-rtn.ll index ae81e97ca39e..c8caf1fe365b 100644 --- a/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-rtn.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps <2 x half> @global_atomic_fadd_v2f16_rtn_intrinsic(ptr addrspace(1) %ptr, <2 x half> %data) { ; GFX90A_GFX940-LABEL: name: global_atomic_fadd_v2f16_rtn_intrinsic diff --git a/llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll b/llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll index 9927f4d166ba..6d1adb9c1f87 100644 --- a/llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll +++ b/llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -start-before=amdgpu-isel -stop-after=amdgpu-isel -verify-machineinstrs < %s | FileCheck %s --check-prefix=GCN +; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -start-before=amdgpu-isel -stop-after=amdgpu-isel -enable-new-pm < %s | FileCheck %s --check-prefix=GCN ; We're really just checking for no crashes ; The feature we're testing for in AdjustWriteMask leaves the image_load as an instruction just post amdgpu-isel diff --git a/llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll b/llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll index 88605785f814..f2858e4ff79c 100644 --- a/llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll +++ b/llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel -verify-machineinstrs -o - %s | FileCheck %s +; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel -enable-new-pm -o - %s | FileCheck %s ; CHECK-LABEL: vcopy_i1_undef ; CHECK: [[IMPDEF0:%[0-9]+]]:sreg_64 = IMPLICIT_DEF diff --git a/llvm/test/CodeGen/AMDGPU/legalize-fp-load-invariant.ll b/llvm/test/CodeGen/AMDGPU/legalize-fp-load-invariant.ll index 55fd8336e967..599488822b64 100644 --- a/llvm/test/CodeGen/AMDGPU/legalize-fp-load-invariant.ll +++ b/llvm/test/CodeGen/AMDGPU/legalize-fp-load-invariant.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=amdgcn -mcpu=tahiti -verify-machineinstrs -stop-after=amdgpu-isel -o - %s | FileCheck -check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -enable-new-pm -stop-after=amdgpu-isel -o - %s | FileCheck -check-prefix=GCN %s ; Type legalization for illegal FP type results was dropping invariant ; and dereferenceable flags. diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll index 18c977bf5100..b4840bce53d2 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2 ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck %s define amdgpu_ps ptr addrspace(8) @basic_raw_buffer(ptr inreg %p) { ; CHECK-LABEL: name: basic_raw_buffer diff --git a/llvm/test/CodeGen/X86/apx/no-rex2-general.ll b/llvm/test/CodeGen/X86/apx/no-rex2-general.ll index 1f92883f4170..805fc7ccaab7 100644 --- a/llvm/test/CodeGen/X86/apx/no-rex2-general.ll +++ b/llvm/test/CodeGen/X86/apx/no-rex2-general.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+sse2,+ssse3,+egpr | FileCheck %s --check-prefix=SSE ; RUN: llc < %s -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+sse2,+ssse3,+egpr,+avx | FileCheck %s --check-prefix=AVX +; RUN: llc < %s -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+sse2,+ssse3,+egpr | FileCheck %s --check-prefix=SSE +; RUN: llc < %s -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+sse2,+ssse3,+egpr,+avx | FileCheck %s --check-prefix=AVX define i32 @map0(ptr nocapture noundef readonly %a, i64 noundef %b) { ; SSE-LABEL: name: map0 diff --git a/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-amx.ll b/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-amx.ll index e082becbc441..5fa4cb4c8826 100644 --- a/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-amx.ll +++ b/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-amx.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+amx-tile,+egpr | FileCheck %s +; RUN: llc < %s -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+amx-tile,+egpr | FileCheck %s define dso_local void @amx(ptr noundef %data) { ; CHECK-LABEL: name: amx diff --git a/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-x87.ll b/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-x87.ll index 10ec184516e7..a9ca591a156c 100644 --- a/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-x87.ll +++ b/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-x87.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=-sse,+egpr | FileCheck %s +; RUN: llc < %s -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=-sse,+egpr | FileCheck %s define void @x87(ptr %0, ptr %1) { ; CHECK-LABEL: name: x87 diff --git a/llvm/test/CodeGen/X86/apx/no-rex2-special.ll b/llvm/test/CodeGen/X86/apx/no-rex2-special.ll index b27794969741..86534427a9ea 100644 --- a/llvm/test/CodeGen/X86/apx/no-rex2-special.ll +++ b/llvm/test/CodeGen/X86/apx/no-rex2-special.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+xsave,+egpr | FileCheck %s +; RUN: llc < %s -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+xsave,+egpr | FileCheck %s define void @test_xsave(ptr %ptr, i32 %hi, i32 %lo) { ; CHECK-LABEL: name: test_xsave diff --git a/llvm/test/tools/llc/new-pm/start-stop.ll b/llvm/test/tools/llc/new-pm/start-stop.ll index ba225d227d4c..9c3b9f009178 100644 --- a/llvm/test/tools/llc/new-pm/start-stop.ll +++ b/llvm/test/tools/llc/new-pm/start-stop.ll @@ -1,5 +1,5 @@ ; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -start-before=mergeicmps -stop-after=gc-lowering -filetype=null %s | FileCheck --match-full-lines %s --check-prefix=NULL ; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -start-before=mergeicmps -stop-after=gc-lowering -o /dev/null %s | FileCheck --match-full-lines %s --check-prefix=OBJ -; NULL: function(mergeicmps,expand-memcmp,gc-lowering) -; OBJ: function(mergeicmps,expand-memcmp,gc-lowering),PrintMIRPreparePass,function(machine-function(print),invalidate) +; NULL: require,require,require,function(verify,loop-mssa(loop-reduce),mergeicmps,expand-memcmp,gc-lowering,ee-instrument,verify) +; OBJ: require,require,require,function(verify,loop-mssa(loop-reduce),mergeicmps,expand-memcmp,gc-lowering,ee-instrument,verify),PrintMIRPreparePass,function(machine-function(print),invalidate) -- GitLab From f63b1d282609df0b4b5ae280b04722c6fecb505e Mon Sep 17 00:00:00 2001 From: paperchalice Date: Sun, 2 Jun 2024 09:23:59 +0800 Subject: [PATCH 025/678] [SelectionDAG] Mark `SelectionDAGISel` destructor virtual (#94132) --- llvm/include/llvm/CodeGen/SelectionDAGISel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h index fe655543a470..4972af927cf1 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h @@ -78,7 +78,7 @@ public: explicit SelectionDAGISel(TargetMachine &tm, CodeGenOptLevel OL = CodeGenOptLevel::Default); - ~SelectionDAGISel(); + virtual ~SelectionDAGISel(); const TargetLowering *getTargetLowering() const { return TLI; } -- GitLab From 3f9ba0004b2a27a721fd4a29364571d91197b82d Mon Sep 17 00:00:00 2001 From: paperchalice Date: Sun, 2 Jun 2024 10:17:24 +0800 Subject: [PATCH 026/678] [BPF] Remove unused ID in `SelectionDAGISel` (#94134) --- llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp index 4cc209bf8ae8..67f98bd7c05b 100644 --- a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp +++ b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp @@ -46,8 +46,6 @@ class BPFDAGToDAGISel : public SelectionDAGISel { const BPFSubtarget *Subtarget; public: - static char ID; - BPFDAGToDAGISel() = delete; explicit BPFDAGToDAGISel(BPFTargetMachine &TM) -- GitLab From de37c06f01772e02465ccc9f538894c76d89a7a1 Mon Sep 17 00:00:00 2001 From: paperchalice Date: Sun, 2 Jun 2024 10:27:50 +0800 Subject: [PATCH 027/678] [Targets] Remove unused ID in *DAGToDAGISel (#94135) --- llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp | 2 -- llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp | 2 -- llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h | 2 -- 3 files changed, 6 deletions(-) diff --git a/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp b/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp index d6712eb0b78d..77db876d47e4 100644 --- a/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp +++ b/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp @@ -29,8 +29,6 @@ namespace { /// Lowers LLVM IR (in DAG form) to AVR MC instructions (in DAG form). class AVRDAGToDAGISel : public SelectionDAGISel { public: - static char ID; - AVRDAGToDAGISel() = delete; AVRDAGToDAGISel(AVRTargetMachine &TM, CodeGenOptLevel OptLevel) diff --git a/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp b/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp index 84b57d90af89..af64e2bf831b 100644 --- a/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp +++ b/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp @@ -48,8 +48,6 @@ namespace { class LanaiDAGToDAGISel : public SelectionDAGISel { public: - static char ID; - LanaiDAGToDAGISel() = delete; explicit LanaiDAGToDAGISel(LanaiTargetMachine &TargetMachine) diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h index 5c199a57de48..363b4f0ca7cf 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h @@ -24,8 +24,6 @@ class LoongArchDAGToDAGISel : public SelectionDAGISel { const LoongArchSubtarget *Subtarget = nullptr; public: - static char ID; - LoongArchDAGToDAGISel() = delete; explicit LoongArchDAGToDAGISel(LoongArchTargetMachine &TM) -- GitLab From 8917afaf0ec2ebe390284e3727e720eaf97967eb Mon Sep 17 00:00:00 2001 From: paperchalice Date: Sun, 2 Jun 2024 14:31:52 +0800 Subject: [PATCH 028/678] Revert "[NewPM][CodeGen] Port selection dag isel to new pass manager" (#94146) This reverts commit de37c06f01772e02465ccc9f538894c76d89a7a1 to de37c06f01772e02465ccc9f538894c76d89a7a1 It still breaks EXPENSIVE_CHECKS build. Sorry. --- llvm/include/llvm/CodeGen/SelectionDAG.h | 12 - llvm/include/llvm/CodeGen/SelectionDAGISel.h | 43 +--- llvm/include/llvm/CodeGen/StackProtector.h | 2 - llvm/include/llvm/Passes/CodeGenPassBuilder.h | 9 +- .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 230 +++++------------- llvm/lib/Target/AArch64/AArch64.h | 2 +- .../Target/AArch64/AArch64ISelDAGToDAG.cpp | 19 +- .../Target/AArch64/AArch64TargetMachine.cpp | 2 +- llvm/lib/Target/AMDGPU/AMDGPU.h | 2 +- .../AMDGPU/AMDGPUCodeGenPassBuilder.cpp | 8 +- llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp | 31 +-- llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h | 24 +- llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def | 6 - .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 3 +- llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp | 13 +- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 19 +- llvm/lib/Target/ARC/ARC.h | 2 +- llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp | 18 +- llvm/lib/Target/ARC/ARCTargetMachine.cpp | 2 +- llvm/lib/Target/ARM/ARM.h | 2 +- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 18 +- llvm/lib/Target/ARM/ARMTargetMachine.cpp | 2 +- llvm/lib/Target/AVR/AVR.h | 2 +- llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp | 18 +- llvm/lib/Target/AVR/AVRTargetMachine.cpp | 2 +- llvm/lib/Target/BPF/BPF.h | 2 +- llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp | 17 +- llvm/lib/Target/BPF/BPFTargetMachine.cpp | 2 +- llvm/lib/Target/CSKY/CSKY.h | 2 +- llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp | 19 +- llvm/lib/Target/CSKY/CSKYTargetMachine.cpp | 2 +- llvm/lib/Target/Hexagon/Hexagon.h | 2 +- .../Target/Hexagon/HexagonISelDAGToDAG.cpp | 11 +- llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h | 12 +- .../Target/Hexagon/HexagonTargetMachine.cpp | 2 +- llvm/lib/Target/Lanai/Lanai.h | 2 +- llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp | 21 +- llvm/lib/Target/Lanai/LanaiTargetMachine.cpp | 2 +- llvm/lib/Target/LoongArch/LoongArch.h | 2 +- .../LoongArch/LoongArchISelDAGToDAG.cpp | 11 +- .../Target/LoongArch/LoongArchISelDAGToDAG.h | 10 +- .../LoongArch/LoongArchTargetMachine.cpp | 2 +- llvm/lib/Target/M68k/M68k.h | 2 +- llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp | 17 +- llvm/lib/Target/M68k/M68kTargetMachine.cpp | 2 +- llvm/lib/Target/MSP430/MSP430.h | 2 +- llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 18 +- .../lib/Target/MSP430/MSP430TargetMachine.cpp | 2 +- llvm/lib/Target/Mips/Mips.h | 2 +- llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp | 6 +- llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h | 5 - llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 12 +- llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 13 +- llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 10 +- llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 8 +- llvm/lib/Target/Mips/MipsTargetMachine.cpp | 2 +- llvm/lib/Target/NVPTX/NVPTX.h | 2 +- llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp | 13 +- llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h | 9 +- llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp | 2 +- llvm/lib/Target/PowerPC/PPC.h | 2 +- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 18 +- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp | 2 +- llvm/lib/Target/RISCV/RISCV.h | 2 +- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 11 +- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 11 +- llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 2 +- llvm/lib/Target/Sparc/Sparc.h | 2 +- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp | 18 +- llvm/lib/Target/Sparc/SparcTargetMachine.cpp | 2 +- llvm/lib/Target/SystemZ/SystemZ.h | 2 +- .../Target/SystemZ/SystemZISelDAGToDAG.cpp | 19 +- .../Target/SystemZ/SystemZTargetMachine.cpp | 2 +- llvm/lib/Target/VE/VE.h | 2 +- llvm/lib/Target/VE/VEISelDAGToDAG.cpp | 17 +- llvm/lib/Target/VE/VETargetMachine.cpp | 2 +- llvm/lib/Target/WebAssembly/WebAssembly.h | 2 +- .../WebAssembly/WebAssemblyISelDAGToDAG.cpp | 20 +- .../WebAssembly/WebAssemblyTargetMachine.cpp | 2 +- llvm/lib/Target/X86/X86.h | 2 +- llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 11 +- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 28 +-- llvm/lib/Target/X86/X86ISelDAGToDAG.h | 25 -- llvm/lib/Target/X86/X86PassRegistry.def | 19 -- llvm/lib/Target/X86/X86TargetMachine.cpp | 2 +- llvm/lib/Target/X86/X86TargetMachine.h | 3 - llvm/lib/Target/XCore/XCore.h | 2 +- llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp | 19 +- llvm/lib/Target/XCore/XCoreTargetMachine.cpp | 2 +- llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp | 25 +- .../AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll | 4 - .../AMDGPU/buffer-atomic-fadd.f32-rtn.ll | 5 +- .../CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll | 2 - .../AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll | 3 - .../AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll | 2 - .../AMDGPU/buffer-intrinsics-mmo-offsets.ll | 1 - .../CodeGen/AMDGPU/bug-v4f64-subvector.ll | 1 - .../test/CodeGen/AMDGPU/carryout-selection.ll | 1 - .../CodeGen/AMDGPU/dagcombine-fma-crash.ll | 1 - .../CodeGen/AMDGPU/divergence-driven-abs.ll | 2 - .../AMDGPU/divergence-driven-bitreverse.ll | 1 - .../AMDGPU/divergence-driven-ctlz-cttz.ll | 1 - .../CodeGen/AMDGPU/divergence-driven-ctpop.ll | 1 - .../AMDGPU/divergence-driven-min-max.ll | 1 - .../divergence-driven-negsubinlineconst.ll | 2 - .../AMDGPU/divergence-driven-not-isel.ll | 1 - .../CodeGen/AMDGPU/divergence-driven-xnor.ll | 2 - .../AMDGPU/extract_subvector_vec4_vec3.ll | 1 - .../CodeGen/AMDGPU/flat-atomic-fadd.f32.ll | 2 - .../CodeGen/AMDGPU/flat-atomic-fadd.f64.ll | 2 - .../fneg-fabs-divergence-driven-isel.ll | 2 - .../AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll | 3 - .../AMDGPU/global-atomic-fadd.v2f16-rtn.ll | 2 - llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll | 1 - llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll | 1 - .../AMDGPU/legalize-fp-load-invariant.ll | 1 - .../AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll | 1 - llvm/test/CodeGen/X86/apx/no-rex2-general.ll | 2 - .../CodeGen/X86/apx/no-rex2-pseudo-amx.ll | 1 - .../CodeGen/X86/apx/no-rex2-pseudo-x87.ll | 1 - llvm/test/CodeGen/X86/apx/no-rex2-special.ll | 1 - llvm/test/tools/llc/new-pm/start-stop.ll | 4 +- 122 files changed, 288 insertions(+), 783 deletions(-) delete mode 100644 llvm/lib/Target/X86/X86ISelDAGToDAG.h delete mode 100644 llvm/lib/Target/X86/X86PassRegistry.def diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 48cb0cdf851c..6d28273029bd 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -29,7 +29,6 @@ #include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineMemOperand.h" -#include "llvm/CodeGen/MachinePassManager.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGenTypes/MachineValueType.h" @@ -231,7 +230,6 @@ class SelectionDAG { const TargetLibraryInfo *LibInfo = nullptr; const FunctionVarLocs *FnVarLocs = nullptr; MachineFunction *MF; - MachineFunctionAnalysisManager *MFAM = nullptr; Pass *SDAGISelPass = nullptr; LLVMContext *Context; CodeGenOptLevel OptLevel; @@ -461,15 +459,6 @@ public: UniformityInfo *UA, ProfileSummaryInfo *PSIin, BlockFrequencyInfo *BFIin, FunctionVarLocs const *FnVarLocs); - void init(MachineFunction &NewMF, OptimizationRemarkEmitter &NewORE, - MachineFunctionAnalysisManager &AM, - const TargetLibraryInfo *LibraryInfo, UniformityInfo *UA, - ProfileSummaryInfo *PSIin, BlockFrequencyInfo *BFIin, - FunctionVarLocs const *FnVarLocs) { - init(NewMF, NewORE, nullptr, LibraryInfo, UA, PSIin, BFIin, FnVarLocs); - MFAM = &AM; - } - void setFunctionLoweringInfo(FunctionLoweringInfo * FuncInfo) { FLI = FuncInfo; } @@ -480,7 +469,6 @@ public: MachineFunction &getMachineFunction() const { return *MF; } const Pass *getPass() const { return SDAGISelPass; } - MachineFunctionAnalysisManager *getMFAM() { return MFAM; } CodeGenOptLevel getOptLevel() const { return OptLevel; } const DataLayout &getDataLayout() const { return MF->getDataLayout(); } diff --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h index 4972af927cf1..837f8bf7263e 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h @@ -15,7 +15,6 @@ #define LLVM_CODEGEN_SELECTIONDAGISEL_H #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachinePassManager.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/IR/BasicBlock.h" #include @@ -25,7 +24,6 @@ class AAResults; class AssumptionCache; class TargetInstrInfo; class TargetMachine; -class SSPLayoutInfo; class SelectionDAGBuilder; class SDValue; class MachineRegisterInfo; @@ -33,7 +31,6 @@ class MachineFunction; class OptimizationRemarkEmitter; class TargetLowering; class TargetLibraryInfo; -class TargetTransformInfo; class FunctionLoweringInfo; class SwiftErrorValueTracking; class GCFunctionInfo; @@ -41,7 +38,7 @@ class ScheduleDAGSDNodes; /// SelectionDAGISel - This is the common base class used for SelectionDAG-based /// pattern-matching instruction selectors. -class SelectionDAGISel { +class SelectionDAGISel : public MachineFunctionPass { public: TargetMachine &TM; const TargetLibraryInfo *LibInfo; @@ -54,10 +51,6 @@ public: AAResults *AA = nullptr; AssumptionCache *AC = nullptr; GCFunctionInfo *GFI = nullptr; - SSPLayoutInfo *SP = nullptr; -#ifndef NDEBUG - TargetTransformInfo *TTI = nullptr; -#endif CodeGenOptLevel OptLevel; const TargetInstrInfo *TII; const TargetLowering *TLI; @@ -74,18 +67,16 @@ public: /// functions. Storing the filter result here so that we only need to do the /// filtering once. bool MatchFilterFuncName = false; - StringRef FuncName; - explicit SelectionDAGISel(TargetMachine &tm, + explicit SelectionDAGISel(char &ID, TargetMachine &tm, CodeGenOptLevel OL = CodeGenOptLevel::Default); - virtual ~SelectionDAGISel(); + ~SelectionDAGISel() override; const TargetLowering *getTargetLowering() const { return TLI; } - void initializeAnalysisResults(MachineFunctionAnalysisManager &MFAM); - void initializeAnalysisResults(MachineFunctionPass &MFP); + void getAnalysisUsage(AnalysisUsage &AU) const override; - virtual bool runOnMachineFunction(MachineFunction &mf); + bool runOnMachineFunction(MachineFunction &MF) override; virtual void emitFunctionEntryCode() {} @@ -526,30 +517,6 @@ private: bool isMorphNodeTo); }; -class SelectionDAGISelLegacy : public MachineFunctionPass { - std::unique_ptr Selector; - -public: - SelectionDAGISelLegacy(char &ID, std::unique_ptr S); - - ~SelectionDAGISelLegacy() override = default; - - void getAnalysisUsage(AnalysisUsage &AU) const override; - - bool runOnMachineFunction(MachineFunction &MF) override; -}; - -class SelectionDAGISelPass : public PassInfoMixin { - std::unique_ptr Selector; - -protected: - SelectionDAGISelPass(std::unique_ptr Selector) - : Selector(std::move(Selector)) {} - -public: - PreservedAnalyses run(MachineFunction &MF, - MachineFunctionAnalysisManager &MFAM); -}; } #endif /* LLVM_CODEGEN_SELECTIONDAGISEL_H */ diff --git a/llvm/include/llvm/CodeGen/StackProtector.h b/llvm/include/llvm/CodeGen/StackProtector.h index dfafc781067d..eb5d9d0caebc 100644 --- a/llvm/include/llvm/CodeGen/StackProtector.h +++ b/llvm/include/llvm/CodeGen/StackProtector.h @@ -109,8 +109,6 @@ public: StackProtector(); - SSPLayoutInfo &getLayoutInfo() { return LayoutInfo; } - void getAnalysisUsage(AnalysisUsage &AU) const override; // Return true if StackProtector is supposed to be handled by SelectionDAG. diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h index afe066101c75..17bea5da48ce 100644 --- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h +++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h @@ -140,9 +140,6 @@ public: } protected: - template - using has_required_t = decltype(std::declval().isRequired()); - template using is_module_pass_t = decltype(std::declval().run( std::declval(), std::declval())); @@ -173,10 +170,8 @@ protected: static_assert((is_detected::value || is_detected::value) && "Only module pass and function pass are supported."); - bool Required = false; - if constexpr (is_detected::value) - Required = PassT::isRequired(); - if (!PB.runBeforeAdding(Name) && !Required) + + if (!PB.runBeforeAdding(Name)) return; // Add Function Pass diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 2c1e557ca109..8addaf1ae3e5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -341,49 +341,9 @@ void TargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, // SelectionDAGISel code //===----------------------------------------------------------------------===// -SelectionDAGISelLegacy::SelectionDAGISelLegacy( - char &ID, std::unique_ptr S) - : MachineFunctionPass(ID), Selector(std::move(S)) { - initializeGCModuleInfoPass(*PassRegistry::getPassRegistry()); - initializeBranchProbabilityInfoWrapperPassPass( - *PassRegistry::getPassRegistry()); - initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry()); - initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); -} - -bool SelectionDAGISelLegacy::runOnMachineFunction(MachineFunction &MF) { - // If we already selected that function, we do not need to run SDISel. - if (MF.getProperties().hasProperty( - MachineFunctionProperties::Property::Selected)) - return false; - - // Do some sanity-checking on the command-line options. - if (EnableFastISelAbort && !Selector->TM.Options.EnableFastISel) - report_fatal_error("-fast-isel-abort > 0 requires -fast-isel"); - - // Decide what flavour of variable location debug-info will be used, before - // we change the optimisation level. - MF.setUseDebugInstrRef(MF.shouldUseDebugInstrRef()); - - // Reset the target options before resetting the optimization - // level below. - // FIXME: This is a horrible hack and should be processed via - // codegen looking at the optimization level explicitly when - // it wants to look at it. - Selector->TM.resetTargetOptions(MF.getFunction()); - // Reset OptLevel to None for optnone functions. - CodeGenOptLevel NewOptLevel = skipFunction(MF.getFunction()) - ? CodeGenOptLevel::None - : Selector->OptLevel; - - Selector->MF = &MF; - OptLevelChanger OLC(*Selector, NewOptLevel); - Selector->initializeAnalysisResults(*this); - return Selector->runOnMachineFunction(MF); -} - -SelectionDAGISel::SelectionDAGISel(TargetMachine &tm, CodeGenOptLevel OL) - : TM(tm), FuncInfo(new FunctionLoweringInfo()), +SelectionDAGISel::SelectionDAGISel(char &ID, TargetMachine &tm, + CodeGenOptLevel OL) + : MachineFunctionPass(ID), TM(tm), FuncInfo(new FunctionLoweringInfo()), SwiftError(new SwiftErrorValueTracking()), CurDAG(new SelectionDAG(tm, OL)), SDB(std::make_unique(*CurDAG, *FuncInfo, *SwiftError, @@ -401,17 +361,14 @@ SelectionDAGISel::~SelectionDAGISel() { delete SwiftError; } -void SelectionDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const { - CodeGenOptLevel OptLevel = Selector->OptLevel; +void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { if (OptLevel != CodeGenOptLevel::None) AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addPreserved(); AU.addRequired(); -#ifndef NDEBUG AU.addRequired(); -#endif AU.addRequired(); if (UseMBPI && OptLevel != CodeGenOptLevel::None) AU.addRequired(); @@ -449,129 +406,65 @@ static void computeUsesMSVCFloatingPoint(const Triple &TT, const Function &F, } } -PreservedAnalyses -SelectionDAGISelPass::run(MachineFunction &MF, - MachineFunctionAnalysisManager &MFAM) { +bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { // If we already selected that function, we do not need to run SDISel. - if (MF.getProperties().hasProperty( + if (mf.getProperties().hasProperty( MachineFunctionProperties::Property::Selected)) - return PreservedAnalyses::all(); - + return false; // Do some sanity-checking on the command-line options. - if (EnableFastISelAbort && !Selector->TM.Options.EnableFastISel) - report_fatal_error("-fast-isel-abort > 0 requires -fast-isel"); + assert((!EnableFastISelAbort || TM.Options.EnableFastISel) && + "-fast-isel-abort > 0 requires -fast-isel"); + + const Function &Fn = mf.getFunction(); + MF = &mf; + +#ifndef NDEBUG + StringRef FuncName = Fn.getName(); + MatchFilterFuncName = isFunctionInPrintList(FuncName); +#else + (void)MatchFilterFuncName; +#endif // Decide what flavour of variable location debug-info will be used, before // we change the optimisation level. - MF.setUseDebugInstrRef(MF.shouldUseDebugInstrRef()); + bool InstrRef = mf.shouldUseDebugInstrRef(); + mf.setUseDebugInstrRef(InstrRef); // Reset the target options before resetting the optimization // level below. // FIXME: This is a horrible hack and should be processed via // codegen looking at the optimization level explicitly when // it wants to look at it. - Selector->TM.resetTargetOptions(MF.getFunction()); - // Reset OptLevel to None for optnone functions. - // TODO: Add a function analysis to handle this. - Selector->MF = &MF; + TM.resetTargetOptions(Fn); // Reset OptLevel to None for optnone functions. - CodeGenOptLevel NewOptLevel = MF.getFunction().hasOptNone() - ? CodeGenOptLevel::None - : Selector->OptLevel; - - OptLevelChanger OLC(*Selector, NewOptLevel); - Selector->initializeAnalysisResults(MFAM); - Selector->runOnMachineFunction(MF); - - return getMachineFunctionPassPreservedAnalyses(); -} - -void SelectionDAGISel::initializeAnalysisResults( - MachineFunctionAnalysisManager &MFAM) { - auto &FAM = MFAM.getResult(*MF) - .getManager(); - auto &MAMP = MFAM.getResult(*MF); - Function &Fn = MF->getFunction(); -#ifndef NDEBUG - FuncName = Fn.getName(); - MatchFilterFuncName = isFunctionInPrintList(FuncName); -#else - (void)MatchFilterFuncName; -#endif + CodeGenOptLevel NewOptLevel = OptLevel; + if (OptLevel != CodeGenOptLevel::None && skipFunction(Fn)) + NewOptLevel = CodeGenOptLevel::None; + OptLevelChanger OLC(*this, NewOptLevel); TII = MF->getSubtarget().getInstrInfo(); TLI = MF->getSubtarget().getTargetLowering(); RegInfo = &MF->getRegInfo(); - LibInfo = &FAM.getResult(Fn); - GFI = Fn.hasGC() ? &FAM.getResult(Fn) : nullptr; + LibInfo = &getAnalysis().getTLI(Fn); + GFI = Fn.hasGC() ? &getAnalysis().getFunctionInfo(Fn) : nullptr; ORE = std::make_unique(&Fn); - AC = &FAM.getResult(Fn); - auto *PSI = MAMP.getCachedResult(*Fn.getParent()); + AC = &getAnalysis().getAssumptionCache(mf.getFunction()); + auto *PSI = &getAnalysis().getPSI(); BlockFrequencyInfo *BFI = nullptr; - FAM.getResult(Fn); if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOptLevel::None) - BFI = &FAM.getResult(Fn); + BFI = &getAnalysis().getBFI(); FunctionVarLocs const *FnVarLocs = nullptr; if (isAssignmentTrackingEnabled(*Fn.getParent())) - FnVarLocs = &FAM.getResult(Fn); + FnVarLocs = getAnalysis().getResults(); - auto *UA = FAM.getCachedResult(Fn); - CurDAG->init(*MF, *ORE, MFAM, LibInfo, UA, PSI, BFI, FnVarLocs); - SwiftError->setFunction(*MF); - - // Now get the optional analyzes if we want to. - // This is based on the possibly changed OptLevel (after optnone is taken - // into account). That's unfortunate but OK because it just means we won't - // ask for passes that have been required anyway. - - if (UseMBPI && OptLevel != CodeGenOptLevel::None) - FuncInfo->BPI = &FAM.getResult(Fn); - else - FuncInfo->BPI = nullptr; - - if (OptLevel != CodeGenOptLevel::None) - AA = &FAM.getResult(Fn); - else - AA = nullptr; - - SP = &FAM.getResult(Fn); - -#ifndef NDEBUG - TTI = &FAM.getResult(Fn); -#endif -} - -void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) { - Function &Fn = MF->getFunction(); -#ifndef NDEBUG - FuncName = Fn.getName(); - MatchFilterFuncName = isFunctionInPrintList(FuncName); -#else - (void)MatchFilterFuncName; -#endif - - TII = MF->getSubtarget().getInstrInfo(); - TLI = MF->getSubtarget().getTargetLowering(); - RegInfo = &MF->getRegInfo(); - LibInfo = &MFP.getAnalysis().getTLI(Fn); - GFI = Fn.hasGC() ? &MFP.getAnalysis().getFunctionInfo(Fn) - : nullptr; - ORE = std::make_unique(&Fn); - AC = &MFP.getAnalysis().getAssumptionCache(Fn); - auto *PSI = &MFP.getAnalysis().getPSI(); - BlockFrequencyInfo *BFI = nullptr; - if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOptLevel::None) - BFI = &MFP.getAnalysis().getBFI(); - - FunctionVarLocs const *FnVarLocs = nullptr; - if (isAssignmentTrackingEnabled(*Fn.getParent())) - FnVarLocs = MFP.getAnalysis().getResults(); + ISEL_DUMP(dbgs() << "\n\n\n=== " << FuncName << "\n"); UniformityInfo *UA = nullptr; - if (auto *UAPass = MFP.getAnalysisIfAvailable()) + if (auto *UAPass = getAnalysisIfAvailable()) UA = &UAPass->getUniformityInfo(); - CurDAG->init(*MF, *ORE, &MFP, LibInfo, UA, PSI, BFI, FnVarLocs); + CurDAG->init(*MF, *ORE, this, LibInfo, UA, PSI, BFI, FnVarLocs); + FuncInfo->set(Fn, *MF, CurDAG); SwiftError->setFunction(*MF); // Now get the optional analyzes if we want to. @@ -580,32 +473,15 @@ void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) { // ask for passes that have been required anyway. if (UseMBPI && OptLevel != CodeGenOptLevel::None) - FuncInfo->BPI = - &MFP.getAnalysis().getBPI(); + FuncInfo->BPI = &getAnalysis().getBPI(); else FuncInfo->BPI = nullptr; if (OptLevel != CodeGenOptLevel::None) - AA = &MFP.getAnalysis().getAAResults(); + AA = &getAnalysis().getAAResults(); else AA = nullptr; - SP = &MFP.getAnalysis().getLayoutInfo(); - -#ifndef NDEBUG - TTI = &MFP.getAnalysis().getTTI(Fn); -#endif -} - -bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { - const Function &Fn = mf.getFunction(); - - bool InstrRef = mf.shouldUseDebugInstrRef(); - - FuncInfo->set(MF->getFunction(), *MF, CurDAG); - - ISEL_DUMP(dbgs() << "\n\n\n=== " << FuncName << '\n'); - SDB->init(GFI, AA, AC, LibInfo); MF->setHasInlineAsm(false); @@ -900,8 +776,11 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { StringRef GroupName = "sdag"; StringRef GroupDescription = "Instruction Selection and Scheduling"; std::string BlockName; - bool MatchFilterBB = false; - (void)MatchFilterBB; + bool MatchFilterBB = false; (void)MatchFilterBB; +#ifndef NDEBUG + TargetTransformInfo &TTI = + getAnalysis().getTTI(*FuncInfo->Fn); +#endif // Pre-type legalization allow creation of any node types. CurDAG->NewNodesMustHaveLegalTypes = false; @@ -926,7 +805,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI->hasBranchDivergence()) + if (TTI.hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -946,7 +825,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI->hasBranchDivergence()) + if (TTI.hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -968,7 +847,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI->hasBranchDivergence()) + if (TTI.hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -992,7 +871,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI->hasBranchDivergence()) + if (TTI.hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif } @@ -1010,7 +889,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI->hasBranchDivergence()) + if (TTI.hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -1026,7 +905,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI->hasBranchDivergence()) + if (TTI.hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -1046,7 +925,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI->hasBranchDivergence()) + if (TTI.hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif } @@ -1066,7 +945,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI->hasBranchDivergence()) + if (TTI.hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -1086,7 +965,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { CurDAG->dump()); #ifndef NDEBUG - if (TTI->hasBranchDivergence()) + if (TTI.hasBranchDivergence()) CurDAG->VerifyDAGDivergence(); #endif @@ -1674,6 +1553,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { } // Iterate over all basic blocks in the function. + StackProtector &SP = getAnalysis(); for (const BasicBlock *LLVMBB : RPOT) { if (OptLevel != CodeGenOptLevel::None) { bool AllPredsVisited = true; @@ -1849,7 +1729,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { FastIS->recomputeInsertPt(); } - if (SP->shouldEmitSDCheck(*LLVMBB)) { + if (SP.shouldEmitSDCheck(*LLVMBB)) { bool FunctionBasedInstrumentation = TLI->getSSPStackGuardCheck(*Fn.getParent()); SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->MBBMap[LLVMBB], @@ -1886,7 +1766,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { if (Fn.getParent()->getModuleFlag("eh-asynch")) reportIPToStateForBlocks(MF); - SP->copyToMachineFrameInfo(MF->getFrameInfo()); + SP.copyToMachineFrameInfo(MF->getFrameInfo()); SwiftError->propagateVRegs(); diff --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h index 0f0a22ec8293..b70fbe42fe5f 100644 --- a/llvm/lib/Target/AArch64/AArch64.h +++ b/llvm/lib/Target/AArch64/AArch64.h @@ -85,7 +85,7 @@ void initializeAArch64CompressJumpTablesPass(PassRegistry&); void initializeAArch64CondBrTuningPass(PassRegistry &); void initializeAArch64ConditionOptimizerPass(PassRegistry&); void initializeAArch64ConditionalComparesPass(PassRegistry &); -void initializeAArch64DAGToDAGISelLegacyPass(PassRegistry &); +void initializeAArch64DAGToDAGISelPass(PassRegistry &); void initializeAArch64DeadRegisterDefinitionsPass(PassRegistry&); void initializeAArch64ExpandPseudoPass(PassRegistry &); void initializeAArch64GlobalsTaggingPass(PassRegistry &); diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 248778f98f4c..8fd58f4698d2 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -44,11 +44,13 @@ class AArch64DAGToDAGISel : public SelectionDAGISel { const AArch64Subtarget *Subtarget; public: + static char ID; + AArch64DAGToDAGISel() = delete; explicit AArch64DAGToDAGISel(AArch64TargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr) {} + : SelectionDAGISel(ID, tm, OptLevel), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override { Subtarget = &MF.getSubtarget(); @@ -505,20 +507,11 @@ private: bool SelectAllActivePredicate(SDValue N); bool SelectAnyPredicate(SDValue N); }; - -class AArch64DAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit AArch64DAGToDAGISelLegacy(AArch64TargetMachine &tm, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(tm, OptLevel)) {} -}; } // end anonymous namespace -char AArch64DAGToDAGISelLegacy::ID = 0; +char AArch64DAGToDAGISel::ID = 0; -INITIALIZE_PASS(AArch64DAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(AArch64DAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) /// isIntImmediate - This method tests to see if the node is a constant /// operand. If so Imm will receive the 32-bit value. @@ -6874,7 +6867,7 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) { /// AArch64-specific DAG, ready for instruction scheduling. FunctionPass *llvm::createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel) { - return new AArch64DAGToDAGISelLegacy(TM, OptLevel); + return new AArch64DAGToDAGISel(TM, OptLevel); } /// When \p PredVT is a scalable vector predicate in the form diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 30f0ceaf674c..945ab5cf1f30 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -258,7 +258,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target() { initializeAArch64StackTaggingPass(*PR); initializeAArch64StackTaggingPreRAPass(*PR); initializeAArch64LowerHomogeneousPrologEpilogPass(*PR); - initializeAArch64DAGToDAGISelLegacyPass(*PR); + initializeAArch64DAGToDAGISelPass(*PR); initializeAArch64GlobalsTaggingPass(*PR); } diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.h b/llvm/lib/Target/AMDGPU/AMDGPU.h index 46cc5f349555..6016bd5187d8 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPU.h +++ b/llvm/lib/Target/AMDGPU/AMDGPU.h @@ -81,7 +81,7 @@ struct AMDGPUUseNativeCallsPass : PassInfoMixin { PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -void initializeAMDGPUDAGToDAGISelLegacyPass(PassRegistry &); +void initializeAMDGPUDAGToDAGISelPass(PassRegistry&); void initializeAMDGPUMachineCFGStructurizerPass(PassRegistry&); extern char &AMDGPUMachineCFGStructurizerID; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp index 7c353fd10284..01ab61a0e407 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp @@ -7,9 +7,7 @@ //===----------------------------------------------------------------------===// #include "AMDGPUCodeGenPassBuilder.h" -#include "AMDGPUISelDAGToDAG.h" #include "AMDGPUTargetMachine.h" -#include "llvm/Analysis/UniformityAnalysis.h" using namespace llvm; @@ -27,8 +25,6 @@ AMDGPUCodeGenPassBuilder::AMDGPUCodeGenPassBuilder( void AMDGPUCodeGenPassBuilder::addPreISel(AddIRPass &addPass) const { // TODO: Add passes pre instruction selection. - // Test only, convert to real IR passes in future. - addPass(RequireAnalysisPass()); } void AMDGPUCodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass, @@ -36,7 +32,7 @@ void AMDGPUCodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass, // TODO: Add AsmPrinter. } -Error AMDGPUCodeGenPassBuilder::addInstSelector(AddMachinePass &addPass) const { - addPass(AMDGPUISelDAGToDAGPass(TM)); +Error AMDGPUCodeGenPassBuilder::addInstSelector(AddMachinePass &) const { + // TODO: Add instruction selector. return Error::success(); } diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp index 3e2581dc904a..e35957338da7 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -98,9 +98,8 @@ static SDValue stripExtractLoElt(SDValue In) { } // end anonymous namespace -INITIALIZE_PASS_BEGIN(AMDGPUDAGToDAGISelLegacy, "amdgpu-isel", - "AMDGPU DAG->DAG Pattern Instruction Selection", false, - false) +INITIALIZE_PASS_BEGIN(AMDGPUDAGToDAGISel, "amdgpu-isel", + "AMDGPU DAG->DAG Pattern Instruction Selection", false, false) INITIALIZE_PASS_DEPENDENCY(AMDGPUArgumentUsageInfo) INITIALIZE_PASS_DEPENDENCY(AMDGPUPerfHintAnalysis) INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass) @@ -108,20 +107,19 @@ INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) #endif -INITIALIZE_PASS_END(AMDGPUDAGToDAGISelLegacy, "amdgpu-isel", - "AMDGPU DAG->DAG Pattern Instruction Selection", false, - false) +INITIALIZE_PASS_END(AMDGPUDAGToDAGISel, "amdgpu-isel", + "AMDGPU DAG->DAG Pattern Instruction Selection", false, false) /// This pass converts a legalized DAG into a AMDGPU-specific // DAG, ready for instruction scheduling. FunctionPass *llvm::createAMDGPUISelDag(TargetMachine &TM, CodeGenOptLevel OptLevel) { - return new AMDGPUDAGToDAGISelLegacy(TM, OptLevel); + return new AMDGPUDAGToDAGISel(TM, OptLevel); } AMDGPUDAGToDAGISel::AMDGPUDAGToDAGISel(TargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(TM, OptLevel) { + : SelectionDAGISel(ID, TM, OptLevel) { EnableLateStructurizeCFG = AMDGPUTargetMachine::EnableLateStructurizeCFG; } @@ -202,14 +200,14 @@ bool AMDGPUDAGToDAGISel::fp16SrcZerosHighBits(unsigned Opc) const { } } -void AMDGPUDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const { +void AMDGPUDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequired(); #ifdef EXPENSIVE_CHECKS AU.addRequired(); AU.addRequired(); #endif - SelectionDAGISelLegacy::getAnalysisUsage(AU); + SelectionDAGISel::getAnalysisUsage(AU); } bool AMDGPUDAGToDAGISel::matchLoadD16FromBuildVector(SDNode *N) const { @@ -773,14 +771,10 @@ bool AMDGPUDAGToDAGISel::isBaseWithConstantOffset64(SDValue Addr, SDValue &LHS, return false; } -StringRef AMDGPUDAGToDAGISelLegacy::getPassName() const { +StringRef AMDGPUDAGToDAGISel::getPassName() const { return "AMDGPU DAG->DAG Pattern Instruction Selection"; } -AMDGPUISelDAGToDAGPass::AMDGPUISelDAGToDAGPass(TargetMachine &TM) - : SelectionDAGISelPass( - std::make_unique(TM, TM.getOptLevel())) {} - //===----------------------------------------------------------------------===// // Complex Patterns //===----------------------------------------------------------------------===// @@ -3613,9 +3607,4 @@ void AMDGPUDAGToDAGISel::PostprocessISelDAG() { } while (IsModified); } -AMDGPUDAGToDAGISelLegacy::AMDGPUDAGToDAGISelLegacy(TargetMachine &TM, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} - -char AMDGPUDAGToDAGISelLegacy::ID = 0; +char AMDGPUDAGToDAGISel::ID = 0; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h index b5b374b6c047..53d25b4cf4ca 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h @@ -83,14 +83,21 @@ class AMDGPUDAGToDAGISel : public SelectionDAGISel { bool fp16SrcZerosHighBits(unsigned Opc) const; public: + static char ID; + AMDGPUDAGToDAGISel() = delete; explicit AMDGPUDAGToDAGISel(TargetMachine &TM, CodeGenOptLevel OptLevel); + ~AMDGPUDAGToDAGISel() override = default; + + void getAnalysisUsage(AnalysisUsage &AU) const override; - bool runOnMachineFunction(MachineFunction &MF) override; bool matchLoadD16FromBuildVector(SDNode *N) const; + + bool runOnMachineFunction(MachineFunction &MF) override; void PreprocessISelDAG() override; void Select(SDNode *N) override; + StringRef getPassName() const override; void PostprocessISelDAG() override; protected: @@ -281,19 +288,4 @@ protected: #include "AMDGPUGenDAGISel.inc" }; -class AMDGPUISelDAGToDAGPass : public SelectionDAGISelPass { -public: - AMDGPUISelDAGToDAGPass(TargetMachine &TM); -}; - -class AMDGPUDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - - AMDGPUDAGToDAGISelLegacy(TargetMachine &TM, CodeGenOptLevel OptLevel); - - void getAnalysisUsage(AnalysisUsage &AU) const override; - StringRef getPassName() const override; -}; - #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUISELDAGTODAG_H diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def b/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def index 57fc3314dd97..90f36fadf359 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def +++ b/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def @@ -71,9 +71,3 @@ FUNCTION_PASS_WITH_PARAMS( }, parseAMDGPUAtomicOptimizerStrategy, "strategy=dpp|iterative|none") #undef FUNCTION_PASS_WITH_PARAMS - -#ifndef MACHINE_FUNCTION_PASS -#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) -#endif -MACHINE_FUNCTION_PASS("amdgpu-isel", AMDGPUISelDAGToDAGPass(*this)) -#undef MACHINE_FUNCTION_PASS diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index 9c94ca1e4708..dbbfe34a6386 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -19,7 +19,6 @@ #include "AMDGPUCtorDtorLowering.h" #include "AMDGPUExportClustering.h" #include "AMDGPUIGroupLP.h" -#include "AMDGPUISelDAGToDAG.h" #include "AMDGPUMacroFusion.h" #include "AMDGPURegBankSelect.h" #include "AMDGPUSplitModule.h" @@ -388,7 +387,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUTarget() { initializeR600ExpandSpecialInstrsPassPass(*PR); initializeR600VectorRegMergerPass(*PR); initializeGlobalISel(*PR); - initializeAMDGPUDAGToDAGISelLegacyPass(*PR); + initializeAMDGPUDAGToDAGISelPass(*PR); initializeGCNDPPCombinePass(*PR); initializeSILowerI1CopiesPass(*PR); initializeAMDGPUGlobalISelDivergenceLoweringPass(*PR); diff --git a/llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp index 28bcf72b3b09..293db13f34f6 100644 --- a/llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp @@ -48,17 +48,6 @@ protected: // Include the pieces autogenerated from the target description. #include "R600GenDAGISel.inc" }; - -class R600DAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit R600DAGToDAGISelLegacy(TargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} -}; - -char R600DAGToDAGISelLegacy::ID = 0; - } // namespace bool R600DAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { @@ -195,5 +184,5 @@ bool R600DAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, // DAG, ready for instruction scheduling. FunctionPass *llvm::createR600ISelDag(TargetMachine &TM, CodeGenOptLevel OptLevel) { - return new R600DAGToDAGISelLegacy(TM, OptLevel); + return new R600DAGToDAGISel(TM, OptLevel); } diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 4d8667affdb4..7cde09cc0b1c 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -3087,12 +3087,9 @@ SDValue SITargetLowering::LowerFormalArguments( if (IsEntryFunc) allocateSystemSGPRs(CCInfo, MF, *Info, CallConv, IsGraphics); - // DAG.getPass() returns nullptr when using new pass manager. - // TODO: Use DAG.getMFAM() to access analysis result. - if (DAG.getPass()) { - auto &ArgUsageInfo = DAG.getPass()->getAnalysis(); - ArgUsageInfo.setFuncArgInfo(Fn, Info->getArgInfo()); - } + auto &ArgUsageInfo = + DAG.getPass()->getAnalysis(); + ArgUsageInfo.setFuncArgInfo(Fn, Info->getArgInfo()); unsigned StackArgSize = CCInfo.getStackSize(); Info->setBytesInStackArgArea(StackArgSize); @@ -3304,13 +3301,9 @@ void SITargetLowering::passSpecialInputs( const AMDGPUFunctionArgInfo *CalleeArgInfo = &AMDGPUArgumentUsageInfo::FixedABIFunctionInfo; if (const Function *CalleeFunc = CLI.CB->getCalledFunction()) { - // DAG.getPass() returns nullptr when using new pass manager. - // TODO: Use DAG.getMFAM() to access analysis result. - if (DAG.getPass()) { - auto &ArgUsageInfo = - DAG.getPass()->getAnalysis(); - CalleeArgInfo = &ArgUsageInfo.lookupFuncArgInfo(*CalleeFunc); - } + auto &ArgUsageInfo = + DAG.getPass()->getAnalysis(); + CalleeArgInfo = &ArgUsageInfo.lookupFuncArgInfo(*CalleeFunc); } // TODO: Unify with private memory register handling. This is complicated by diff --git a/llvm/lib/Target/ARC/ARC.h b/llvm/lib/Target/ARC/ARC.h index 459f79c6eacc..b81016d0cee4 100644 --- a/llvm/lib/Target/ARC/ARC.h +++ b/llvm/lib/Target/ARC/ARC.h @@ -27,7 +27,7 @@ FunctionPass *createARCISelDag(ARCTargetMachine &TM, CodeGenOptLevel OptLevel); FunctionPass *createARCExpandPseudosPass(); FunctionPass *createARCOptAddrMode(); FunctionPass *createARCBranchFinalizePass(); -void initializeARCDAGToDAGISelLegacyPass(PassRegistry &); +void initializeARCDAGToDAGISelPass(PassRegistry &); } // end namespace llvm diff --git a/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp b/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp index 5e6cfa539b6d..17c2d7bb13b4 100644 --- a/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp @@ -41,10 +41,12 @@ namespace { class ARCDAGToDAGISel : public SelectionDAGISel { public: + static char ID; + ARCDAGToDAGISel() = delete; ARCDAGToDAGISel(ARCTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(TM, OptLevel) {} + : SelectionDAGISel(ID, TM, OptLevel) {} void Select(SDNode *N) override; @@ -58,25 +60,17 @@ public: #include "ARCGenDAGISel.inc" }; -class ARCDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit ARCDAGToDAGISelLegacy(ARCTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} -}; - -char ARCDAGToDAGISelLegacy::ID; +char ARCDAGToDAGISel::ID; } // end anonymous namespace -INITIALIZE_PASS(ARCDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(ARCDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) /// This pass converts a legalized DAG into a ARC-specific DAG, ready for /// instruction scheduling. FunctionPass *llvm::createARCISelDag(ARCTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new ARCDAGToDAGISelLegacy(TM, OptLevel); + return new ARCDAGToDAGISel(TM, OptLevel); } bool ARCDAGToDAGISel::SelectAddrModeImm(SDValue Addr, SDValue &Base, diff --git a/llvm/lib/Target/ARC/ARCTargetMachine.cpp b/llvm/lib/Target/ARC/ARCTargetMachine.cpp index 5f021cf1f442..f50c3c0265e3 100644 --- a/llvm/lib/Target/ARC/ARCTargetMachine.cpp +++ b/llvm/lib/Target/ARC/ARCTargetMachine.cpp @@ -97,7 +97,7 @@ MachineFunctionInfo *ARCTargetMachine::createMachineFunctionInfo( extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARCTarget() { RegisterTargetMachine X(getTheARCTarget()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeARCDAGToDAGISelLegacyPass(PR); + initializeARCDAGToDAGISelPass(PR); } TargetTransformInfo diff --git a/llvm/lib/Target/ARM/ARM.h b/llvm/lib/Target/ARM/ARM.h index 0b7045eadde7..b96e01822985 100644 --- a/llvm/lib/Target/ARM/ARM.h +++ b/llvm/lib/Target/ARM/ARM.h @@ -64,7 +64,7 @@ void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, void initializeARMBlockPlacementPass(PassRegistry &); void initializeARMBranchTargetsPass(PassRegistry &); void initializeARMConstantIslandsPass(PassRegistry &); -void initializeARMDAGToDAGISelLegacyPass(PassRegistry &); +void initializeARMDAGToDAGISelPass(PassRegistry &); void initializeARMExpandPseudoPass(PassRegistry &); void initializeARMFixCortexA57AES1742098Pass(PassRegistry &); void initializeARMLoadStoreOptPass(PassRegistry &); diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp index 7ffc64378ef4..20dd3e7baf84 100644 --- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -59,10 +59,12 @@ class ARMDAGToDAGISel : public SelectionDAGISel { const ARMSubtarget *Subtarget; public: + static char ID; + ARMDAGToDAGISel() = delete; explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(tm, OptLevel) {} + : SelectionDAGISel(ID, tm, OptLevel) {} bool runOnMachineFunction(MachineFunction &MF) override { // Reset the subtarget each time through. @@ -360,19 +362,11 @@ private: /// selected when N would have been selected. void replaceDAGValue(const SDValue &N, SDValue M); }; - -class ARMDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - ARMDAGToDAGISelLegacy(ARMBaseTargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(tm, OptLevel)) {} -}; } -char ARMDAGToDAGISelLegacy::ID = 0; +char ARMDAGToDAGISel::ID = 0; -INITIALIZE_PASS(ARMDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(ARMDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) /// isInt32Immediate - This method tests to see if the node is a 32-bit constant /// operand. If so Imm will receive the 32-bit value. @@ -5892,5 +5886,5 @@ bool ARMDAGToDAGISel::SelectInlineAsmMemoryOperand( /// FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new ARMDAGToDAGISelLegacy(TM, OptLevel); + return new ARMDAGToDAGISel(TM, OptLevel); } diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp index 7553778c5740..4ef00df57ef9 100644 --- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -110,7 +110,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTarget() { initializeARMSLSHardeningPass(Registry); initializeMVELaneInterleavingPass(Registry); initializeARMFixCortexA57AES1742098Pass(Registry); - initializeARMDAGToDAGISelLegacyPass(Registry); + initializeARMDAGToDAGISelPass(Registry); } static std::unique_ptr createTLOF(const Triple &TT) { diff --git a/llvm/lib/Target/AVR/AVR.h b/llvm/lib/Target/AVR/AVR.h index 0e67bb4eb50c..4b1336ecd661 100644 --- a/llvm/lib/Target/AVR/AVR.h +++ b/llvm/lib/Target/AVR/AVR.h @@ -31,7 +31,7 @@ FunctionPass *createAVRExpandPseudoPass(); FunctionPass *createAVRFrameAnalyzerPass(); FunctionPass *createAVRBranchSelectionPass(); -void initializeAVRDAGToDAGISelLegacyPass(PassRegistry &); +void initializeAVRDAGToDAGISelPass(PassRegistry &); void initializeAVRExpandPseudoPass(PassRegistry &); void initializeAVRShiftExpandPass(PassRegistry &); diff --git a/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp b/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp index 77db876d47e4..e67a1e2ed509 100644 --- a/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp +++ b/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp @@ -29,10 +29,12 @@ namespace { /// Lowers LLVM IR (in DAG form) to AVR MC instructions (in DAG form). class AVRDAGToDAGISel : public SelectionDAGISel { public: + static char ID; + AVRDAGToDAGISel() = delete; AVRDAGToDAGISel(AVRTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(TM, OptLevel), Subtarget(nullptr) {} + : SelectionDAGISel(ID, TM, OptLevel), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override; @@ -58,19 +60,11 @@ private: const AVRSubtarget *Subtarget; }; -class AVRDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - AVRDAGToDAGISelLegacy(AVRTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} -}; - } // namespace -char AVRDAGToDAGISelLegacy::ID = 0; +char AVRDAGToDAGISel::ID = 0; -INITIALIZE_PASS(AVRDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(AVRDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) bool AVRDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { Subtarget = &MF.getSubtarget(); @@ -592,5 +586,5 @@ bool AVRDAGToDAGISel::trySelect(SDNode *N) { FunctionPass *llvm::createAVRISelDag(AVRTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new AVRDAGToDAGISelLegacy(TM, OptLevel); + return new AVRDAGToDAGISel(TM, OptLevel); } diff --git a/llvm/lib/Target/AVR/AVRTargetMachine.cpp b/llvm/lib/Target/AVR/AVRTargetMachine.cpp index a8c967f865c0..e0776a6cab43 100644 --- a/llvm/lib/Target/AVR/AVRTargetMachine.cpp +++ b/llvm/lib/Target/AVR/AVRTargetMachine.cpp @@ -95,7 +95,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRTarget() { auto &PR = *PassRegistry::getPassRegistry(); initializeAVRExpandPseudoPass(PR); initializeAVRShiftExpandPass(PR); - initializeAVRDAGToDAGISelLegacyPass(PR); + initializeAVRDAGToDAGISelPass(PR); } const AVRSubtarget *AVRTargetMachine::getSubtargetImpl() const { diff --git a/llvm/lib/Target/BPF/BPF.h b/llvm/lib/Target/BPF/BPF.h index 694d7bacf642..bbdbdbbde532 100644 --- a/llvm/lib/Target/BPF/BPF.h +++ b/llvm/lib/Target/BPF/BPF.h @@ -35,7 +35,7 @@ InstructionSelector *createBPFInstructionSelector(const BPFTargetMachine &, const BPFRegisterBankInfo &); void initializeBPFCheckAndAdjustIRPass(PassRegistry&); -void initializeBPFDAGToDAGISelLegacyPass(PassRegistry &); +void initializeBPFDAGToDAGISelPass(PassRegistry &); void initializeBPFMIPeepholePass(PassRegistry &); void initializeBPFMIPreEmitCheckingPass(PassRegistry&); void initializeBPFMIPreEmitPeepholePass(PassRegistry &); diff --git a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp index 67f98bd7c05b..7b8bcb2c5866 100644 --- a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp +++ b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp @@ -46,10 +46,12 @@ class BPFDAGToDAGISel : public SelectionDAGISel { const BPFSubtarget *Subtarget; public: + static char ID; + BPFDAGToDAGISel() = delete; explicit BPFDAGToDAGISel(BPFTargetMachine &TM) - : SelectionDAGISel(TM), Subtarget(nullptr) {} + : SelectionDAGISel(ID, TM), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override { // Reset the subtarget each time through. @@ -92,18 +94,11 @@ private: // Mapping from ConstantStruct global value to corresponding byte-list values std::map cs_vals_; }; - -class BPFDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - BPFDAGToDAGISelLegacy(BPFTargetMachine &TM) - : SelectionDAGISelLegacy(ID, std::make_unique(TM)) {} -}; } // namespace -char BPFDAGToDAGISelLegacy::ID = 0; +char BPFDAGToDAGISel::ID = 0; -INITIALIZE_PASS(BPFDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(BPFDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) // ComplexPattern used on BPF Load/Store instructions bool BPFDAGToDAGISel::SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) { @@ -494,5 +489,5 @@ void BPFDAGToDAGISel::PreprocessTrunc(SDNode *Node, } FunctionPass *llvm::createBPFISelDag(BPFTargetMachine &TM) { - return new BPFDAGToDAGISelLegacy(TM); + return new BPFDAGToDAGISel(TM); } diff --git a/llvm/lib/Target/BPF/BPFTargetMachine.cpp b/llvm/lib/Target/BPF/BPFTargetMachine.cpp index 7b73c9f4a1e4..a7bed69b0f2a 100644 --- a/llvm/lib/Target/BPF/BPFTargetMachine.cpp +++ b/llvm/lib/Target/BPF/BPFTargetMachine.cpp @@ -48,7 +48,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTarget() { initializeGlobalISel(PR); initializeBPFCheckAndAdjustIRPass(PR); initializeBPFMIPeepholePass(PR); - initializeBPFDAGToDAGISelLegacyPass(PR); + initializeBPFDAGToDAGISelPass(PR); } // DataLayout: little or big endian diff --git a/llvm/lib/Target/CSKY/CSKY.h b/llvm/lib/Target/CSKY/CSKY.h index 21ebf13f2064..7ca630c9abaa 100644 --- a/llvm/lib/Target/CSKY/CSKY.h +++ b/llvm/lib/Target/CSKY/CSKY.h @@ -27,7 +27,7 @@ FunctionPass *createCSKYISelDag(CSKYTargetMachine &TM, FunctionPass *createCSKYConstantIslandPass(); void initializeCSKYConstantIslandsPass(PassRegistry &); -void initializeCSKYDAGToDAGISelLegacyPass(PassRegistry &); +void initializeCSKYDAGToDAGISelPass(PassRegistry &); } // namespace llvm diff --git a/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp b/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp index 22da80b3eddc..c0c23a45d155 100644 --- a/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp +++ b/llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp @@ -28,8 +28,10 @@ class CSKYDAGToDAGISel : public SelectionDAGISel { const CSKYSubtarget *Subtarget; public: + static char ID; + explicit CSKYDAGToDAGISel(CSKYTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(TM, OptLevel) {} + : SelectionDAGISel(ID, TM, OptLevel) {} bool runOnMachineFunction(MachineFunction &MF) override { // Reset the subtarget each time through. @@ -52,20 +54,11 @@ public: #include "CSKYGenDAGISel.inc" }; - -class CSKYDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit CSKYDAGToDAGISelLegacy(CSKYTargetMachine &TM, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} -}; } // namespace -char CSKYDAGToDAGISelLegacy::ID = 0; +char CSKYDAGToDAGISel::ID = 0; -INITIALIZE_PASS(CSKYDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(CSKYDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) void CSKYDAGToDAGISel::Select(SDNode *N) { // If we have a custom node, we have already selected @@ -408,5 +401,5 @@ bool CSKYDAGToDAGISel::SelectInlineAsmMemoryOperand( FunctionPass *llvm::createCSKYISelDag(CSKYTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new CSKYDAGToDAGISelLegacy(TM, OptLevel); + return new CSKYDAGToDAGISel(TM, OptLevel); } diff --git a/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp b/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp index a756061e307a..0bbfabe93147 100644 --- a/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp +++ b/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp @@ -30,7 +30,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTarget() { PassRegistry *Registry = PassRegistry::getPassRegistry(); initializeCSKYConstantIslandsPass(*Registry); - initializeCSKYDAGToDAGISelLegacyPass(*Registry); + initializeCSKYDAGToDAGISelPass(*Registry); } static std::string computeDataLayout(const Triple &TT) { diff --git a/llvm/lib/Target/Hexagon/Hexagon.h b/llvm/lib/Target/Hexagon/Hexagon.h index 4a290c798c27..861f61a0bfd2 100644 --- a/llvm/lib/Target/Hexagon/Hexagon.h +++ b/llvm/lib/Target/Hexagon/Hexagon.h @@ -22,7 +22,7 @@ namespace llvm { /// Creates a Hexagon-specific Target Transformation Info pass. ImmutablePass *createHexagonTargetTransformInfoPass(const HexagonTargetMachine *TM); - void initializeHexagonDAGToDAGISelLegacyPass(PassRegistry &); + void initializeHexagonDAGToDAGISelPass(PassRegistry &); } // end namespace llvm; #endif diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index febbc95ec0db..6fe3fe0d36b9 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -60,18 +60,13 @@ namespace llvm { /// Hexagon-specific DAG, ready for instruction scheduling. FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new HexagonDAGToDAGISelLegacy(TM, OptLevel); + return new HexagonDAGToDAGISel(TM, OptLevel); } } -HexagonDAGToDAGISelLegacy::HexagonDAGToDAGISelLegacy(HexagonTargetMachine &tm, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(tm, OptLevel)) {} +char HexagonDAGToDAGISel::ID = 0; -char HexagonDAGToDAGISelLegacy::ID = 0; - -INITIALIZE_PASS(HexagonDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(HexagonDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) void HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl) { SDValue Chain = LD->getChain(); diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h index 2d23aeecda6d..50162b107996 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h @@ -29,13 +29,14 @@ class HexagonDAGToDAGISel : public SelectionDAGISel { const HexagonSubtarget *HST; const HexagonInstrInfo *HII; const HexagonRegisterInfo *HRI; - public: + static char ID; + HexagonDAGToDAGISel() = delete; explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(tm, OptLevel), HST(nullptr), HII(nullptr), + : SelectionDAGISel(ID, tm, OptLevel), HST(nullptr), HII(nullptr), HRI(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override { @@ -161,13 +162,6 @@ private: SDValue balanceSubTree(SDNode *N, bool Factorize = false); void rebalanceAddressTrees(); }; // end HexagonDAGToDAGISel - -class HexagonDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit HexagonDAGToDAGISelLegacy(HexagonTargetMachine &tm, - CodeGenOptLevel OptLevel); -}; } #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H diff --git a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp index e4886506de19..3a792ecfd03d 100644 --- a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -254,7 +254,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonTarget() { initializeHexagonVectorCombineLegacyPass(PR); initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PR); initializeHexagonVExtractPass(PR); - initializeHexagonDAGToDAGISelLegacyPass(PR); + initializeHexagonDAGToDAGISelPass(PR); } HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, diff --git a/llvm/lib/Target/Lanai/Lanai.h b/llvm/lib/Target/Lanai/Lanai.h index 72a7efc58062..0f87b17b773e 100644 --- a/llvm/lib/Target/Lanai/Lanai.h +++ b/llvm/lib/Target/Lanai/Lanai.h @@ -37,7 +37,7 @@ FunctionPass *createLanaiMemAluCombinerPass(); // operations. FunctionPass *createLanaiSetflagAluCombinerPass(); -void initializeLanaiDAGToDAGISelLegacyPass(PassRegistry &); +void initializeLanaiDAGToDAGISelPass(PassRegistry &); } // namespace llvm diff --git a/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp b/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp index af64e2bf831b..6f5495ac00e1 100644 --- a/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp +++ b/llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp @@ -48,10 +48,16 @@ namespace { class LanaiDAGToDAGISel : public SelectionDAGISel { public: + static char ID; + LanaiDAGToDAGISel() = delete; explicit LanaiDAGToDAGISel(LanaiTargetMachine &TargetMachine) - : SelectionDAGISel(TargetMachine) {} + : SelectionDAGISel(ID, TargetMachine) {} + + bool runOnMachineFunction(MachineFunction &MF) override { + return SelectionDAGISel::runOnMachineFunction(MF); + } bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintCode, @@ -91,18 +97,11 @@ bool canBeRepresentedAsSls(const ConstantSDNode &CN) { return isInt<21>(CN.getSExtValue()) && ((CN.getSExtValue() & 0x3) == 0); } -class LanaiDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit LanaiDAGToDAGISelLegacy(LanaiTargetMachine &TM) - : SelectionDAGISelLegacy(ID, std::make_unique(TM)) {} -}; - } // namespace -char LanaiDAGToDAGISelLegacy::ID = 0; +char LanaiDAGToDAGISel::ID = 0; -INITIALIZE_PASS(LanaiDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(LanaiDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) // Helper functions for ComplexPattern used on LanaiInstrInfo // Used on Lanai Load/Store instructions. @@ -367,5 +366,5 @@ void LanaiDAGToDAGISel::selectFrameIndex(SDNode *Node) { // createLanaiISelDag - This pass converts a legalized DAG into a // Lanai-specific DAG, ready for instruction scheduling. FunctionPass *llvm::createLanaiISelDag(LanaiTargetMachine &TM) { - return new LanaiDAGToDAGISelLegacy(TM); + return new LanaiDAGToDAGISel(TM); } diff --git a/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp b/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp index 68eb12f87d89..2357221b0120 100644 --- a/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp +++ b/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp @@ -37,7 +37,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiTarget() { RegisterTargetMachine registered_target( getTheLanaiTarget()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeLanaiDAGToDAGISelLegacyPass(PR); + initializeLanaiDAGToDAGISelPass(PR); } static std::string computeDataLayout() { diff --git a/llvm/lib/Target/LoongArch/LoongArch.h b/llvm/lib/Target/LoongArch/LoongArch.h index 0928ea31054a..2109176d4998 100644 --- a/llvm/lib/Target/LoongArch/LoongArch.h +++ b/llvm/lib/Target/LoongArch/LoongArch.h @@ -38,7 +38,7 @@ FunctionPass *createLoongArchISelDag(LoongArchTargetMachine &TM); FunctionPass *createLoongArchOptWInstrsPass(); FunctionPass *createLoongArchPreRAExpandPseudoPass(); FunctionPass *createLoongArchExpandPseudoPass(); -void initializeLoongArchDAGToDAGISelLegacyPass(PassRegistry &); +void initializeLoongArchDAGToDAGISelPass(PassRegistry &); void initializeLoongArchExpandAtomicPseudoPass(PassRegistry &); void initializeLoongArchOptWInstrsPass(PassRegistry &); void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &); diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp index b6ade6b978d2..726856bda5dc 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp @@ -22,14 +22,9 @@ using namespace llvm; #define DEBUG_TYPE "loongarch-isel" #define PASS_NAME "LoongArch DAG->DAG Pattern Instruction Selection" -char LoongArchDAGToDAGISelLegacy::ID; +char LoongArchDAGToDAGISel::ID; -LoongArchDAGToDAGISelLegacy::LoongArchDAGToDAGISelLegacy( - LoongArchTargetMachine &TM) - : SelectionDAGISelLegacy(ID, std::make_unique(TM)) {} - -INITIALIZE_PASS(LoongArchDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, - false) +INITIALIZE_PASS(LoongArchDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) void LoongArchDAGToDAGISel::Select(SDNode *Node) { // If we have a custom node, we have already selected. @@ -419,5 +414,5 @@ bool LoongArchDAGToDAGISel::selectVSplatUimmPow2(SDValue N, // This pass converts a legalized DAG into a LoongArch-specific DAG, ready // for instruction scheduling. FunctionPass *llvm::createLoongArchISelDag(LoongArchTargetMachine &TM) { - return new LoongArchDAGToDAGISelLegacy(TM); + return new LoongArchDAGToDAGISel(TM); } diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h index 363b4f0ca7cf..48a178bfeb95 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h @@ -24,10 +24,12 @@ class LoongArchDAGToDAGISel : public SelectionDAGISel { const LoongArchSubtarget *Subtarget = nullptr; public: + static char ID; + LoongArchDAGToDAGISel() = delete; explicit LoongArchDAGToDAGISel(LoongArchTargetMachine &TM) - : SelectionDAGISel(TM) {} + : SelectionDAGISel(ID, TM) {} bool runOnMachineFunction(MachineFunction &MF) override { Subtarget = &MF.getSubtarget(); @@ -67,12 +69,6 @@ public: #include "LoongArchGenDAGISel.inc" }; -class LoongArchDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit LoongArchDAGToDAGISelLegacy(LoongArchTargetMachine &TM); -}; - } // end namespace llvm #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp index 83466d53f84d..2b2d4e478cc8 100644 --- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp @@ -36,7 +36,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() { auto *PR = PassRegistry::getPassRegistry(); initializeLoongArchOptWInstrsPass(*PR); initializeLoongArchPreRAExpandPseudoPass(*PR); - initializeLoongArchDAGToDAGISelLegacyPass(*PR); + initializeLoongArchDAGToDAGISelPass(*PR); } static cl::opt diff --git a/llvm/lib/Target/M68k/M68k.h b/llvm/lib/Target/M68k/M68k.h index 5db9d796d1d3..1d0f383dc5c9 100644 --- a/llvm/lib/Target/M68k/M68k.h +++ b/llvm/lib/Target/M68k/M68k.h @@ -46,7 +46,7 @@ InstructionSelector * createM68kInstructionSelector(const M68kTargetMachine &, const M68kSubtarget &, const M68kRegisterBankInfo &); -void initializeM68kDAGToDAGISelLegacyPass(PassRegistry &); +void initializeM68kDAGToDAGISelPass(PassRegistry &); void initializeM68kExpandPseudoPass(PassRegistry &); void initializeM68kGlobalBaseRegPass(PassRegistry &); void initializeM68kCollapseMOVEMPass(PassRegistry &); diff --git a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp index dc89fec8108c..e3aa9cb50847 100644 --- a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp +++ b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp @@ -174,10 +174,12 @@ namespace { class M68kDAGToDAGISel : public SelectionDAGISel { public: + static char ID; + M68kDAGToDAGISel() = delete; explicit M68kDAGToDAGISel(M68kTargetMachine &TM) - : SelectionDAGISel(TM), Subtarget(nullptr) {} + : SelectionDAGISel(ID, TM), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override; bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const override; @@ -314,18 +316,11 @@ private: SDNode *getGlobalBaseReg(); }; -class M68kDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit M68kDAGToDAGISelLegacy(M68kTargetMachine &TM) - : SelectionDAGISelLegacy(ID, std::make_unique(TM)) {} -}; - -char M68kDAGToDAGISelLegacy::ID; +char M68kDAGToDAGISel::ID; } // namespace -INITIALIZE_PASS(M68kDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(M68kDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) bool M68kDAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const { @@ -362,7 +357,7 @@ bool M68kDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { /// This pass converts a legalized DAG into a M68k-specific DAG, /// ready for instruction scheduling. FunctionPass *llvm::createM68kISelDag(M68kTargetMachine &TM) { - return new M68kDAGToDAGISelLegacy(TM); + return new M68kDAGToDAGISel(TM); } static bool doesDispFitFI(M68kISelAddressMode &AM) { diff --git a/llvm/lib/Target/M68k/M68kTargetMachine.cpp b/llvm/lib/Target/M68k/M68kTargetMachine.cpp index b65de5e177b5..bbbcb1556ed5 100644 --- a/llvm/lib/Target/M68k/M68kTargetMachine.cpp +++ b/llvm/lib/Target/M68k/M68kTargetMachine.cpp @@ -37,7 +37,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kTarget() { RegisterTargetMachine X(getTheM68kTarget()); auto *PR = PassRegistry::getPassRegistry(); initializeGlobalISel(*PR); - initializeM68kDAGToDAGISelLegacyPass(*PR); + initializeM68kDAGToDAGISelPass(*PR); initializeM68kExpandPseudoPass(*PR); initializeM68kGlobalBaseRegPass(*PR); initializeM68kCollapseMOVEMPass(*PR); diff --git a/llvm/lib/Target/MSP430/MSP430.h b/llvm/lib/Target/MSP430/MSP430.h index 019835908db8..60685b6704ba 100644 --- a/llvm/lib/Target/MSP430/MSP430.h +++ b/llvm/lib/Target/MSP430/MSP430.h @@ -43,7 +43,7 @@ FunctionPass *createMSP430ISelDag(MSP430TargetMachine &TM, FunctionPass *createMSP430BranchSelectionPass(); -void initializeMSP430DAGToDAGISelLegacyPass(PassRegistry &); +void initializeMSP430DAGToDAGISelPass(PassRegistry &); } // namespace llvm diff --git a/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp index 7be51d98d97d..efb23b1a4e3f 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp @@ -91,10 +91,12 @@ namespace { namespace { class MSP430DAGToDAGISel : public SelectionDAGISel { public: + static char ID; + MSP430DAGToDAGISel() = delete; MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(TM, OptLevel) {} + : SelectionDAGISel(ID, TM, OptLevel) {} private: bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); @@ -117,26 +119,18 @@ namespace { bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp); }; - - class MSP430DAGToDAGISelLegacy : public SelectionDAGISelLegacy { - public: - static char ID; - MSP430DAGToDAGISelLegacy(MSP430TargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} - }; } // end anonymous namespace -char MSP430DAGToDAGISelLegacy::ID; +char MSP430DAGToDAGISel::ID; -INITIALIZE_PASS(MSP430DAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(MSP430DAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) /// createMSP430ISelDag - This pass converts a legalized DAG into a /// MSP430-specific DAG, ready for instruction scheduling. /// FunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM, CodeGenOptLevel OptLevel) { - return new MSP430DAGToDAGISelLegacy(TM, OptLevel); + return new MSP430DAGToDAGISel(TM, OptLevel); } /// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode. diff --git a/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp b/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp index f307c3765150..ed0fcf7110b7 100644 --- a/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp +++ b/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp @@ -26,7 +26,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430Target() { // Register the target. RegisterTargetMachine X(getTheMSP430Target()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeMSP430DAGToDAGISelLegacyPass(PR); + initializeMSP430DAGToDAGISelPass(PR); } static Reloc::Model getEffectiveRelocModel(std::optional RM) { diff --git a/llvm/lib/Target/Mips/Mips.h b/llvm/lib/Target/Mips/Mips.h index 36a17334ae3b..f0cf039928c1 100644 --- a/llvm/lib/Target/Mips/Mips.h +++ b/llvm/lib/Target/Mips/Mips.h @@ -47,7 +47,7 @@ InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &, void initializeMicroMipsSizeReducePass(PassRegistry &); void initializeMipsBranchExpansionPass(PassRegistry &); -void initializeMipsDAGToDAGISelLegacyPass(PassRegistry &); +void initializeMipsDAGToDAGISelPass(PassRegistry &); void initializeMipsDelaySlotFillerPass(PassRegistry &); void initializeMipsMulMulBugFixPass(PassRegistry &); void initializeMipsPostLegalizerCombinerPass(PassRegistry &); diff --git a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp index b8e6dcefe622..0be9b94187a2 100644 --- a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp @@ -219,11 +219,7 @@ bool Mips16DAGToDAGISel::trySelect(SDNode *Node) { return false; } -Mips16DAGToDAGISelLegacy::Mips16DAGToDAGISelLegacy(MipsTargetMachine &TM, - CodeGenOptLevel OL) - : MipsDAGToDAGISelLegacy(std::make_unique(TM, OL)) {} - FunctionPass *llvm::createMips16ISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new Mips16DAGToDAGISelLegacy(TM, OptLevel); + return new Mips16DAGToDAGISel(TM, OptLevel); } diff --git a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h index ec6e74568c56..c6d3bde68806 100644 --- a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h @@ -47,11 +47,6 @@ private: void initMips16SPAliasReg(MachineFunction &MF); }; -class Mips16DAGToDAGISelLegacy : public MipsDAGToDAGISelLegacy { -public: - explicit Mips16DAGToDAGISelLegacy(MipsTargetMachine &TM, CodeGenOptLevel OL); -}; - FunctionPass *createMips16ISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel); } diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index f6f32fde3b77..01b41f3b2159 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -49,11 +49,11 @@ using namespace llvm; // instructions for SelectionDAG operations. //===----------------------------------------------------------------------===// -void MipsDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const { +void MipsDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { // There are multiple MipsDAGToDAGISel instances added to the pass pipeline. // We need to preserve StackProtector for the next one. AU.addPreserved(); - SelectionDAGISelLegacy::getAnalysisUsage(AU); + SelectionDAGISel::getAnalysisUsage(AU); } bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { @@ -344,10 +344,6 @@ bool MipsDAGToDAGISel::isUnneededShiftMask(SDNode *N, return (Known.Zero | RHS).countr_one() >= ShAmtBits; } -char MipsDAGToDAGISelLegacy::ID = 0; +char MipsDAGToDAGISel::ID = 0; -MipsDAGToDAGISelLegacy::MipsDAGToDAGISelLegacy( - std::unique_ptr S) - : SelectionDAGISelLegacy(ID, std::move(S)) {} - -INITIALIZE_PASS(MipsDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(MipsDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h index 6135f9680785..52207d0f6284 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h @@ -30,13 +30,17 @@ namespace llvm { class MipsDAGToDAGISel : public SelectionDAGISel { public: + static char ID; + MipsDAGToDAGISel() = delete; explicit MipsDAGToDAGISel(MipsTargetMachine &TM, CodeGenOptLevel OL) - : SelectionDAGISel(TM, OL), Subtarget(nullptr) {} + : SelectionDAGISel(ID, TM, OL), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; + protected: SDNode *getGlobalBaseReg(); @@ -141,13 +145,6 @@ private: std::vector &OutOps) override; bool isUnneededShiftMask(SDNode *N, unsigned ShAmtBits) const; }; - -class MipsDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - MipsDAGToDAGISelLegacy(std::unique_ptr S); - void getAnalysisUsage(AnalysisUsage &AU) const override; -}; } #endif diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 7ad300c6cccd..ab39d1b661ef 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -44,9 +44,9 @@ bool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { return MipsDAGToDAGISel::runOnMachineFunction(MF); } -void MipsSEDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const { +void MipsSEDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); - SelectionDAGISelLegacy::getAnalysisUsage(AU); + SelectionDAGISel::getAnalysisUsage(AU); } void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, @@ -1439,11 +1439,7 @@ bool MipsSEDAGToDAGISel::SelectInlineAsmMemoryOperand( return true; } -MipsSEDAGToDAGISelLegacy::MipsSEDAGToDAGISelLegacy(MipsTargetMachine &TM, - CodeGenOptLevel OL) - : MipsDAGToDAGISelLegacy(std::make_unique(TM, OL)) {} - FunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new MipsSEDAGToDAGISelLegacy(TM, OptLevel); + return new MipsSEDAGToDAGISel(TM, OptLevel); } diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index 7b843b0e0b25..96dc876cb753 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -27,6 +27,8 @@ private: bool runOnMachineFunction(MachineFunction &MF) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; + void addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, MachineFunction &MF); @@ -137,12 +139,6 @@ private: std::vector &OutOps) override; }; -class MipsSEDAGToDAGISelLegacy : public MipsDAGToDAGISelLegacy { -public: - explicit MipsSEDAGToDAGISelLegacy(MipsTargetMachine &TM, CodeGenOptLevel OL); - void getAnalysisUsage(AnalysisUsage &AU) const override; -}; - FunctionPass *createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel); } diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp index 9515e506c73e..4c4bf70e22c6 100644 --- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp +++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp @@ -67,7 +67,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTarget() { initializeMipsPreLegalizerCombinerPass(*PR); initializeMipsPostLegalizerCombinerPass(*PR); initializeMipsMulMulBugFixPass(*PR); - initializeMipsDAGToDAGISelLegacyPass(*PR); + initializeMipsDAGToDAGISelPass(*PR); } static std::string computeDataLayout(const Triple &TT, StringRef CPU, diff --git a/llvm/lib/Target/NVPTX/NVPTX.h b/llvm/lib/Target/NVPTX/NVPTX.h index 5eefab59a6ab..07ee34968b02 100644 --- a/llvm/lib/Target/NVPTX/NVPTX.h +++ b/llvm/lib/Target/NVPTX/NVPTX.h @@ -194,7 +194,7 @@ enum PrmtMode { }; } } -void initializeNVPTXDAGToDAGISelLegacyPass(PassRegistry &); +void initializeNVPTXDAGToDAGISelPass(PassRegistry &); } // namespace llvm // Defines symbolic names for NVPTX registers. This defines a mapping from diff --git a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp index 1e1cbb15e33d..2713b6859ff3 100644 --- a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp @@ -38,21 +38,16 @@ static cl::opt /// NVPTX-specific DAG, ready for instruction scheduling. FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM, llvm::CodeGenOptLevel OptLevel) { - return new NVPTXDAGToDAGISelLegacy(TM, OptLevel); + return new NVPTXDAGToDAGISel(TM, OptLevel); } -NVPTXDAGToDAGISelLegacy::NVPTXDAGToDAGISelLegacy(NVPTXTargetMachine &tm, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(tm, OptLevel)) {} +char NVPTXDAGToDAGISel::ID = 0; -char NVPTXDAGToDAGISelLegacy::ID = 0; - -INITIALIZE_PASS(NVPTXDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(NVPTXDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(tm, OptLevel), TM(tm) { + : SelectionDAGISel(ID, tm, OptLevel), TM(tm) { doMulWide = (OptLevel > CodeGenOptLevel::None); } diff --git a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h index c5524351f2ff..7a7774744bc7 100644 --- a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h +++ b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h @@ -39,6 +39,8 @@ class LLVM_LIBRARY_VISIBILITY NVPTXDAGToDAGISel : public SelectionDAGISel { bool doRsqrtOpt() const; public: + static char ID; + NVPTXDAGToDAGISel() = delete; explicit NVPTXDAGToDAGISel(NVPTXTargetMachine &tm, CodeGenOptLevel OptLevel); @@ -99,13 +101,6 @@ private: static unsigned GetConvertOpcode(MVT DestTy, MVT SrcTy, LoadSDNode *N); }; - -class NVPTXDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit NVPTXDAGToDAGISelLegacy(NVPTXTargetMachine &tm, - CodeGenOptLevel OptLevel); -}; } // end namespace llvm #endif diff --git a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp index 4dc3cea4bd8e..2a47c16a6bce 100644 --- a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp @@ -103,7 +103,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeNVPTXTarget() { initializeNVPTXCtorDtorLoweringLegacyPass(PR); initializeNVPTXLowerAggrCopiesPass(PR); initializeNVPTXProxyRegErasurePass(PR); - initializeNVPTXDAGToDAGISelLegacyPass(PR); + initializeNVPTXDAGToDAGISelPass(PR); initializeNVPTXAAWrapperPassPass(PR); initializeNVPTXExternalAAWrapperPass(PR); } diff --git a/llvm/lib/Target/PowerPC/PPC.h b/llvm/lib/Target/PowerPC/PPC.h index 94a59d14601b..eb8886dcc907 100644 --- a/llvm/lib/Target/PowerPC/PPC.h +++ b/llvm/lib/Target/PowerPC/PPC.h @@ -78,7 +78,7 @@ class ModulePass; void initializePPCMIPeepholePass(PassRegistry&); void initializePPCExpandAtomicPseudoPass(PassRegistry &); void initializePPCCTRLoopsPass(PassRegistry &); - void initializePPCDAGToDAGISelLegacyPass(PassRegistry &); + void initializePPCDAGToDAGISelPass(PassRegistry &); void initializePPCMergeStringPoolPass(PassRegistry &); extern char &PPCVSXFMAMutateID; diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 275b3337a276..26560dc5cdeb 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -147,10 +147,12 @@ namespace { unsigned GlobalBaseReg = 0; public: + static char ID; + PPCDAGToDAGISel() = delete; explicit PPCDAGToDAGISel(PPCTargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(tm, OptLevel), TM(tm) {} + : SelectionDAGISel(ID, tm, OptLevel), TM(tm) {} bool runOnMachineFunction(MachineFunction &MF) override { // Make sure we re-emit a set of the global base reg if necessary @@ -445,19 +447,11 @@ private: void transferMemOperands(SDNode *N, SDNode *Result); }; - class PPCDAGToDAGISelLegacy : public SelectionDAGISelLegacy { - public: - static char ID; - explicit PPCDAGToDAGISelLegacy(PPCTargetMachine &tm, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(tm, OptLevel)) {} - }; } // end anonymous namespace -char PPCDAGToDAGISelLegacy::ID = 0; +char PPCDAGToDAGISel::ID = 0; -INITIALIZE_PASS(PPCDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(PPCDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) /// getGlobalBaseReg - Output the instructions required to put the /// base address to use for accessing globals into a register. @@ -7927,5 +7921,5 @@ void PPCDAGToDAGISel::PeepholePPC64() { /// FunctionPass *llvm::createPPCISelDag(PPCTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new PPCDAGToDAGISelLegacy(TM, OptLevel); + return new PPCDAGToDAGISel(TM, OptLevel); } diff --git a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp index 1ef891d1b677..714cf69827a1 100644 --- a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -141,7 +141,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTarget() { initializePPCExpandAtomicPseudoPass(PR); initializeGlobalISel(PR); initializePPCCTRLoopsPass(PR); - initializePPCDAGToDAGISelLegacyPass(PR); + initializePPCDAGToDAGISelPass(PR); initializePPCMergeStringPoolPass(PR); } diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h index 8d2e1fc340c3..dcf4c65c44df 100644 --- a/llvm/lib/Target/RISCV/RISCV.h +++ b/llvm/lib/Target/RISCV/RISCV.h @@ -82,7 +82,7 @@ void initializeRISCVPushPopOptPass(PassRegistry &); InstructionSelector *createRISCVInstructionSelector(const RISCVTargetMachine &, RISCVSubtarget &, RISCVRegisterBankInfo &); -void initializeRISCVDAGToDAGISelLegacyPass(PassRegistry &); +void initializeRISCVDAGToDAGISelPass(PassRegistry &); FunctionPass *createRISCVPostLegalizerCombiner(); void initializeRISCVPostLegalizerCombinerPass(PassRegistry &); diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 251401db3e28..d965dd4fc9a9 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -3912,14 +3912,9 @@ bool RISCVDAGToDAGISel::doPeepholeNoRegPassThru() { // for instruction scheduling. FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new RISCVDAGToDAGISelLegacy(TM, OptLevel); + return new RISCVDAGToDAGISel(TM, OptLevel); } -char RISCVDAGToDAGISelLegacy::ID = 0; +char RISCVDAGToDAGISel::ID = 0; -RISCVDAGToDAGISelLegacy::RISCVDAGToDAGISelLegacy(RISCVTargetMachine &TM, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} - -INITIALIZE_PASS(RISCVDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(RISCVDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h index 5d70245c0c55..ece04dd7f4b7 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h @@ -25,11 +25,13 @@ class RISCVDAGToDAGISel : public SelectionDAGISel { const RISCVSubtarget *Subtarget = nullptr; public: + static char ID; + RISCVDAGToDAGISel() = delete; explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine, CodeGenOptLevel OptLevel) - : SelectionDAGISel(TargetMachine, OptLevel) {} + : SelectionDAGISel(ID, TargetMachine, OptLevel) {} bool runOnMachineFunction(MachineFunction &MF) override { Subtarget = &MF.getSubtarget(); @@ -194,13 +196,6 @@ private: bool performCombineVMergeAndVOps(SDNode *N); }; -class RISCVDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit RISCVDAGToDAGISelLegacy(RISCVTargetMachine &TargetMachine, - CodeGenOptLevel OptLevel); -}; - namespace RISCV { struct VLSEGPseudo { uint16_t NF : 4; diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index 35d0b3408d09..87ae2ee0d379 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -123,7 +123,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { initializeRISCVInsertVSETVLIPass(*PR); initializeRISCVInsertReadWriteCSRPass(*PR); initializeRISCVInsertWriteVXRMPass(*PR); - initializeRISCVDAGToDAGISelLegacyPass(*PR); + initializeRISCVDAGToDAGISelPass(*PR); initializeRISCVMoveMergePass(*PR); initializeRISCVPushPopOptPass(*PR); } diff --git a/llvm/lib/Target/Sparc/Sparc.h b/llvm/lib/Target/Sparc/Sparc.h index 33a803469603..fca7657871e8 100644 --- a/llvm/lib/Target/Sparc/Sparc.h +++ b/llvm/lib/Target/Sparc/Sparc.h @@ -31,7 +31,7 @@ FunctionPass *createSparcDelaySlotFillerPass(); void LowerSparcMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP); -void initializeSparcDAGToDAGISelLegacyPass(PassRegistry &); +void initializeSparcDAGToDAGISelPass(PassRegistry &); } // namespace llvm namespace llvm { diff --git a/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 253161194819..3c9841d81b4f 100644 --- a/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -35,11 +35,12 @@ class SparcDAGToDAGISel : public SelectionDAGISel { /// Subtarget - Keep a pointer to the Sparc Subtarget around so that we can /// make the right decision when generating code for different targets. const SparcSubtarget *Subtarget = nullptr; - public: + static char ID; + SparcDAGToDAGISel() = delete; - explicit SparcDAGToDAGISel(SparcTargetMachine &tm) : SelectionDAGISel(tm) {} + explicit SparcDAGToDAGISel(SparcTargetMachine &tm) : SelectionDAGISel(ID, tm) {} bool runOnMachineFunction(MachineFunction &MF) override { Subtarget = &MF.getSubtarget(); @@ -65,18 +66,11 @@ private: SDNode* getGlobalBaseReg(); bool tryInlineAsm(SDNode *N); }; - -class SparcDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit SparcDAGToDAGISelLegacy(SparcTargetMachine &tm) - : SelectionDAGISelLegacy(ID, std::make_unique(tm)) {} -}; } // end anonymous namespace -char SparcDAGToDAGISelLegacy::ID = 0; +char SparcDAGToDAGISel::ID = 0; -INITIALIZE_PASS(SparcDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(SparcDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) SDNode* SparcDAGToDAGISel::getGlobalBaseReg() { Register GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF); @@ -403,5 +397,5 @@ bool SparcDAGToDAGISel::SelectInlineAsmMemoryOperand( /// SPARC-specific DAG, ready for instruction scheduling. /// FunctionPass *llvm::createSparcISelDag(SparcTargetMachine &TM) { - return new SparcDAGToDAGISelLegacy(TM); + return new SparcDAGToDAGISel(TM); } diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp index ea403230bea8..20ddafb0e43d 100644 --- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp +++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp @@ -28,7 +28,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcTarget() { RegisterTargetMachine Z(getTheSparcelTarget()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeSparcDAGToDAGISelLegacyPass(PR); + initializeSparcDAGToDAGISelPass(PR); } static cl::opt diff --git a/llvm/lib/Target/SystemZ/SystemZ.h b/llvm/lib/Target/SystemZ/SystemZ.h index 8824954ce448..d7aa9e4e18cb 100644 --- a/llvm/lib/Target/SystemZ/SystemZ.h +++ b/llvm/lib/Target/SystemZ/SystemZ.h @@ -199,7 +199,7 @@ FunctionPass *createSystemZPostRewritePass(SystemZTargetMachine &TM); FunctionPass *createSystemZTDCPass(); void initializeSystemZCopyPhysRegsPass(PassRegistry &); -void initializeSystemZDAGToDAGISelLegacyPass(PassRegistry &); +void initializeSystemZDAGToDAGISelPass(PassRegistry &); void initializeSystemZElimComparePass(PassRegistry &); void initializeSystemZLDCleanupPass(PassRegistry &); void initializeSystemZLongBranchPass(PassRegistry &); diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index 6c6a9b490d91..1bf23c2e8e41 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -356,10 +356,12 @@ class SystemZDAGToDAGISel : public SelectionDAGISel { bool shouldSelectForReassoc(SDNode *N) const; public: + static char ID; + SystemZDAGToDAGISel() = delete; SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(TM, OptLevel) {} + : SelectionDAGISel(ID, TM, OptLevel) {} bool runOnMachineFunction(MachineFunction &MF) override { const Function &F = MF.getFunction(); @@ -385,24 +387,15 @@ public: // Include the pieces autogenerated from the target description. #include "SystemZGenDAGISel.inc" }; - -class SystemZDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit SystemZDAGToDAGISelLegacy(SystemZTargetMachine &TM, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} -}; } // end anonymous namespace -char SystemZDAGToDAGISelLegacy::ID = 0; +char SystemZDAGToDAGISel::ID = 0; -INITIALIZE_PASS(SystemZDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(SystemZDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) FunctionPass *llvm::createSystemZISelDag(SystemZTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new SystemZDAGToDAGISelLegacy(TM, OptLevel); + return new SystemZDAGToDAGISel(TM, OptLevel); } // Return true if Val should be selected as a displacement for an address diff --git a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp index 6f76839724ee..dced64d6b21a 100644 --- a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp +++ b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp @@ -47,7 +47,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZTarget() { initializeSystemZShortenInstPass(PR); initializeSystemZPostRewritePass(PR); initializeSystemZTDCPassPass(PR); - initializeSystemZDAGToDAGISelLegacyPass(PR); + initializeSystemZDAGToDAGISelPass(PR); } static std::string computeDataLayout(const Triple &TT) { diff --git a/llvm/lib/Target/VE/VE.h b/llvm/lib/Target/VE/VE.h index ee76c5121d36..6f0243010ba0 100644 --- a/llvm/lib/Target/VE/VE.h +++ b/llvm/lib/Target/VE/VE.h @@ -29,7 +29,7 @@ class VETargetMachine; FunctionPass *createVEISelDag(VETargetMachine &TM); FunctionPass *createLVLGenPass(); -void initializeVEDAGToDAGISelLegacyPass(PassRegistry &); +void initializeVEDAGToDAGISelPass(PassRegistry &); void LowerVEMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP); diff --git a/llvm/lib/Target/VE/VEISelDAGToDAG.cpp b/llvm/lib/Target/VE/VEISelDAGToDAG.cpp index 680bd12fb4b6..87646bc1a12f 100644 --- a/llvm/lib/Target/VE/VEISelDAGToDAG.cpp +++ b/llvm/lib/Target/VE/VEISelDAGToDAG.cpp @@ -34,9 +34,11 @@ class VEDAGToDAGISel : public SelectionDAGISel { const VESubtarget *Subtarget; public: + static char ID; + VEDAGToDAGISel() = delete; - explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {} + explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(ID, tm) {} bool runOnMachineFunction(MachineFunction &MF) override { Subtarget = &MF.getSubtarget(); @@ -68,18 +70,11 @@ private: bool matchADDRrr(SDValue N, SDValue &Base, SDValue &Index); bool matchADDRri(SDValue N, SDValue &Base, SDValue &Offset); }; - -class VEDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit VEDAGToDAGISelLegacy(VETargetMachine &tm) - : SelectionDAGISelLegacy(ID, std::make_unique(tm)) {} -}; } // end anonymous namespace -char VEDAGToDAGISelLegacy::ID = 0; +char VEDAGToDAGISel::ID = 0; -INITIALIZE_PASS(VEDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(VEDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) bool VEDAGToDAGISel::selectADDRrri(SDValue Addr, SDValue &Base, SDValue &Index, SDValue &Offset) { @@ -341,5 +336,5 @@ SDNode *VEDAGToDAGISel::getGlobalBaseReg() { /// VE-specific DAG, ready for instruction scheduling. /// FunctionPass *llvm::createVEISelDag(VETargetMachine &TM) { - return new VEDAGToDAGISelLegacy(TM); + return new VEDAGToDAGISel(TM); } diff --git a/llvm/lib/Target/VE/VETargetMachine.cpp b/llvm/lib/Target/VE/VETargetMachine.cpp index 383667bf79e1..6f4e137e4d2f 100644 --- a/llvm/lib/Target/VE/VETargetMachine.cpp +++ b/llvm/lib/Target/VE/VETargetMachine.cpp @@ -30,7 +30,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVETarget() { RegisterTargetMachine X(getTheVETarget()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeVEDAGToDAGISelLegacyPass(PR); + initializeVEDAGToDAGISelPass(PR); } static std::string computeDataLayout(const Triple &T) { diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h index 8f142fa0928c..7fc8546248f1 100644 --- a/llvm/lib/Target/WebAssembly/WebAssembly.h +++ b/llvm/lib/Target/WebAssembly/WebAssembly.h @@ -67,7 +67,7 @@ void initializeWebAssemblyArgumentMovePass(PassRegistry &); void initializeWebAssemblyCleanCodeAfterTrapPass(PassRegistry &); void initializeWebAssemblyCFGSortPass(PassRegistry &); void initializeWebAssemblyCFGStackifyPass(PassRegistry &); -void initializeWebAssemblyDAGToDAGISelLegacyPass(PassRegistry &); +void initializeWebAssemblyDAGToDAGISelPass(PassRegistry &); void initializeWebAssemblyDebugFixupPass(PassRegistry &); void initializeWebAssemblyExceptionInfoPass(PassRegistry &); void initializeWebAssemblyExplicitLocalsPass(PassRegistry &); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp index 0f06f54f219f..8833aee02a6a 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp @@ -42,11 +42,13 @@ class WebAssemblyDAGToDAGISel final : public SelectionDAGISel { const WebAssemblySubtarget *Subtarget; public: + static char ID; + WebAssemblyDAGToDAGISel() = delete; WebAssemblyDAGToDAGISel(WebAssemblyTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(TM, OptLevel), Subtarget(nullptr) {} + : SelectionDAGISel(ID, TM, OptLevel), Subtarget(nullptr) {} bool runOnMachineFunction(MachineFunction &MF) override { LLVM_DEBUG(dbgs() << "********** ISelDAGToDAG **********\n" @@ -80,21 +82,11 @@ private: bool SelectAddrAddOperands(MVT OffsetType, SDValue N, SDValue &Offset, SDValue &Addr); }; - -class WebAssemblyDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - explicit WebAssemblyDAGToDAGISelLegacy(WebAssemblyTargetMachine &TM, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} -}; } // end anonymous namespace -char WebAssemblyDAGToDAGISelLegacy::ID; +char WebAssemblyDAGToDAGISel::ID; -INITIALIZE_PASS(WebAssemblyDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, - false) +INITIALIZE_PASS(WebAssemblyDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) void WebAssemblyDAGToDAGISel::PreprocessISelDAG() { // Stack objects that should be allocated to locals are hoisted to WebAssembly @@ -417,5 +409,5 @@ bool WebAssemblyDAGToDAGISel::SelectAddrOperands64(SDValue Op, SDValue &Offset, /// for instruction scheduling. FunctionPass *llvm::createWebAssemblyISelDag(WebAssemblyTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new WebAssemblyDAGToDAGISelLegacy(TM, OptLevel); + return new WebAssemblyDAGToDAGISel(TM, OptLevel); } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index 23539a5f4b26..fd92a35c2638 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -90,7 +90,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTarget() { initializeWebAssemblyMCLowerPrePassPass(PR); initializeWebAssemblyLowerRefTypesIntPtrConvPass(PR); initializeWebAssemblyFixBrTableDefaultsPass(PR); - initializeWebAssemblyDAGToDAGISelLegacyPass(PR); + initializeWebAssemblyDAGToDAGISelPass(PR); } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h index fdb9e4cad5e8..21623a805f55 100644 --- a/llvm/lib/Target/X86/X86.h +++ b/llvm/lib/Target/X86/X86.h @@ -179,7 +179,7 @@ void initializeX86AvoidSFBPassPass(PassRegistry &); void initializeX86AvoidTrailingCallPassPass(PassRegistry &); void initializeX86CallFrameOptimizationPass(PassRegistry &); void initializeX86CmovConverterPassPass(PassRegistry &); -void initializeX86DAGToDAGISelLegacyPass(PassRegistry &); +void initializeX86DAGToDAGISelPass(PassRegistry &); void initializeX86DomainReassignmentPass(PassRegistry &); void initializeX86ExecutionDomainFixPass(PassRegistry &); void initializeX86ExpandPseudoPass(PassRegistry &); diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp index cc5937d0bda6..7c1fb0b99f41 100644 --- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp +++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp @@ -10,12 +10,10 @@ /// TODO: Port CodeGen passes to new pass manager. //===----------------------------------------------------------------------===// -#include "X86ISelDAGToDAG.h" #include "X86TargetMachine.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Passes/CodeGenPassBuilder.h" -#include "llvm/Passes/PassBuilder.h" using namespace llvm; @@ -42,20 +40,13 @@ void X86CodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass, // TODO: Add AsmPrinter. } -Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &addPass) const { +Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &) const { // TODO: Add instruction selector. - addPass(X86ISelDAGToDAGPass(static_cast(TM))); return Error::success(); } } // namespace -void X86TargetMachine::registerPassBuilderCallbacks( - PassBuilder &PB, bool PopulateClassToPassNames) { -#define GET_PASS_REGISTRY "X86PassRegistry.def" -#include "llvm/Passes/TargetPassRegistry.inc" -} - Error X86TargetMachine::buildCodeGenPipeline( ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType, const CGPassBuilderOption &Opt, diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 0bf3294af92a..3227bf75a43f 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include "X86ISelDAGToDAG.h" #include "X86.h" #include "X86MachineFunctionInfo.h" #include "X86RegisterInfo.h" @@ -170,10 +169,12 @@ namespace { bool IndirectTlsSegRefs; public: + static char ID; + X86DAGToDAGISel() = delete; explicit X86DAGToDAGISel(X86TargetMachine &tm, CodeGenOptLevel OptLevel) - : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr), + : SelectionDAGISel(ID, tm, OptLevel), Subtarget(nullptr), OptForMinSize(false), IndirectTlsSegRefs(false) {} bool runOnMachineFunction(MachineFunction &MF) override { @@ -186,7 +187,9 @@ namespace { OptForMinSize = MF.getFunction().hasMinSize(); assert((!OptForMinSize || MF.getFunction().hasOptSize()) && "OptForMinSize implies OptForSize"); - return SelectionDAGISel::runOnMachineFunction(MF); + + SelectionDAGISel::runOnMachineFunction(MF); + return true; } void emitFunctionEntryCode() override; @@ -574,20 +577,11 @@ namespace { bool hasNoSignFlagUses(SDValue Flags) const; bool hasNoCarryFlagUses(SDValue Flags) const; }; - - class X86DAGToDAGISelLegacy : public SelectionDAGISelLegacy { - public: - static char ID; - explicit X86DAGToDAGISelLegacy(X86TargetMachine &tm, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(tm, OptLevel)) {} - }; } -char X86DAGToDAGISelLegacy::ID = 0; +char X86DAGToDAGISel::ID = 0; -INITIALIZE_PASS(X86DAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(X86DAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) // Returns true if this masked compare can be implemented legally with this // type. @@ -6599,13 +6593,9 @@ bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand( return false; } -X86ISelDAGToDAGPass::X86ISelDAGToDAGPass(X86TargetMachine &TM) - : SelectionDAGISelPass( - std::make_unique(TM, TM.getOptLevel())) {} - /// This pass converts a legalized DAG into a X86-specific DAG, /// ready for instruction scheduling. FunctionPass *llvm::createX86ISelDag(X86TargetMachine &TM, CodeGenOptLevel OptLevel) { - return new X86DAGToDAGISelLegacy(TM, OptLevel); + return new X86DAGToDAGISel(TM, OptLevel); } diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.h b/llvm/lib/Target/X86/X86ISelDAGToDAG.h deleted file mode 100644 index 1f30c25b502f..000000000000 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.h +++ /dev/null @@ -1,25 +0,0 @@ -//===-- X86ISelDAGToDAG.h ---------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_X86_X86ISELDAGTODAG_H -#define LLVM_LIB_TARGET_X86_X86ISELDAGTODAG_H - -#include "llvm/CodeGen/SelectionDAGISel.h" - -namespace llvm { - -class X86TargetMachine; - -class X86ISelDAGToDAGPass : public SelectionDAGISelPass { -public: - X86ISelDAGToDAGPass(X86TargetMachine &TM); -}; - -} // namespace llvm - -#endif // LLVM_LIB_TARGET_X86_X86ISELDAGTODAG_H diff --git a/llvm/lib/Target/X86/X86PassRegistry.def b/llvm/lib/Target/X86/X86PassRegistry.def deleted file mode 100644 index 620526ffc1ab..000000000000 --- a/llvm/lib/Target/X86/X86PassRegistry.def +++ /dev/null @@ -1,19 +0,0 @@ -//===- X86PassRegistry.def - Registry of X86 specific passes ----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file is used as the registry of passes that are part of the X86 backend. -// -//===----------------------------------------------------------------------===// - -// NOTE: NO INCLUDE GUARD DESIRED! - -#ifndef MACHINE_FUNCTION_PASS -#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) -#endif -MACHINE_FUNCTION_PASS("x86-isel", X86ISelDAGToDAGPass(*this)) -#undef MACHINE_FUNCTION_PASS diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index 27542e54829b..ab59cf8a309a 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -100,7 +100,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86Target() { initializeX86PartialReductionPass(PR); initializePseudoProbeInserterPass(PR); initializeX86ReturnThunksPass(PR); - initializeX86DAGToDAGISelLegacyPass(PR); + initializeX86DAGToDAGISelPass(PR); initializeX86ArgumentStackSlotPassPass(PR); initializeX86FixupInstTuningPassPass(PR); initializeX86FixupVectorConstantsPassPass(PR); diff --git a/llvm/lib/Target/X86/X86TargetMachine.h b/llvm/lib/Target/X86/X86TargetMachine.h index 4a5f20fcc017..4e7ded16729d 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.h +++ b/llvm/lib/Target/X86/X86TargetMachine.h @@ -58,9 +58,6 @@ public: createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override; - void registerPassBuilderCallbacks(PassBuilder &PB, - bool PopulateClassToPassNames) override; - Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &, raw_pwrite_stream *, CodeGenFileType, const CGPassBuilderOption &, diff --git a/llvm/lib/Target/XCore/XCore.h b/llvm/lib/Target/XCore/XCore.h index ad50f05a89d8..f019fa49f185 100644 --- a/llvm/lib/Target/XCore/XCore.h +++ b/llvm/lib/Target/XCore/XCore.h @@ -31,7 +31,7 @@ namespace llvm { FunctionPass *createXCoreISelDag(XCoreTargetMachine &TM, CodeGenOptLevel OptLevel); ModulePass *createXCoreLowerThreadLocalPass(); - void initializeXCoreDAGToDAGISelLegacyPass(PassRegistry &); + void initializeXCoreDAGToDAGISelPass(PassRegistry &); } // end namespace llvm; diff --git a/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp b/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp index dcbf1145a5cc..1535eb622da6 100644 --- a/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp +++ b/llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp @@ -41,10 +41,12 @@ namespace { class XCoreDAGToDAGISel : public SelectionDAGISel { public: + static char ID; + XCoreDAGToDAGISel() = delete; XCoreDAGToDAGISel(XCoreTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(TM, OptLevel) {} + : SelectionDAGISel(ID, TM, OptLevel) {} void Select(SDNode *N) override; bool tryBRIND(SDNode *N); @@ -76,27 +78,18 @@ namespace { // Include the pieces autogenerated from the target description. #include "XCoreGenDAGISel.inc" }; - - class XCoreDAGToDAGISelLegacy : public SelectionDAGISelLegacy { - public: - static char ID; - explicit XCoreDAGToDAGISelLegacy(XCoreTargetMachine &TM, - CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} - }; } // end anonymous namespace -char XCoreDAGToDAGISelLegacy::ID = 0; +char XCoreDAGToDAGISel::ID = 0; -INITIALIZE_PASS(XCoreDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS(XCoreDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) /// createXCoreISelDag - This pass converts a legalized DAG into a /// XCore-specific DAG, ready for instruction scheduling. /// FunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new XCoreDAGToDAGISelLegacy(TM, OptLevel); + return new XCoreDAGToDAGISel(TM, OptLevel); } bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base, diff --git a/llvm/lib/Target/XCore/XCoreTargetMachine.cpp b/llvm/lib/Target/XCore/XCoreTargetMachine.cpp index bb5beefbb65e..374e91d01bda 100644 --- a/llvm/lib/Target/XCore/XCoreTargetMachine.cpp +++ b/llvm/lib/Target/XCore/XCoreTargetMachine.cpp @@ -107,7 +107,7 @@ void XCorePassConfig::addPreEmitPass() { extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXCoreTarget() { RegisterTargetMachine X(getTheXCoreTarget()); PassRegistry &PR = *PassRegistry::getPassRegistry(); - initializeXCoreDAGToDAGISelLegacyPass(PR); + initializeXCoreDAGToDAGISelPass(PR); } TargetTransformInfo diff --git a/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp b/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp index 145f28503635..5ebedefafc16 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp @@ -28,8 +28,14 @@ namespace { class XtensaDAGToDAGISel : public SelectionDAGISel { public: + static char ID; + XtensaDAGToDAGISel(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISel(TM, OptLevel) {} + : SelectionDAGISel(ID, TM, OptLevel) {} + + StringRef getPassName() const override { + return "Xtensa DAG->DAG Pattern Instruction Selection"; + } void Select(SDNode *Node) override; @@ -101,26 +107,13 @@ public: // Include the pieces autogenerated from the target description. #include "XtensaGenDAGISel.inc" }; // namespace - -class XtensaDAGToDAGISelLegacy : public SelectionDAGISelLegacy { -public: - static char ID; - - XtensaDAGToDAGISelLegacy(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel) - : SelectionDAGISelLegacy( - ID, std::make_unique(TM, OptLevel)) {} - - StringRef getPassName() const override { - return "Xtensa DAG->DAG Pattern Instruction Selection"; - } -}; } // end anonymous namespace -char XtensaDAGToDAGISelLegacy::ID = 0; +char XtensaDAGToDAGISel::ID = 0; FunctionPass *llvm::createXtensaISelDag(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel) { - return new XtensaDAGToDAGISelLegacy(TM, OptLevel); + return new XtensaDAGToDAGISel(TM, OptLevel); } void XtensaDAGToDAGISel::Select(SDNode *Node) { diff --git a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll index 85a701b23a6c..41eb2b7bb274 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll @@ -3,10 +3,6 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908_GFX11 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908_GFX11 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908_GFX11 %s define amdgpu_ps void @buffer_atomic_fadd_f32_offset_no_rtn(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { ; GFX908_GFX11-LABEL: name: buffer_atomic_fadd_f32_offset_no_rtn diff --git a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-rtn.ll b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-rtn.ll index 417dee573c5d..f964da2ddf40 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f32-rtn.ll @@ -1,10 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s define amdgpu_ps float @buffer_atomic_fadd_f32_offset_rtn(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { ; GFX90A_GFX940-LABEL: name: buffer_atomic_fadd_f32_offset_rtn diff --git a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll index ff087715e0fc..89a29526320c 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll @@ -1,8 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps void @buffer_atomic_fadd_f64_offset_no_rtn(double %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { ; GFX90A_GFX940-LABEL: name: buffer_atomic_fadd_f64_offset_no_rtn diff --git a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll index 44fddc372293..0b62977613f1 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll @@ -2,9 +2,6 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps void @buffer_atomic_fadd_v2f16_offset_no_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { ; GFX908-LABEL: name: buffer_atomic_fadd_v2f16_offset_no_rtn diff --git a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll index c4ef1390a288..8c33683c0f5e 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll @@ -1,8 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps <2 x half> @buffer_atomic_fadd_v2f16_offset_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) { ; GFX90A_GFX940-LABEL: name: buffer_atomic_fadd_v2f16_offset_rtn diff --git a/llvm/test/CodeGen/AMDGPU/buffer-intrinsics-mmo-offsets.ll b/llvm/test/CodeGen/AMDGPU/buffer-intrinsics-mmo-offsets.ll index a62ea8fe4606..f4cd19a2ffa8 100644 --- a/llvm/test/CodeGen/AMDGPU/buffer-intrinsics-mmo-offsets.ll +++ b/llvm/test/CodeGen/AMDGPU/buffer-intrinsics-mmo-offsets.ll @@ -1,6 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -verify-machineinstrs -amdgpu-atomic-optimizer-strategy=None -stop-after=amdgpu-isel -o - %s | FileCheck -check-prefix=GCN %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -enable-new-pm -amdgpu-atomic-optimizer-strategy=None -stop-after=amdgpu-isel -o - %s | FileCheck -check-prefix=GCN %s define amdgpu_cs void @mmo_offsets0(ptr addrspace(6) inreg noalias align(16) dereferenceable(18446744073709551615) %arg0, i32 %arg1) { ; GCN-LABEL: name: mmo_offsets0 diff --git a/llvm/test/CodeGen/AMDGPU/bug-v4f64-subvector.ll b/llvm/test/CodeGen/AMDGPU/bug-v4f64-subvector.ll index 2c7072b8c93b..459913eb4f6e 100644 --- a/llvm/test/CodeGen/AMDGPU/bug-v4f64-subvector.ll +++ b/llvm/test/CodeGen/AMDGPU/bug-v4f64-subvector.ll @@ -1,5 +1,4 @@ ; RUN: llc < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -start-before=amdgpu-isel -stop-after=amdgpu-isel -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK -; RUN: llc < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -stop-after=amdgpu-isel -enable-new-pm | FileCheck %s --check-prefixes=CHECK ; This caused failure in infinite cycle in Selection DAG (combine) due to missing insert_subvector. ; diff --git a/llvm/test/CodeGen/AMDGPU/carryout-selection.ll b/llvm/test/CodeGen/AMDGPU/carryout-selection.ll index a0499ef6d0f6..9a22635e880f 100644 --- a/llvm/test/CodeGen/AMDGPU/carryout-selection.ll +++ b/llvm/test/CodeGen/AMDGPU/carryout-selection.ll @@ -1,6 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN-ISEL %s -; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel -enable-new-pm < %s | FileCheck -enable-var-scope -check-prefixes=GCN-ISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=verde -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=CISI %s ; RUN: llc -mtriple=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=VI %s diff --git a/llvm/test/CodeGen/AMDGPU/dagcombine-fma-crash.ll b/llvm/test/CodeGen/AMDGPU/dagcombine-fma-crash.ll index 8b1a6878136a..09a1f4555760 100644 --- a/llvm/test/CodeGen/AMDGPU/dagcombine-fma-crash.ll +++ b/llvm/test/CodeGen/AMDGPU/dagcombine-fma-crash.ll @@ -1,6 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx1030 -start-before=amdgpu-isel -stop-after=amdgpu-isel < %s | FileCheck %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx1030 -enable-new-pm -start-before=amdgpu-isel -stop-after=amdgpu-isel < %s | FileCheck %s define void @main(float %arg) { ; CHECK-LABEL: name: main diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-abs.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-abs.ll index 4ea553b8aaad..c135acaaf474 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-abs.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-abs.ll @@ -1,7 +1,5 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX900 %s -; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX900 %s ; GCN-LABEL: name: s_abs_i32 ; GCN: S_ABS_I32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-bitreverse.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-bitreverse.ll index 85ae5f13e731..d5597df08aa2 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-bitreverse.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-bitreverse.ll @@ -1,5 +1,4 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s -; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; GCN-LABEL: name: uniform_bitreverse_i32 ; GCN: S_BREV_B32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-ctlz-cttz.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-ctlz-cttz.ll index 030de51abb90..45cb4c623a4b 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-ctlz-cttz.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-ctlz-cttz.ll @@ -1,5 +1,4 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s -; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; GCN-LABEL: name: s_ctlz_i32 ; GCN: S_FLBIT_I32_B32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-ctpop.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-ctpop.ll index 4a3a44d09210..5c5b7b3e5b9a 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-ctpop.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-ctpop.ll @@ -1,5 +1,4 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s -; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; GCN-LABEL: name: s_ctpop_i32 ; GCN: S_BCNT1_I32_B32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll index 45c805aa1b80..2711e532fc16 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll @@ -1,5 +1,4 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s -; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; GCN-LABEL: name: uniform_imin ; GCN: S_MIN_I32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-negsubinlineconst.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-negsubinlineconst.ll index e740bb3d5eef..a7f3c18accc9 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-negsubinlineconst.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-negsubinlineconst.ll @@ -1,7 +1,5 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX900 %s -; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX900 %s ; GCN-LABEL: name: uniform_add_SIC ; GCN: S_SUB_I32 killed %{{[0-9]+}}, 32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-not-isel.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-not-isel.ll index 5f0d17d08660..f673f2f43d7f 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-not-isel.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-not-isel.ll @@ -1,5 +1,4 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s -; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; GCN-LABEL: name: scalar_not_i32 ; GCN: S_NOT_B32 diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-xnor.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-xnor.ll index e8d8b1eb1abc..ccfc908b4005 100644 --- a/llvm/test/CodeGen/AMDGPU/divergence-driven-xnor.ll +++ b/llvm/test/CodeGen/AMDGPU/divergence-driven-xnor.ll @@ -1,7 +1,5 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx906 -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN_DL %s -; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx906 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN_DL %s ; GCN-LABEL: name: uniform_xnor_i64 ; GCN: S_XNOR_B64 diff --git a/llvm/test/CodeGen/AMDGPU/extract_subvector_vec4_vec3.ll b/llvm/test/CodeGen/AMDGPU/extract_subvector_vec4_vec3.ll index 1319c526868c..d0c0d3acf271 100644 --- a/llvm/test/CodeGen/AMDGPU/extract_subvector_vec4_vec3.ll +++ b/llvm/test/CodeGen/AMDGPU/extract_subvector_vec4_vec3.ll @@ -1,6 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 < %s -stop-after=amdgpu-isel | FileCheck -check-prefix=GCN %s -; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 < %s -enable-new-pm -stop-after=amdgpu-isel | FileCheck -check-prefix=GCN %s ; We want to see a BUFFER_LOAD, some register shuffling, and a BUFFER_STORE. ; Specifically, we do not want to see a BUFFER_STORE that says "store into diff --git a/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f32.ll b/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f32.ll index 5eb8620f1ff2..ce4beb8789dc 100644 --- a/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f32.ll +++ b/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f32.ll @@ -1,8 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX11 %s define amdgpu_ps void @flat_atomic_fadd_f32_no_rtn_intrinsic(ptr %ptr, float %data) { ; GFX940-LABEL: name: flat_atomic_fadd_f32_no_rtn_intrinsic diff --git a/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f64.ll b/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f64.ll index df803ad8470d..afd38136870b 100644 --- a/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f64.ll +++ b/llvm/test/CodeGen/AMDGPU/flat-atomic-fadd.f64.ll @@ -1,8 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps void @flat_atomic_fadd_f64_no_rtn_intrinsic(ptr %ptr, double %data) { ; GFX90A_GFX940-LABEL: name: flat_atomic_fadd_f64_no_rtn_intrinsic diff --git a/llvm/test/CodeGen/AMDGPU/fneg-fabs-divergence-driven-isel.ll b/llvm/test/CodeGen/AMDGPU/fneg-fabs-divergence-driven-isel.ll index d431503643d6..07f315ea6cb4 100644 --- a/llvm/test/CodeGen/AMDGPU/fneg-fabs-divergence-driven-isel.ll +++ b/llvm/test/CodeGen/AMDGPU/fneg-fabs-divergence-driven-isel.ll @@ -1,7 +1,5 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefixes=GCN,SI %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -stop-after=amdgpu-isel < %s | FileCheck -check-prefixes=GCN,FP16 %s -; RUN: llc -mtriple=amdgcn -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefixes=GCN,SI %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefixes=GCN,FP16 %s define amdgpu_kernel void @divergent_fneg_f32(ptr addrspace(1) %out, ptr addrspace(1) %in) { diff --git a/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll b/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll index 60345c0b4433..666971618a5c 100644 --- a/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll @@ -2,9 +2,6 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx908 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX908 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps void @global_atomic_fadd_v2f16_no_rtn_intrinsic(ptr addrspace(1) %ptr, <2 x half> %data) { ; GFX908-LABEL: name: global_atomic_fadd_v2f16_no_rtn_intrinsic diff --git a/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-rtn.ll b/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-rtn.ll index c8caf1fe365b..ae81e97ca39e 100644 --- a/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/global-atomic-fadd.v2f16-rtn.ll @@ -1,8 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx940 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GFX90A_GFX940 %s define amdgpu_ps <2 x half> @global_atomic_fadd_v2f16_rtn_intrinsic(ptr addrspace(1) %ptr, <2 x half> %data) { ; GFX90A_GFX940-LABEL: name: global_atomic_fadd_v2f16_rtn_intrinsic diff --git a/llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll b/llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll index 6d1adb9c1f87..9927f4d166ba 100644 --- a/llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll +++ b/llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll @@ -1,5 +1,4 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -start-before=amdgpu-isel -stop-after=amdgpu-isel -verify-machineinstrs < %s | FileCheck %s --check-prefix=GCN -; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -start-before=amdgpu-isel -stop-after=amdgpu-isel -enable-new-pm < %s | FileCheck %s --check-prefix=GCN ; We're really just checking for no crashes ; The feature we're testing for in AdjustWriteMask leaves the image_load as an instruction just post amdgpu-isel diff --git a/llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll b/llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll index f2858e4ff79c..88605785f814 100644 --- a/llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll +++ b/llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll @@ -1,5 +1,4 @@ ; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel -verify-machineinstrs -o - %s | FileCheck %s -; RUN: llc -mtriple=amdgcn -stop-after=amdgpu-isel -enable-new-pm -o - %s | FileCheck %s ; CHECK-LABEL: vcopy_i1_undef ; CHECK: [[IMPDEF0:%[0-9]+]]:sreg_64 = IMPLICIT_DEF diff --git a/llvm/test/CodeGen/AMDGPU/legalize-fp-load-invariant.ll b/llvm/test/CodeGen/AMDGPU/legalize-fp-load-invariant.ll index 599488822b64..55fd8336e967 100644 --- a/llvm/test/CodeGen/AMDGPU/legalize-fp-load-invariant.ll +++ b/llvm/test/CodeGen/AMDGPU/legalize-fp-load-invariant.ll @@ -1,5 +1,4 @@ ; RUN: llc -mtriple=amdgcn -mcpu=tahiti -verify-machineinstrs -stop-after=amdgpu-isel -o - %s | FileCheck -check-prefix=GCN %s -; RUN: llc -mtriple=amdgcn -mcpu=tahiti -enable-new-pm -stop-after=amdgpu-isel -o - %s | FileCheck -check-prefix=GCN %s ; Type legalization for illegal FP type results was dropping invariant ; and dereferenceable flags. diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll index b4840bce53d2..18c977bf5100 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll @@ -1,6 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2 ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs -stop-after=amdgpu-isel < %s | FileCheck %s -; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -enable-new-pm -stop-after=amdgpu-isel < %s | FileCheck %s define amdgpu_ps ptr addrspace(8) @basic_raw_buffer(ptr inreg %p) { ; CHECK-LABEL: name: basic_raw_buffer diff --git a/llvm/test/CodeGen/X86/apx/no-rex2-general.ll b/llvm/test/CodeGen/X86/apx/no-rex2-general.ll index 805fc7ccaab7..1f92883f4170 100644 --- a/llvm/test/CodeGen/X86/apx/no-rex2-general.ll +++ b/llvm/test/CodeGen/X86/apx/no-rex2-general.ll @@ -1,8 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+sse2,+ssse3,+egpr | FileCheck %s --check-prefix=SSE ; RUN: llc < %s -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+sse2,+ssse3,+egpr,+avx | FileCheck %s --check-prefix=AVX -; RUN: llc < %s -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+sse2,+ssse3,+egpr | FileCheck %s --check-prefix=SSE -; RUN: llc < %s -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+sse2,+ssse3,+egpr,+avx | FileCheck %s --check-prefix=AVX define i32 @map0(ptr nocapture noundef readonly %a, i64 noundef %b) { ; SSE-LABEL: name: map0 diff --git a/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-amx.ll b/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-amx.ll index 5fa4cb4c8826..e082becbc441 100644 --- a/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-amx.ll +++ b/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-amx.ll @@ -1,6 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+amx-tile,+egpr | FileCheck %s -; RUN: llc < %s -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+amx-tile,+egpr | FileCheck %s define dso_local void @amx(ptr noundef %data) { ; CHECK-LABEL: name: amx diff --git a/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-x87.ll b/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-x87.ll index a9ca591a156c..10ec184516e7 100644 --- a/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-x87.ll +++ b/llvm/test/CodeGen/X86/apx/no-rex2-pseudo-x87.ll @@ -1,6 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=-sse,+egpr | FileCheck %s -; RUN: llc < %s -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=-sse,+egpr | FileCheck %s define void @x87(ptr %0, ptr %1) { ; CHECK-LABEL: name: x87 diff --git a/llvm/test/CodeGen/X86/apx/no-rex2-special.ll b/llvm/test/CodeGen/X86/apx/no-rex2-special.ll index 86534427a9ea..b27794969741 100644 --- a/llvm/test/CodeGen/X86/apx/no-rex2-special.ll +++ b/llvm/test/CodeGen/X86/apx/no-rex2-special.ll @@ -1,6 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+xsave,+egpr | FileCheck %s -; RUN: llc < %s -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel -mattr=+xsave,+egpr | FileCheck %s define void @test_xsave(ptr %ptr, i32 %hi, i32 %lo) { ; CHECK-LABEL: name: test_xsave diff --git a/llvm/test/tools/llc/new-pm/start-stop.ll b/llvm/test/tools/llc/new-pm/start-stop.ll index 9c3b9f009178..ba225d227d4c 100644 --- a/llvm/test/tools/llc/new-pm/start-stop.ll +++ b/llvm/test/tools/llc/new-pm/start-stop.ll @@ -1,5 +1,5 @@ ; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -start-before=mergeicmps -stop-after=gc-lowering -filetype=null %s | FileCheck --match-full-lines %s --check-prefix=NULL ; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -start-before=mergeicmps -stop-after=gc-lowering -o /dev/null %s | FileCheck --match-full-lines %s --check-prefix=OBJ -; NULL: require,require,require,function(verify,loop-mssa(loop-reduce),mergeicmps,expand-memcmp,gc-lowering,ee-instrument,verify) -; OBJ: require,require,require,function(verify,loop-mssa(loop-reduce),mergeicmps,expand-memcmp,gc-lowering,ee-instrument,verify),PrintMIRPreparePass,function(machine-function(print),invalidate) +; NULL: function(mergeicmps,expand-memcmp,gc-lowering) +; OBJ: function(mergeicmps,expand-memcmp,gc-lowering),PrintMIRPreparePass,function(machine-function(print),invalidate) -- GitLab From c9a86fa9a631eb77f229e457a323caec705600bf Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sun, 2 Jun 2024 10:34:48 +0100 Subject: [PATCH 029/678] [DAG] canCreateUndefOrPoison - fix missing argument typo We were missing the PoisonOnly argument (so Depth + 1 was being used instead and the default Depth = 0 argument then being silently used) Fixes #94145 and serves as the test case for 9e22c7a0ea87228dffcdfd7ab62724f72e0b3e30 --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 +- llvm/test/CodeGen/RISCV/pr94145.ll | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/RISCV/pr94145.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 3def51c49f3a..414c724b94f7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5286,7 +5286,7 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts, // If the max shift amount isn't in range, then the shift can // create poison. return !isGuaranteedNotToBeUndefOrPoison(Op.getOperand(1), DemandedElts, - Depth + 1) || + PoisonOnly, Depth + 1) || !getValidMaximumShiftAmount(Op, DemandedElts, Depth + 1); case ISD::SCALAR_TO_VECTOR: diff --git a/llvm/test/CodeGen/RISCV/pr94145.ll b/llvm/test/CodeGen/RISCV/pr94145.ll new file mode 100644 index 000000000000..17e355a9243d --- /dev/null +++ b/llvm/test/CodeGen/RISCV/pr94145.ll @@ -0,0 +1,20 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=riscv32-- | FileCheck %s +; RUN: llc < %s -mtriple=riscv64-- | FileCheck %s + +define i32 @PR94145(i16 %a0) { +; CHECK-LABEL: PR94145: +; CHECK: # %bb.0: +; CHECK-NEXT: andi a0, a0, 2 +; CHECK-NEXT: seqz a0, a0 +; CHECK-NEXT: li a1, 1 +; CHECK-NEXT: sll a0, a1, a0 +; CHECK-NEXT: ret + %lshr = lshr i16 %a0, 1 + %and = and i16 %lshr, 1 + %xor = xor i16 %and, 1 + %shl = shl i16 1, %xor + %freeze = freeze i16 %shl + %zext = zext i16 %freeze to i32 + ret i32 %zext +} -- GitLab From 45964eb9b88c46045e4e84beb4e2135cdeed6855 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 2 Jun 2024 03:37:31 -0700 Subject: [PATCH 030/678] [libc++] [test] Fix `__has_include` usage, expand condvarany and spaceship coverage (#94120) Three unrelated, small improvements: * `test_macros.h` was incorrectly saying `__has_include("")` instead of `__has_include()`. + This caused `` to always be included (noticed because MSVC's STL emitted a deprecation warning). + I searched all of LLVM and found no other occurrences. * `thread.condition.condvarany/wait_for_pred.pass.cpp` forgot to test anything. + I followed what `wait_for.pass.cpp` is testing. * Uncomment spaceship test coverage. --- .../totally_ordered.pass.cpp | 13 ++++++------- .../totally_ordered_with.pass.cpp | 7 ++----- .../wait_for_pred.pass.cpp | 8 +++++++- libcxx/test/support/test_macros.h | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp index 2e9dd0f9e7df..d0f90337ec48 100644 --- a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp +++ b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp @@ -111,13 +111,12 @@ static_assert(!std::totally_ordered >); static_assert(!std::totally_ordered >); struct A {}; -// FIXME(cjdb): uncomment when operator<=> is implemented for each of these types. -// static_assert(!std::totally_ordered >); -// static_assert(!std::totally_ordered >); -// static_assert(!std::totally_ordered >); -// static_assert(!std::totally_ordered >); -// static_assert(!std::totally_ordered >); -// static_assert(!std::totally_ordered >); +static_assert(!std::totally_ordered >); +static_assert(!std::totally_ordered >); +static_assert(!std::totally_ordered >); +static_assert(!std::totally_ordered >); +static_assert(!std::totally_ordered >); +static_assert(!std::totally_ordered >); } // namespace standard_types namespace types_fit_for_purpose { diff --git a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp index 54861c1c4248..5f71a3911539 100644 --- a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp +++ b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp @@ -1034,11 +1034,8 @@ static_assert( static_assert(!check_totally_ordered_with, int>()); struct A {}; -// FIXME(cjdb): uncomment when operator<=> is implemented for each of these types. -// static_assert(!check_totally_ordered_with >, -// std::optional > >()); -// static_assert(!check_totally_ordered_with >, -// std::vector >()); +static_assert(!check_totally_ordered_with >, std::optional > >()); +static_assert(!check_totally_ordered_with >, std::vector >()); struct B {}; static_assert(!check_totally_ordered_with, std::vector >()); static_assert( diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp index 2dc36938b41e..67ba06b83529 100644 --- a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp @@ -162,4 +162,10 @@ void test() { } } -int main(int, char**) { return 0; } +int main(int, char**) { + test>(); + test>(); + test>(); + test>(); + return 0; +} diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h index 68dd591cb575..15fc5b69b520 100644 --- a/libcxx/test/support/test_macros.h +++ b/libcxx/test/support/test_macros.h @@ -11,7 +11,7 @@ #define SUPPORT_TEST_MACROS_HPP #ifdef __has_include -# if __has_include("") +# if __has_include() # include # else # include -- GitLab From b6ea134e4162e61c6b448ff48fd1deaa0d523166 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sun, 2 Jun 2024 10:18:14 -0400 Subject: [PATCH 031/678] Fix pagination issue in libc++ buildbot restarter --- .github/workflows/restart-preempted-libcxx-jobs.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/restart-preempted-libcxx-jobs.yaml b/.github/workflows/restart-preempted-libcxx-jobs.yaml index 4e96e1048861..f8faaf25045b 100644 --- a/.github/workflows/restart-preempted-libcxx-jobs.yaml +++ b/.github/workflows/restart-preempted-libcxx-jobs.yaml @@ -63,7 +63,8 @@ jobs: const check_suites = await github.rest.checks.listForSuite({ owner: context.repo.owner, repo: context.repo.repo, - check_suite_id: context.payload.workflow_run.check_suite_id + check_suite_id: context.payload.workflow_run.check_suite_id, + per_page: 100 // FIXME: We don't have 100 check runs yet, but we should handle this better. }) check_run_ids = []; -- GitLab From 197c3a3efc703711ac8f14bc4f1765eaadb8e5bc Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sun, 2 Jun 2024 07:45:50 -0700 Subject: [PATCH 032/678] Use llvm::less_first (NFC) (#94136) --- clang/lib/Serialization/ASTWriter.cpp | 4 +--- .../DependencyScanning/DependencyScanningWorker.cpp | 4 +--- llvm/lib/MC/MCPseudoProbe.cpp | 10 ++-------- llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h | 5 +---- .../SparseTensor/Transforms/SparseReinterpretMap.cpp | 4 +--- .../SparseTensor/Transforms/Utils/LoopEmitter.cpp | 3 +-- 6 files changed, 7 insertions(+), 23 deletions(-) diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e830c4026ea7..eb41a205bc82 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3205,9 +3205,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, } // Sort by diag::kind for deterministic output. - llvm::sort(Mappings, [](const auto &LHS, const auto &RHS) { - return LHS.first < RHS.first; - }); + llvm::sort(Mappings, llvm::less_first()); for (const auto &I : Mappings) { Record.push_back(I.first); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 0c047b6c5da2..0f82f22d8b9a 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -259,9 +259,7 @@ static void canonicalizeDefines(PreprocessorOptions &PPOpts) { ++Index; } - llvm::stable_sort(SimpleNames, [](const MacroOpt &A, const MacroOpt &B) { - return A.first < B.first; - }); + llvm::stable_sort(SimpleNames, llvm::less_first()); // Keep the last instance of each macro name by going in reverse auto NewEnd = std::unique( SimpleNames.rbegin(), SimpleNames.rend(), diff --git a/llvm/lib/MC/MCPseudoProbe.cpp b/llvm/lib/MC/MCPseudoProbe.cpp index cec50322bb9f..040f3aab8812 100644 --- a/llvm/lib/MC/MCPseudoProbe.cpp +++ b/llvm/lib/MC/MCPseudoProbe.cpp @@ -182,13 +182,10 @@ void MCPseudoProbeInlineTree::emit(MCObjectStreamer *MCOS, // Emit sorted descendant. InlineSite is unique for each pair, so there will // be no ordering of Inlinee based on MCPseudoProbeInlineTree* using InlineeType = std::pair; - auto Comparer = [](const InlineeType &A, const InlineeType &B) { - return A.first < B.first; - }; std::vector Inlinees; for (const auto &Child : Children) Inlinees.emplace_back(Child.first, Child.second.get()); - std::sort(Inlinees.begin(), Inlinees.end(), Comparer); + llvm::sort(Inlinees, llvm::less_first()); for (const auto &Inlinee : Inlinees) { // Emit probe index @@ -230,13 +227,10 @@ void MCPseudoProbeSections::emit(MCObjectStreamer *MCOS) { // Emit sorted descendant. InlineSite is unique for each pair, so there // will be no ordering of Inlinee based on MCPseudoProbeInlineTree* using InlineeType = std::pair; - auto Comparer = [](const InlineeType &A, const InlineeType &B) { - return A.first < B.first; - }; std::vector Inlinees; for (const auto &Child : Root.getChildren()) Inlinees.emplace_back(Child.first, Child.second.get()); - std::sort(Inlinees.begin(), Inlinees.end(), Comparer); + llvm::sort(Inlinees, llvm::less_first()); for (const auto &Inlinee : Inlinees) { // Emit the group guarded by a sentinel probe. diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h index 8c014832f5e4..9fe02e24c8a1 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h @@ -597,10 +597,7 @@ public: const ReservedRegSet &getWWMReservedRegs() const { return WWMReservedRegs; } ArrayRef getPrologEpilogSGPRSpills() const { - assert( - is_sorted(PrologEpilogSGPRSpills, [](const auto &LHS, const auto &RHS) { - return LHS.first < RHS.first; - })); + assert(is_sorted(PrologEpilogSGPRSpills, llvm::less_first())); return PrologEpilogSGPRSpills; } diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp index 36ecf692b02c..ce7f6b286537 100644 --- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp +++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp @@ -557,9 +557,7 @@ private: unsigned lvl = llvm::cast(expr).getPosition(); lvlSeq.push_back(std::make_pair(lvl, lvlSeq.size())); } - std::sort(lvlSeq.begin(), lvlSeq.end(), [](auto &lhs, auto &rhs) -> bool { - return lhs.first < rhs.first; - }); + llvm::sort(lvlSeq, llvm::less_first()); SmallVector perm = llvm::to_vector(llvm::make_second_range(lvlSeq)); auto dimToLvl = AffineMap::getPermutationMap(perm, linalgOp.getContext()); diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/LoopEmitter.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/LoopEmitter.cpp index 98e315865ba5..05883f1cefdf 100644 --- a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/LoopEmitter.cpp +++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/LoopEmitter.cpp @@ -184,8 +184,7 @@ void LoopEmitter::initialize(ValueRange ts, StringAttr loopTag, bool hasOutput, for (Level l = 0; l < lvlRank; l++) { std::vector> deps = dimGetter(tid, l); // Sort the loop by order. - std::sort(deps.begin(), deps.end(), - [](auto &lhs, auto &rhs) { return lhs.first < rhs.first; }); + llvm::sort(deps, llvm::less_first()); dependentLvlMap[tid][l] = std::move(deps); unsigned depends = dependentLvlMap[tid][l].size(); -- GitLab From e044283996f6f2a157c2087cffa6618f32cc5ae8 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sun, 2 Jun 2024 08:59:32 -0700 Subject: [PATCH 033/678] [memprof] Use GlobalValue::GUID instead of uint64_t (NFC) (#94086) --- llvm/include/llvm/ProfileData/MemProf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/ProfileData/MemProf.h b/llvm/include/llvm/ProfileData/MemProf.h index e8683e8ac2b9..0e00b243c157 100644 --- a/llvm/include/llvm/ProfileData/MemProf.h +++ b/llvm/include/llvm/ProfileData/MemProf.h @@ -216,7 +216,7 @@ struct Frame { IsInlineFrame = Other.IsInlineFrame; } - Frame(uint64_t Hash, uint32_t Off, uint32_t Col, bool Inline) + Frame(GlobalValue::GUID Hash, uint32_t Off, uint32_t Col, bool Inline) : Function(Hash), LineOffset(Off), Column(Col), IsInlineFrame(Inline) {} bool operator==(const Frame &Other) const { -- GitLab From df9167bfb3040bee492fd6bf64b97175f105da50 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 2 Jun 2024 09:17:46 -0700 Subject: [PATCH 034/678] [libc++] [test] Cleanup compile-only tests (#94121) I noticed that these tests had empty `main` functions. Dropping them and renaming the tests to `MEOW.compile.pass.cpp` will slightly improve test throughput. --- ...pass.cpp => member_types.compile.pass.cpp} | 2 - ...s.cpp => totally_ordered.compile.pass.cpp} | 22 +- .../totally_ordered_with.compile.pass.cpp | 681 ++++++++++ .../totally_ordered_with.pass.cpp | 1138 ----------------- ...ss.cpp => floating_point.compile.pass.cpp} | 4 +- ...ral.pass.cpp => integral.compile.pass.cpp} | 4 +- ...s.cpp => signed_integral.compile.pass.cpp} | 16 +- ...cpp => unsigned_integral.compile.pass.cpp} | 22 +- ...ss.cpp => gcc_workaround.compile.pass.cpp} | 6 +- ...cpp => default_recursive.compile.pass.cpp} | 17 +- ...cpp => default_recursive.compile.pass.cpp} | 17 +- ...ss.cpp => gcc_workaround.compile.pass.cpp} | 2 - ...pass.cpp => iter_value_t.compile.pass.cpp} | 6 +- ...pe.pass.cpp => user_type.compile.pass.cpp} | 2 - .../nothing_to_do.compile.pass.cpp} | 2 - .../nothing_to_do.compile.pass.cpp} | 2 - ...ass.cpp => nothing_to_do.compile.pass.cpp} | 2 - .../nothing_to_do.compile.pass.cpp} | 2 - 18 files changed, 721 insertions(+), 1226 deletions(-) rename libcxx/test/std/atomics/atomics.ref/{member_types.pass.cpp => member_types.compile.pass.cpp} (99%) rename libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/{totally_ordered.pass.cpp => totally_ordered.compile.pass.cpp} (91%) create mode 100644 libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.compile.pass.cpp delete mode 100644 libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp rename libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/{floating_point.pass.cpp => floating_point.compile.pass.cpp} (97%) rename libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/{integral.pass.cpp => integral.compile.pass.cpp} (97%) rename libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/{signed_integral.pass.cpp => signed_integral.compile.pass.cpp} (87%) rename libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/{unsigned_integral.pass.cpp => unsigned_integral.compile.pass.cpp} (82%) rename libcxx/test/std/containers/associative/map/{gcc_workaround.pass.cpp => gcc_workaround.compile.pass.cpp} (88%) rename libcxx/test/std/containers/associative/map/map.cons/{default_recursive.pass.cpp => default_recursive.compile.pass.cpp} (60%) rename libcxx/test/std/containers/associative/multimap/multimap.cons/{default_recursive.pass.cpp => default_recursive.compile.pass.cpp} (59%) rename libcxx/test/std/containers/associative/set/{gcc_workaround.pass.cpp => gcc_workaround.compile.pass.cpp} (93%) rename libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/{iter_value_t.pass.cpp => iter_value_t.compile.pass.cpp} (96%) rename libcxx/test/std/numerics/numbers/{user_type.pass.cpp => user_type.compile.pass.cpp} (96%) rename libcxx/test/std/strings/{strings.general/nothing_to_do.pass.cpp => char.traits/char.traits.require/nothing_to_do.compile.pass.cpp} (90%) rename libcxx/test/std/strings/char.traits/{char.traits.require/nothing_to_do.pass.cpp => char.traits.typedefs/nothing_to_do.compile.pass.cpp} (90%) rename libcxx/test/std/strings/string.view/string.view.synop/{nothing_to_do.pass.cpp => nothing_to_do.compile.pass.cpp} (91%) rename libcxx/test/std/strings/{char.traits/char.traits.typedefs/nothing_to_do.pass.cpp => strings.general/nothing_to_do.compile.pass.cpp} (90%) diff --git a/libcxx/test/std/atomics/atomics.ref/member_types.pass.cpp b/libcxx/test/std/atomics/atomics.ref/member_types.compile.pass.cpp similarity index 99% rename from libcxx/test/std/atomics/atomics.ref/member_types.pass.cpp rename to libcxx/test/std/atomics/atomics.ref/member_types.compile.pass.cpp index d4e2f0126d62..b085e209492f 100644 --- a/libcxx/test/std/atomics/atomics.ref/member_types.pass.cpp +++ b/libcxx/test/std/atomics/atomics.ref/member_types.compile.pass.cpp @@ -128,5 +128,3 @@ void testall() { test(); // + TODO extended floating-point types } - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.compile.pass.cpp similarity index 91% rename from libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp rename to libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.compile.pass.cpp index d0f90337ec48..d95de10f35cd 100644 --- a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp +++ b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.compile.pass.cpp @@ -74,25 +74,25 @@ static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); -static_assert(!std::totally_ordered < int (S::*)() && noexcept >); +static_assert(!std::totally_ordered < int(S::*)() && noexcept >); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); -static_assert(!std::totally_ordered < int (S::*)() const&& noexcept >); +static_assert(!std::totally_ordered < int(S::*)() const&& noexcept >); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); -static_assert(!std::totally_ordered < int (S::*)() volatile&& noexcept >); +static_assert(!std::totally_ordered < int(S::*)() volatile && noexcept >); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); -static_assert(!std::totally_ordered < int (S::*)() const volatile&& noexcept >); +static_assert(!std::totally_ordered < int(S::*)() const volatile&& noexcept >); static_assert(!std::totally_ordered); } // namespace fundamentals @@ -146,14 +146,10 @@ static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); -static_assert( - !std::totally_ordered); -static_assert( - !std::totally_ordered); -static_assert( - !std::totally_ordered); -static_assert( - !std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); +static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); static_assert(!std::totally_ordered); @@ -168,5 +164,3 @@ static_assert(std::totally_ordered); static_assert(std::totally_ordered); static_assert(std::totally_ordered); } // namespace types_fit_for_purpose - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.compile.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.compile.pass.cpp new file mode 100644 index 000000000000..0d7bd288c0a1 --- /dev/null +++ b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.compile.pass.cpp @@ -0,0 +1,681 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// template +// concept totally_ordered_with; + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "compare_types.h" +#include "test_macros.h" + +template +constexpr bool check_totally_ordered_with() noexcept { + constexpr bool result = std::totally_ordered_with; + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + static_assert(std::totally_ordered_with == result); + return result; +} + +namespace fundamentals { +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); + +struct S {}; +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int, int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int*, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int*, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int*, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int*, int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int[5], int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int[5], int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int[5], int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int[5], int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int[5], int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (*)(), int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (*)(), int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (*)(), int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (*)(), int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (*)(), int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (*)(), int (S::*)() const volatile&& noexcept > ()); + +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (&)(), int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (&)(), int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (&)(), int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (&)(), int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (&)(), int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int (&)(), int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)(), int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)(), int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)(), int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)(), int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)(), int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)(), int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)() noexcept, int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)() noexcept, int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() noexcept, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() noexcept, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() noexcept, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() noexcept, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)() const, int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)() const, int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const noexcept, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const noexcept, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const noexcept, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const noexcept, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)() volatile, int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)() volatile, int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile noexcept, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile noexcept, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile noexcept, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile noexcept, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile, int (S::*)() const volatile&& noexcept > ()); + +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile noexcept, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile noexcept, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile noexcept, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)() &, int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() &, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() &, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() &, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() &, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() & noexcept, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() & noexcept, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() & noexcept, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() & noexcept, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)() const&, int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const&, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const&, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const&, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const&, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const& noexcept, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const& noexcept, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const& noexcept, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const& noexcept, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile&, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile&, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile&, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile&, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile & noexcept, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile & noexcept, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile & noexcept, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile & noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile&, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile&, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile&, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile&, int (S::*)() const volatile&& noexcept > ()); + +static_assert( + !check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< int (S::*)() const volatile & noexcept, int (S::*)() &&>()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile& noexcept, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with< int (S::*)() const volatile & noexcept, int (S::*)() const&&>()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile& noexcept, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile& noexcept, + int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() &&, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() &&, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() &&, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() &&, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with < int(S::*)() && noexcept, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with < int(S::*)() && noexcept, int (S::*)() const&& > ()); +static_assert(!check_totally_ordered_with < int(S::*)() && noexcept, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with < int(S::*)() && noexcept, int (S::*)() volatile&& > ()); +static_assert(!check_totally_ordered_with < int(S::*)() && noexcept, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with < int(S::*)() && noexcept, int (S::*)() const volatile&& > ()); +static_assert(!check_totally_ordered_with < int(S::*)() && noexcept, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const&&, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const&&, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const&&, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with < int(S::*)() const&& noexcept, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with < int(S::*)() const&& noexcept, int (S::*)() volatile&& > ()); +static_assert(!check_totally_ordered_with < int(S::*)() const&& noexcept, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with < int(S::*)() const&& noexcept, int (S::*)() const volatile&& > ()); +static_assert(!check_totally_ordered_with < int(S::*)() const&& noexcept, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile&&, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile&&, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with < int(S::*)() volatile && noexcept, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile && noexcept, int (S::*)() const volatile&& > ()); +static_assert(!check_totally_ordered_with < int(S::*)() volatile && noexcept, + int (S::*)() const volatile&& noexcept > ()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile&&, int (S::*)() const volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with < int(S::*)() const volatile&& noexcept, + int (S::*)() const volatile&& noexcept > ()); + +#if !defined(TEST_COMPILER_GCC) +static_assert(!check_totally_ordered_with()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +#endif + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< std::nullptr_t, int (S::*)() const volatile noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with< std::nullptr_t, int (S::*)() const volatile & noexcept>()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < std::nullptr_t, int (S::*)() && noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < std::nullptr_t, int (S::*)() const&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < std::nullptr_t, int (S::*)() volatile&& noexcept > ()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with < std::nullptr_t, int (S::*)() const volatile&& noexcept > ()); + +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with < void, int (S::*)() && noexcept >); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with < void, int (S::*)() const&& noexcept >); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with < void, int (S::*)() volatile&& noexcept >); +static_assert(!std::equality_comparable_with); +static_assert(!std::equality_comparable_with < void, int (S::*)() const volatile&& noexcept >); +} // namespace fundamentals + +namespace standard_types { +static_assert(check_totally_ordered_with, std::array >()); +static_assert(!check_totally_ordered_with, std::array >()); +static_assert(check_totally_ordered_with, std::deque >()); +static_assert(!check_totally_ordered_with, std::vector >()); +static_assert(check_totally_ordered_with, std::forward_list >()); +static_assert(!check_totally_ordered_with, std::vector >()); +static_assert(check_totally_ordered_with, std::list >()); +static_assert(!check_totally_ordered_with, std::vector >()); + +static_assert(check_totally_ordered_with, std::map >()); +static_assert(!check_totally_ordered_with, std::vector >()); +static_assert(check_totally_ordered_with >, std::optional > >()); +static_assert(check_totally_ordered_with >, std::vector >()); +static_assert(check_totally_ordered_with, std::vector >()); +static_assert(!check_totally_ordered_with, int>()); + +struct A {}; +static_assert(!check_totally_ordered_with >, std::optional > >()); +static_assert(!check_totally_ordered_with >, std::vector >()); +struct B {}; +static_assert(!check_totally_ordered_with, std::vector >()); +static_assert(!check_totally_ordered_with, std::optional >()); +} // namespace standard_types + +namespace types_fit_for_purpose { +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); + +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); + +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); + +static_assert(!check_totally_ordered_with()); +static_assert(std::common_reference_with && + !check_totally_ordered_with()); + +static_assert(!check_totally_ordered_with()); +static_assert(std::common_reference_with && + !check_totally_ordered_with()); + +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); + +static_assert(!check_totally_ordered_with()); +static_assert(!check_totally_ordered_with()); +static_assert(std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); +static_assert(check_totally_ordered_with()); + +static_assert(std::totally_ordered && + std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(std::totally_ordered && + std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(std::totally_ordered && + std::equality_comparable_with && + !check_totally_ordered_with()); +static_assert(std::totally_ordered && + std::equality_comparable_with && + !check_totally_ordered_with()); +} // namespace types_fit_for_purpose diff --git a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp deleted file mode 100644 index 5f71a3911539..000000000000 --- a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp +++ /dev/null @@ -1,1138 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17 - -// template -// concept totally_ordered_with; - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "compare_types.h" -#include "test_macros.h" - -template -constexpr bool check_totally_ordered_with() noexcept { - constexpr bool result = std::totally_ordered_with; - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - static_assert(std::totally_ordered_with == result); - return result; -} - -namespace fundamentals { -static_assert(check_totally_ordered_with()); -static_assert(check_totally_ordered_with()); -static_assert(check_totally_ordered_with()); -static_assert(check_totally_ordered_with()); -static_assert(check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); - -struct S {}; -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int, int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int, - int (S::*)() volatile&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(check_totally_ordered_with()); -static_assert(check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int*, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int*, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int*, - int (S::*)() volatile&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int*, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int[5], int (S::*)() const volatile noexcept>()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int[5], - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int[5], - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int[5], - int (S::*)() volatile&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int[5], - int (S::*)() const volatile&& noexcept > ()); - -static_assert(check_totally_ordered_with()); -static_assert(check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (*)(), int (S::*)() const volatile noexcept>()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (*)(), int (S::*)() const volatile & noexcept>()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (*)(), - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (*)(), - int (S::*)() const&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (*)(), - int (S::*)() volatile&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (*)(), - int (S::*)() const volatile&& noexcept > ()); - -static_assert(check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (&)(), int (S::*)() const volatile noexcept>()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (&)(), int (S::*)() const volatile & noexcept>()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (&)(), - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (&)(), - int (S::*)() const&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (&)(), - int (S::*)() volatile&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (&)(), - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)(), int (S::*)() const volatile noexcept>()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)(), int (S::*)() const volatile & noexcept>()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)(), - int (S::*)() && noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)(), - int (S::*)() const&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)(), - int (S::*)() volatile&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)(), - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)() noexcept, int (S::*)() const volatile noexcept>()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)() noexcept, int (S::*)() const volatile & noexcept>()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() noexcept, - int (S::*)() && noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() noexcept, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)() const, int (S::*)() const volatile noexcept>()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)() const, int (S::*)() const volatile & noexcept>()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const, - int (S::*)() && noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const, - int (S::*)() const&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const noexcept, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const noexcept, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)() volatile, int (S::*)() const volatile noexcept>()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)() volatile, int (S::*)() const volatile & noexcept>()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile, - int (S::*)() && noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const volatile, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const volatile, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const volatile, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const volatile, - int (S::*)() const volatile&& noexcept > ()); - -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() - const volatile noexcept, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() - const volatile noexcept, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() - const volatile noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() - const volatile noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)() &, int (S::*)() const volatile & noexcept>()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() &, - int (S::*)() && noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() &, - int (S::*)() const&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() &, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() &, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() & noexcept, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() & noexcept, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() & noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() & noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)() const&, int (S::*)() const volatile & noexcept>()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const&, - int (S::*)() && noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const&, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const&, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const&, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile&, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile&, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile&, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile&, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const volatile&, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const volatile&, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const volatile&, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const volatile&, - int (S::*)() const volatile&& noexcept > ()); - -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - int (S::*)() const volatile & noexcept, int (S::*)() &&>()); -static_assert(!check_totally_ordered_with < int (S::*)() - const volatile& noexcept, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with< - int (S::*)() const volatile & noexcept, int (S::*)() const&&>()); -static_assert(!check_totally_ordered_with < int (S::*)() - const volatile& noexcept, - int (S::*)() const&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() - const volatile& noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() - const volatile& noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() &&, - int (S::*)() && noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() &&, - int (S::*)() const&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() &&, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() &&, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, - int (S::*)() && noexcept > ()); -static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, - int (S::*)() const&& > ()); -static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, - int (S::*)() volatile&& > ()); -static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, - int (S::*)() const volatile&& > ()); -static_assert(!check_totally_ordered_with < int (S::*)() && noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const&&, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const&&, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const&&, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept, - int (S::*)() const&& noexcept > ()); -static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept, - int (S::*)() volatile&& > ()); -static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept, - int (S::*)() const volatile&& > ()); -static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile&&, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile&&, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with < int (S::*)() volatile&& noexcept, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile&& noexcept, - int (S::*)() const volatile&& > ()); -static_assert(!check_totally_ordered_with < int (S::*)() volatile&& noexcept, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < int (S::*)() const volatile&&, - int (S::*)() const volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with < int (S::*)() - const volatile&& noexcept, - int (S::*)() const volatile&& noexcept > ()); - -#if !defined(TEST_COMPILER_GCC) -static_assert(!check_totally_ordered_with()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -#endif - -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - std::nullptr_t, int (S::*)() const volatile noexcept>()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with< - std::nullptr_t, int (S::*)() const volatile & noexcept>()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < std::nullptr_t, - int (S::*)() && noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < std::nullptr_t, - int (S::*)() const&& noexcept > ()); -static_assert( - !check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < std::nullptr_t, - int (S::*)() volatile&& noexcept > ()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with < std::nullptr_t, - int (S::*)() const volatile&& noexcept > ()); - -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert( - !std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert( - !std::equality_comparable_with); -static_assert( - !std::equality_comparable_with); -static_assert( - !std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert( - !std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert( - !std::equality_comparable_with); -static_assert( - !std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with < void, - int (S::*)() && noexcept >); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with < void, - int (S::*)() const&& noexcept >); -static_assert(!std::equality_comparable_with); -static_assert(!std::equality_comparable_with < void, - int (S::*)() volatile&& noexcept >); -static_assert( - !std::equality_comparable_with); -static_assert(!std::equality_comparable_with < void, - int (S::*)() const volatile&& noexcept >); -} // namespace fundamentals - -namespace standard_types { -static_assert( - check_totally_ordered_with, std::array >()); -static_assert(!check_totally_ordered_with, - std::array >()); -static_assert(check_totally_ordered_with, std::deque >()); -static_assert( - !check_totally_ordered_with, std::vector >()); -static_assert(check_totally_ordered_with, - std::forward_list >()); -static_assert( - !check_totally_ordered_with, std::vector >()); -static_assert(check_totally_ordered_with, std::list >()); -static_assert(!check_totally_ordered_with, std::vector >()); - -static_assert( - check_totally_ordered_with, std::map >()); -static_assert( - !check_totally_ordered_with, std::vector >()); -static_assert(check_totally_ordered_with >, - std::optional > >()); -static_assert(check_totally_ordered_with >, - std::vector >()); -static_assert( - check_totally_ordered_with, std::vector >()); -static_assert(!check_totally_ordered_with, int>()); - -struct A {}; -static_assert(!check_totally_ordered_with >, std::optional > >()); -static_assert(!check_totally_ordered_with >, std::vector >()); -struct B {}; -static_assert(!check_totally_ordered_with, std::vector >()); -static_assert( - !check_totally_ordered_with, std::optional >()); -} // namespace standard_types - -namespace types_fit_for_purpose { -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); - -static_assert(check_totally_ordered_with()); -static_assert(check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); - -static_assert( - check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert( - check_totally_ordered_with()); - -static_assert(!check_totally_ordered_with()); -static_assert( - std::common_reference_with && - !check_totally_ordered_with()); - -static_assert(!check_totally_ordered_with()); -static_assert( - std::common_reference_with && - !check_totally_ordered_with()); - -static_assert( - check_totally_ordered_with()); -static_assert(check_totally_ordered_with()); -static_assert( - check_totally_ordered_with()); - -static_assert(!check_totally_ordered_with()); -static_assert(!check_totally_ordered_with()); -static_assert(std::equality_comparable_with && - !check_totally_ordered_with()); -static_assert(std::equality_comparable_with && - !check_totally_ordered_with()); -static_assert(std::equality_comparable_with && - !check_totally_ordered_with()); -static_assert(std::equality_comparable_with && - !check_totally_ordered_with()); -static_assert(check_totally_ordered_with()); -static_assert( - check_totally_ordered_with()); - -static_assert( - std::totally_ordered&& - std::equality_comparable_with && - !check_totally_ordered_with()); -static_assert( - std::totally_ordered&& - std::equality_comparable_with && - !check_totally_ordered_with()); -static_assert( - std::totally_ordered&& - std::equality_comparable_with && - !check_totally_ordered_with()); -static_assert( - std::totally_ordered&& - std::equality_comparable_with && - !check_totally_ordered_with()); -} // namespace types_fit_for_purpose - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.compile.pass.cpp similarity index 97% rename from libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.pass.cpp rename to libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.compile.pass.cpp index 20efed42088c..118b595e7958 100644 --- a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.pass.cpp +++ b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.compile.pass.cpp @@ -40,7 +40,7 @@ constexpr bool CheckFloatingPointQualifiers() { static_assert(!std::floating_point); static_assert(!std::floating_point); - static_assert(!std::floating_point); + static_assert(!std::floating_point); return result; } @@ -74,5 +74,3 @@ static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); static_assert(!CheckFloatingPointQualifiers()); - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/integral.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/integral.compile.pass.cpp similarity index 97% rename from libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/integral.pass.cpp rename to libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/integral.compile.pass.cpp index f40aed1909d3..1891b3939d48 100644 --- a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/integral.pass.cpp +++ b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/integral.compile.pass.cpp @@ -41,7 +41,7 @@ constexpr bool CheckIntegralQualifiers() { static_assert(!std::integral); static_assert(!std::integral); - static_assert(!std::integral); + static_assert(!std::integral); return result; } @@ -88,5 +88,3 @@ static_assert(!CheckIntegralQualifiers()); static_assert(CheckSubsumption(0)); static_assert(CheckSubsumption(0U)); - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.compile.pass.cpp similarity index 87% rename from libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.pass.cpp rename to libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.compile.pass.cpp index c1f4717a374d..6cbeed283c28 100644 --- a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.pass.cpp +++ b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.compile.pass.cpp @@ -41,7 +41,7 @@ constexpr bool CheckSignedIntegralQualifiers() { static_assert(!std::signed_integral); static_assert(!std::signed_integral); - static_assert(!std::signed_integral); + static_assert(!std::signed_integral); return result; } @@ -54,16 +54,12 @@ static_assert(CheckSignedIntegralQualifiers()); static_assert(CheckSignedIntegralQualifiers()); // bool and character *may* be signed -static_assert(CheckSignedIntegralQualifiers() == - std::is_signed_v); +static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); -static_assert(CheckSignedIntegralQualifiers() == - std::is_signed_v); -static_assert(CheckSignedIntegralQualifiers() == - std::is_signed_v); -static_assert(CheckSignedIntegralQualifiers() == - std::is_signed_v); +static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); +static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); +static_assert(CheckSignedIntegralQualifiers() == std::is_signed_v); // integers that aren't signed integrals static_assert(!CheckSignedIntegralQualifiers()); @@ -92,5 +88,3 @@ static_assert(!CheckSignedIntegralQualifiers()); static_assert(CheckSubsumption(0)); static_assert(CheckSubsumption(0U)); - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.compile.pass.cpp similarity index 82% rename from libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.pass.cpp rename to libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.compile.pass.cpp index b89941627f01..aa986ddd2bb8 100644 --- a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.pass.cpp +++ b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.compile.pass.cpp @@ -41,7 +41,7 @@ constexpr bool CheckUnsignedIntegralQualifiers() { static_assert(!std::unsigned_integral); static_assert(!std::unsigned_integral); - static_assert(!std::unsigned_integral); + static_assert(!std::unsigned_integral); return result; } @@ -54,18 +54,12 @@ static_assert(CheckUnsignedIntegralQualifiers()); static_assert(CheckUnsignedIntegralQualifiers()); // Whether bool and character types are signed or unsigned is impl-defined -static_assert(CheckUnsignedIntegralQualifiers() == - !std::is_signed_v); -static_assert(CheckUnsignedIntegralQualifiers() == - !std::is_signed_v); -static_assert(CheckUnsignedIntegralQualifiers() == - !std::is_signed_v); -static_assert(CheckUnsignedIntegralQualifiers() == - !std::is_signed_v); -static_assert(CheckUnsignedIntegralQualifiers() == - !std::is_signed_v); -static_assert(CheckUnsignedIntegralQualifiers() == - !std::is_signed_v); +static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); +static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); +static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); +static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); +static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); +static_assert(CheckUnsignedIntegralQualifiers() == !std::is_signed_v); // extended integers #ifndef TEST_HAS_NO_INT128 @@ -93,5 +87,3 @@ static_assert(!CheckUnsignedIntegralQualifiers()); static_assert(CheckSubsumption(0)); static_assert(CheckSubsumption(0U)); - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/containers/associative/map/gcc_workaround.pass.cpp b/libcxx/test/std/containers/associative/map/gcc_workaround.compile.pass.cpp similarity index 88% rename from libcxx/test/std/containers/associative/map/gcc_workaround.pass.cpp rename to libcxx/test/std/containers/associative/map/gcc_workaround.compile.pass.cpp index e69a24110b66..66672b6f740e 100644 --- a/libcxx/test/std/containers/associative/map/gcc_workaround.pass.cpp +++ b/libcxx/test/std/containers/associative/map/gcc_workaround.compile.pass.cpp @@ -9,11 +9,9 @@ // Tests workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37804 #include -std::map::iterator it; +std::map::iterator it; #include #include "test_macros.h" -using std::set; using std::multiset; - -int main(int, char**) { return 0; } +using std::set; diff --git a/libcxx/test/std/containers/associative/map/map.cons/default_recursive.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/default_recursive.compile.pass.cpp similarity index 60% rename from libcxx/test/std/containers/associative/map/map.cons/default_recursive.pass.cpp rename to libcxx/test/std/containers/associative/map/map.cons/default_recursive.compile.pass.cpp index 8b95aefc5514..f7204c56e4ae 100644 --- a/libcxx/test/std/containers/associative/map/map.cons/default_recursive.pass.cpp +++ b/libcxx/test/std/containers/associative/map/map.cons/default_recursive.compile.pass.cpp @@ -16,16 +16,13 @@ #include "test_macros.h" -struct X -{ - std::map m; - std::map::iterator i; - std::map::const_iterator ci; +struct X { + std::map m; + std::map::iterator i; + std::map::const_iterator ci; #if TEST_STD_VER <= 17 - // These reverse_iterator specializations require X to be complete in C++20. - std::map::reverse_iterator ri; - std::map::const_reverse_iterator cri; + // These reverse_iterator specializations require X to be complete in C++20. + std::map::reverse_iterator ri; + std::map::const_reverse_iterator cri; #endif // TEST_STD_VER <= 17 }; - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/default_recursive.compile.pass.cpp similarity index 59% rename from libcxx/test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp rename to libcxx/test/std/containers/associative/multimap/multimap.cons/default_recursive.compile.pass.cpp index 94003f350eba..74ed99922d4d 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/default_recursive.compile.pass.cpp @@ -16,16 +16,13 @@ #include "test_macros.h" -struct X -{ - std::multimap m; - std::multimap::iterator i; - std::multimap::const_iterator ci; +struct X { + std::multimap m; + std::multimap::iterator i; + std::multimap::const_iterator ci; #if TEST_STD_VER <= 17 - // These reverse_iterator specializations require X to be complete in C++20. - std::multimap::reverse_iterator ri; - std::multimap::const_reverse_iterator cri; + // These reverse_iterator specializations require X to be complete in C++20. + std::multimap::reverse_iterator ri; + std::multimap::const_reverse_iterator cri; #endif // TEST_STD_VER <= 17 }; - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/containers/associative/set/gcc_workaround.pass.cpp b/libcxx/test/std/containers/associative/set/gcc_workaround.compile.pass.cpp similarity index 93% rename from libcxx/test/std/containers/associative/set/gcc_workaround.pass.cpp rename to libcxx/test/std/containers/associative/set/gcc_workaround.compile.pass.cpp index 0eb500210ec1..4318077a5dca 100644 --- a/libcxx/test/std/containers/associative/set/gcc_workaround.pass.cpp +++ b/libcxx/test/std/containers/associative/set/gcc_workaround.compile.pass.cpp @@ -15,5 +15,3 @@ std::set s; #include "test_macros.h" using std::map; using std::multimap; - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/iter_value_t.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/iter_value_t.compile.pass.cpp similarity index 96% rename from libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/iter_value_t.pass.cpp rename to libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/iter_value_t.compile.pass.cpp index 2d465203e189..8739a0d89ba1 100644 --- a/libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/iter_value_t.pass.cpp +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/iter_value_t.compile.pass.cpp @@ -40,7 +40,7 @@ static_assert(check_iter_value_t::iterator, int>()); static_assert(check_iter_value_t, int>()); struct both_members { - using value_type = double; + using value_type = double; using element_type = double; }; static_assert(check_iter_value_t()); @@ -65,9 +65,7 @@ struct S {}; static_assert(check_no_iter_value_t()); struct different_value_element_members { - using value_type = int; + using value_type = int; using element_type = long; }; static_assert(check_no_iter_value_t()); - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/numerics/numbers/user_type.pass.cpp b/libcxx/test/std/numerics/numbers/user_type.compile.pass.cpp similarity index 96% rename from libcxx/test/std/numerics/numbers/user_type.pass.cpp rename to libcxx/test/std/numerics/numbers/user_type.compile.pass.cpp index d4df035628f0..89347ec99232 100644 --- a/libcxx/test/std/numerics/numbers/user_type.pass.cpp +++ b/libcxx/test/std/numerics/numbers/user_type.compile.pass.cpp @@ -52,5 +52,3 @@ user std::numbers::egamma_v{}; template <> user std::numbers::phi_v{}; - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/strings/strings.general/nothing_to_do.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.require/nothing_to_do.compile.pass.cpp similarity index 90% rename from libcxx/test/std/strings/strings.general/nothing_to_do.pass.cpp rename to libcxx/test/std/strings/char.traits/char.traits.require/nothing_to_do.compile.pass.cpp index 3e0d2a6570f4..7978e80f40cb 100644 --- a/libcxx/test/std/strings/strings.general/nothing_to_do.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.require/nothing_to_do.compile.pass.cpp @@ -5,5 +5,3 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.require/nothing_to_do.pass.cpp b/libcxx/test/std/strings/char.traits/char.traits.typedefs/nothing_to_do.compile.pass.cpp similarity index 90% rename from libcxx/test/std/strings/char.traits/char.traits.require/nothing_to_do.pass.cpp rename to libcxx/test/std/strings/char.traits/char.traits.typedefs/nothing_to_do.compile.pass.cpp index 3e0d2a6570f4..7978e80f40cb 100644 --- a/libcxx/test/std/strings/char.traits/char.traits.require/nothing_to_do.pass.cpp +++ b/libcxx/test/std/strings/char.traits/char.traits.typedefs/nothing_to_do.compile.pass.cpp @@ -5,5 +5,3 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/strings/string.view/string.view.synop/nothing_to_do.pass.cpp b/libcxx/test/std/strings/string.view/string.view.synop/nothing_to_do.compile.pass.cpp similarity index 91% rename from libcxx/test/std/strings/string.view/string.view.synop/nothing_to_do.pass.cpp rename to libcxx/test/std/strings/string.view/string.view.synop/nothing_to_do.compile.pass.cpp index c2738673a436..0949a612cbf0 100644 --- a/libcxx/test/std/strings/string.view/string.view.synop/nothing_to_do.pass.cpp +++ b/libcxx/test/std/strings/string.view/string.view.synop/nothing_to_do.compile.pass.cpp @@ -7,5 +7,3 @@ //===----------------------------------------------------------------------===// #include - -int main(int, char**) { return 0; } diff --git a/libcxx/test/std/strings/char.traits/char.traits.typedefs/nothing_to_do.pass.cpp b/libcxx/test/std/strings/strings.general/nothing_to_do.compile.pass.cpp similarity index 90% rename from libcxx/test/std/strings/char.traits/char.traits.typedefs/nothing_to_do.pass.cpp rename to libcxx/test/std/strings/strings.general/nothing_to_do.compile.pass.cpp index 3e0d2a6570f4..7978e80f40cb 100644 --- a/libcxx/test/std/strings/char.traits/char.traits.typedefs/nothing_to_do.pass.cpp +++ b/libcxx/test/std/strings/strings.general/nothing_to_do.compile.pass.cpp @@ -5,5 +5,3 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// - -int main(int, char**) { return 0; } -- GitLab From c26a99384bce5719107d26f4617d6e3b1e9253ff Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Sun, 2 Jun 2024 19:23:09 +0300 Subject: [PATCH 035/678] [clang][NFC] Update CWG issues list --- clang/www/cxx_dr_status.html | 48 +++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 4c5f922e5295..744d22959db4 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -12670,7 +12670,7 @@ and POD class 2144 - drafting + tentatively ready Function/variable declaration ambiguity Not resolved @@ -17081,7 +17081,7 @@ objects 2879 - open + drafting Undesired outcomes with const_cast Not resolved @@ -17099,13 +17099,13 @@ objects 2882 - open + tentatively ready Unclear treatment of conversion to void Not resolved 2883 - open + tentatively ready Definition of "odr-usable" ignores lambda scopes Not resolved @@ -17117,25 +17117,25 @@ objects 2885 - review + tentatively ready Non-eligible trivial default constructors Not resolved 2886 - open + tentatively ready Temporaries and trivial potentially-throwing special member functions Not resolved 2887 - open + tentatively ready Missing compatibility entries for xvalues Not resolved 2888 - open + review Missing cases for reference and array types for argument-dependent lookup Not resolved @@ -17153,9 +17153,39 @@ objects 2891 - review + tentatively ready Normative status of implementation limits Not resolved + + + 2892 + tentatively ready + Unclear usual arithmetic conversions + Not resolved + + + 2893 + open + Instantiations in discarded if constexpr substatements + Not resolved + + + 2894 + open + Functional casts create prvalues of reference type + Not resolved + + + 2895 + open + Initialization should ignore the destination type's cv-qualification + Not resolved + + + 2896 + open + Template argument deduction involving exception specifications + Not resolved -- GitLab From d9293519bce5d2a6a22b73933810306317b51b3b Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sun, 2 Jun 2024 11:52:12 -0700 Subject: [PATCH 036/678] [TableGen] Use llvm::unique (NFC) (#94163) --- llvm/utils/TableGen/AsmMatcherEmitter.cpp | 4 +--- llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp | 3 +-- llvm/utils/TableGen/Common/CodeGenRegisters.cpp | 2 +- llvm/utils/TableGen/Common/CodeGenSchedule.cpp | 2 +- llvm/utils/TableGen/Common/CodeGenTarget.cpp | 6 ++---- .../GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp | 4 +--- llvm/utils/TableGen/DFAEmitter.cpp | 5 ++--- llvm/utils/TableGen/FastISelEmitter.cpp | 3 +-- llvm/utils/TableGen/GlobalISelEmitter.cpp | 5 ++--- llvm/utils/TableGen/InstrInfoEmitter.cpp | 4 +--- llvm/utils/TableGen/RegisterInfoEmitter.cpp | 9 ++++----- 11 files changed, 17 insertions(+), 30 deletions(-) diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp index 8e475f9153b0..29f15f0e5733 100644 --- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -3472,9 +3472,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { } return false; }); - FeatureBitsets.erase( - std::unique(FeatureBitsets.begin(), FeatureBitsets.end()), - FeatureBitsets.end()); + FeatureBitsets.erase(llvm::unique(FeatureBitsets), FeatureBitsets.end()); OS << "// Feature bitsets.\n" << "enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n" << " AMFBS_None,\n"; diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp index 709aa00ae8b3..a8cecca0d4a5 100644 --- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp @@ -1499,8 +1499,7 @@ void PatternToMatch::getPredicateRecords( // Sort so that different orders get canonicalized to the same string. llvm::sort(PredicateRecs, LessRecord()); // Remove duplicate predicates. - PredicateRecs.erase(std::unique(PredicateRecs.begin(), PredicateRecs.end()), - PredicateRecs.end()); + PredicateRecs.erase(llvm::unique(PredicateRecs), PredicateRecs.end()); } /// getPredicateCheck - Return a single string containing all of this diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp index 624e8d5d54ba..3c868b1e8f4f 100644 --- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp @@ -743,7 +743,7 @@ struct TupleExpander : SetTheory::Expander { static void sortAndUniqueRegisters(CodeGenRegister::Vec &M) { llvm::sort(M, deref>()); - M.erase(std::unique(M.begin(), M.end(), deref>()), M.end()); + M.erase(llvm::unique(M, deref>()), M.end()); } CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) diff --git a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp index 2ec0812320d1..152e68797b99 100644 --- a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp +++ b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp @@ -1699,7 +1699,7 @@ static void inferFromTransitions(ArrayRef LastTransitions, RecVec Preds; transform(LastTransition.PredTerm, std::back_inserter(Preds), [](const PredCheck &P) { return P.Predicate; }); - Preds.erase(std::unique(Preds.begin(), Preds.end()), Preds.end()); + Preds.erase(llvm::unique(Preds), Preds.end()); dumpTransition(SchedModels, FromSC, SCTrans, Preds); SCTrans.PredTerm = std::move(Preds); SchedModels.getSchedClass(FromClassIdx) diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.cpp b/llvm/utils/TableGen/Common/CodeGenTarget.cpp index bc3ccd888cb4..6915ecbbf368 100644 --- a/llvm/utils/TableGen/Common/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/Common/CodeGenTarget.cpp @@ -250,7 +250,7 @@ std::vector CodeGenTarget::getRegisterVTs(Record *R) const { // Remove duplicates. llvm::sort(Result); - Result.erase(std::unique(Result.begin(), Result.end()), Result.end()); + Result.erase(llvm::unique(Result), Result.end()); return Result; } @@ -260,9 +260,7 @@ void CodeGenTarget::ReadLegalValueTypes() const { // Remove duplicates. llvm::sort(LegalValueTypes); - LegalValueTypes.erase( - std::unique(LegalValueTypes.begin(), LegalValueTypes.end()), - LegalValueTypes.end()); + LegalValueTypes.erase(llvm::unique(LegalValueTypes), LegalValueTypes.end()); } CodeGenSchedModels &CodeGenTarget::getSchedModels() const { diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp index 331da97a6f7c..6edbfa350e35 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp +++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp @@ -70,9 +70,7 @@ void GlobalISelMatchTableExecutorEmitter::emitSubtargetFeatureBitsetImpl( return (A.second < B.second); }); - FeatureBitsets.erase( - std::unique(FeatureBitsets.begin(), FeatureBitsets.end()), - FeatureBitsets.end()); + FeatureBitsets.erase(llvm::unique(FeatureBitsets), FeatureBitsets.end()); OS << "// Feature bitsets.\n" << "enum {\n" << " GIFBS_Invalid,\n"; diff --git a/llvm/utils/TableGen/DFAEmitter.cpp b/llvm/utils/TableGen/DFAEmitter.cpp index 567184d3d5ee..4b9affb6e850 100644 --- a/llvm/utils/TableGen/DFAEmitter.cpp +++ b/llvm/utils/TableGen/DFAEmitter.cpp @@ -76,10 +76,9 @@ void DfaEmitter::visitDfaState(const DfaState &DS) { continue; // Sort and unique. sort(NewStates); - NewStates.erase(std::unique(NewStates.begin(), NewStates.end()), - NewStates.end()); + NewStates.erase(llvm::unique(NewStates), NewStates.end()); sort(TI); - TI.erase(std::unique(TI.begin(), TI.end()), TI.end()); + TI.erase(llvm::unique(TI), TI.end()); unsigned ToId = DfaStates.insert(NewStates); DfaTransitions.emplace(std::pair(FromId, A), std::pair(ToId, TI)); } diff --git a/llvm/utils/TableGen/FastISelEmitter.cpp b/llvm/utils/TableGen/FastISelEmitter.cpp index acfdc20316b7..8766d76683d0 100644 --- a/llvm/utils/TableGen/FastISelEmitter.cpp +++ b/llvm/utils/TableGen/FastISelEmitter.cpp @@ -821,8 +821,7 @@ void FastISelMap::printFunctionDefinitions(raw_ostream &OS) { if (MI != SignaturesWithConstantForms.end()) { // Unique any duplicates out of the list. llvm::sort(MI->second); - MI->second.erase(std::unique(MI->second.begin(), MI->second.end()), - MI->second.end()); + MI->second.erase(llvm::unique(MI->second), MI->second.end()); // Check each in order it was seen. It would be nice to have a good // relative ordering between them, but we're not going for optimality diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index ec41cd9fec07..c29cb4edec18 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -2469,9 +2469,8 @@ void GlobalISelEmitter::run(raw_ostream &OS) { // Sort and remove duplicates to get a list of unique renderer functions, in // case some were mentioned more than once. llvm::sort(CustomRendererFns); - CustomRendererFns.erase( - std::unique(CustomRendererFns.begin(), CustomRendererFns.end()), - CustomRendererFns.end()); + CustomRendererFns.erase(llvm::unique(CustomRendererFns), + CustomRendererFns.end()); // Create a table containing the LLT objects needed by the matcher and an enum // for the matcher to reference them with. diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp index b3a05e081f63..ac85de189e11 100644 --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -776,9 +776,7 @@ void InstrInfoEmitter::emitFeatureVerifier(raw_ostream &OS, } return false; }); - FeatureBitsets.erase( - std::unique(FeatureBitsets.begin(), FeatureBitsets.end()), - FeatureBitsets.end()); + FeatureBitsets.erase(llvm::unique(FeatureBitsets), FeatureBitsets.end()); OS << "inline FeatureBitset computeRequiredFeatures(unsigned Opcode) {\n" << " enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n" << " CEFBS_None,\n"; diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp index 980d9a39636e..2233072718bb 100644 --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -370,11 +370,10 @@ static void finalizeDwarfRegNumsKeys(DwarfRegNumsVecTy &DwarfRegNums) { "specified multiple times"); LastSeenReg = Reg; } - auto Last = std::unique( - DwarfRegNums.begin(), DwarfRegNums.end(), - [](const DwarfRegNumsMapPair &A, const DwarfRegNumsMapPair &B) { - return A.first->getName() == B.first->getName(); - }); + auto Last = llvm::unique(DwarfRegNums, [](const DwarfRegNumsMapPair &A, + const DwarfRegNumsMapPair &B) { + return A.first->getName() == B.first->getName(); + }); DwarfRegNums.erase(Last, DwarfRegNums.end()); } -- GitLab From 5367b2c862a7bfe138ee17994edfdb7938437064 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Sun, 2 Jun 2024 21:05:53 +0200 Subject: [PATCH 037/678] [libc++] Don't give functions C linkage (#94102) There is no reason to give any of the functions C linkage. This makes all of the libc++ functions have C++ linkage, removing the need for `_LIBCPP_HIDE_FROM_ABI_C`. --- libcxx/include/__config | 4 - .../__locale_dir/locale_base_api/android.h | 14 +--- .../__locale_dir/locale_base_api/ibm.h | 10 +-- .../__locale_dir/locale_base_api/musl.h | 19 ++--- .../__locale_dir/locale_base_api/openbsd.h | 12 +-- .../__support/xlocale/__nop_locale_mgmt.h | 16 +--- .../__support/xlocale/__posix_l_fallback.h | 74 +++++++++---------- .../__support/xlocale/__strtonum_fallback.h | 25 ++----- 8 files changed, 57 insertions(+), 117 deletions(-) diff --git a/libcxx/include/__config b/libcxx/include/__config index 4f4863619d6b..aac8c70c74a3 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -572,10 +572,6 @@ typedef __char32_t char32_t; # endif # define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION -// This macro provides a HIDE_FROM_ABI equivalent that can be applied to extern -// "C" function, as those lack mangling. -# define _LIBCPP_HIDE_FROM_ABI_C _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION - # ifdef _LIBCPP_BUILDING_LIBRARY # if _LIBCPP_ABI_VERSION > 1 # define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI diff --git a/libcxx/include/__locale_dir/locale_base_api/android.h b/libcxx/include/__locale_dir/locale_base_api/android.h index c2dea1e731cf..a33d2539f065 100644 --- a/libcxx/include/__locale_dir/locale_base_api/android.h +++ b/libcxx/include/__locale_dir/locale_base_api/android.h @@ -42,26 +42,18 @@ extern "C" { # include <__support/xlocale/__strtonum_fallback.h> # elif __ANDROID_API__ < 26 -# if defined(__cplusplus) -extern "C" { -# endif - -inline _LIBCPP_HIDE_FROM_ABI_C float strtof_l(const char* __nptr, char** __endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI float strtof_l(const char* __nptr, char** __endptr, locale_t) { return ::strtof(__nptr, __endptr); } -inline _LIBCPP_HIDE_FROM_ABI_C double strtod_l(const char* __nptr, char** __endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI double strtod_l(const char* __nptr, char** __endptr, locale_t) { return ::strtod(__nptr, __endptr); } -inline _LIBCPP_HIDE_FROM_ABI_C long strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) { return ::strtol(__nptr, __endptr, __base); } -# if defined(__cplusplus) -} -# endif - # endif // __ANDROID_API__ < 26 # endif // __NDK_MAJOR__ <= 16 diff --git a/libcxx/include/__locale_dir/locale_base_api/ibm.h b/libcxx/include/__locale_dir/locale_base_api/ibm.h index c5d7f34186b1..5e89a1dc1e8a 100644 --- a/libcxx/include/__locale_dir/locale_base_api/ibm.h +++ b/libcxx/include/__locale_dir/locale_base_api/ibm.h @@ -20,10 +20,6 @@ #include "cstdlib" -#ifdef __cplusplus -extern "C" { -#endif - #if defined(__MVS__) # include // POSIX routines @@ -93,7 +89,8 @@ inline _LIBCPP_HIDE_FROM_ABI unsigned long strtoul_l(const char* __nptr, char** return ::strtoul(__nptr, __endptr, __base); } -inline _LIBCPP_HIDE_FROM_ABI int vasprintf(char** strp, const char* fmt, va_list ap) { +inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char* fmt, va_list ap) { const size_t buff_size = 256; if ((*strp = (char*)malloc(buff_size)) == NULL) { return -1; @@ -118,7 +115,4 @@ inline _LIBCPP_HIDE_FROM_ABI int vasprintf(char** strp, const char* fmt, va_list return str_size; } -#ifdef __cplusplus -} -#endif #endif // _LIBCPP___LOCALE_LOCALE_BASE_API_IBM_H diff --git a/libcxx/include/__locale_dir/locale_base_api/musl.h b/libcxx/include/__locale_dir/locale_base_api/musl.h index e4121ec1a9f4..b689200baee7 100644 --- a/libcxx/include/__locale_dir/locale_base_api/musl.h +++ b/libcxx/include/__locale_dir/locale_base_api/musl.h @@ -20,34 +20,25 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif - -inline _LIBCPP_HIDE_FROM_ABI_C long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) { return ::strtoll(__nptr, __endptr, __base); } -inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long -strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI unsigned long long strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) { return ::strtoull(__nptr, __endptr, __base); } -inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoll_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long long wcstoll_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) { return ::wcstoll(__nptr, __endptr, __base); } -inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long +inline _LIBCPP_HIDE_FROM_ABI unsigned long long wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) { return ::wcstoull(__nptr, __endptr, __base); } -inline _LIBCPP_HIDE_FROM_ABI_C long double wcstold_l(const wchar_t* __nptr, wchar_t** __endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long double wcstold_l(const wchar_t* __nptr, wchar_t** __endptr, locale_t) { return ::wcstold(__nptr, __endptr); } -#ifdef __cplusplus -} -#endif - #endif // _LIBCPP___LOCALE_LOCALE_BASE_API_MUSL_H diff --git a/libcxx/include/__locale_dir/locale_base_api/openbsd.h b/libcxx/include/__locale_dir/locale_base_api/openbsd.h index 623abdb4db84..ad999f5dfcad 100644 --- a/libcxx/include/__locale_dir/locale_base_api/openbsd.h +++ b/libcxx/include/__locale_dir/locale_base_api/openbsd.h @@ -16,20 +16,12 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif - -inline _LIBCPP_HIDE_FROM_ABI_C long strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) { return ::strtol(__nptr, __endptr, __base); } -inline _LIBCPP_HIDE_FROM_ABI_C unsigned long strtoul_l(const char* __nptr, char** __endptr, int __base, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI unsigned long strtoul_l(const char* __nptr, char** __endptr, int __base, locale_t) { return ::strtoul(__nptr, __endptr, __base); } -#ifdef __cplusplus -} -#endif - #endif // _LIBCPP___LOCALE_LOCALE_BASE_API_OPENBSD_H diff --git a/libcxx/include/__support/xlocale/__nop_locale_mgmt.h b/libcxx/include/__support/xlocale/__nop_locale_mgmt.h index f7d4d5ce3f1a..b9ffcbe1622d 100644 --- a/libcxx/include/__support/xlocale/__nop_locale_mgmt.h +++ b/libcxx/include/__support/xlocale/__nop_locale_mgmt.h @@ -12,20 +12,16 @@ #include <__config> -#ifdef __cplusplus -extern "C" { -#endif - // Patch over lack of extended locale support typedef void* locale_t; -inline _LIBCPP_HIDE_FROM_ABI_C locale_t duplocale(locale_t) { return NULL; } +inline _LIBCPP_HIDE_FROM_ABI locale_t duplocale(locale_t) { return NULL; } -inline _LIBCPP_HIDE_FROM_ABI_C void freelocale(locale_t) {} +inline _LIBCPP_HIDE_FROM_ABI void freelocale(locale_t) {} -inline _LIBCPP_HIDE_FROM_ABI_C locale_t newlocale(int, const char*, locale_t) { return NULL; } +inline _LIBCPP_HIDE_FROM_ABI locale_t newlocale(int, const char*, locale_t) { return NULL; } -inline _LIBCPP_HIDE_FROM_ABI_C locale_t uselocale(locale_t) { return NULL; } +inline _LIBCPP_HIDE_FROM_ABI locale_t uselocale(locale_t) { return NULL; } #define LC_COLLATE_MASK (1 << LC_COLLATE) #define LC_CTYPE_MASK (1 << LC_CTYPE) @@ -36,8 +32,4 @@ inline _LIBCPP_HIDE_FROM_ABI_C locale_t uselocale(locale_t) { return NULL; } #define LC_ALL_MASK \ (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK | LC_MESSAGES_MASK) -#ifdef __cplusplus -} // extern "C" -#endif - #endif // _LIBCPP___SUPPORT_XLOCALE_NOP_LOCALE_MGMT_H diff --git a/libcxx/include/__support/xlocale/__posix_l_fallback.h b/libcxx/include/__support/xlocale/__posix_l_fallback.h index 42d24db94e25..9c3c99e37ecc 100644 --- a/libcxx/include/__support/xlocale/__posix_l_fallback.h +++ b/libcxx/include/__support/xlocale/__posix_l_fallback.h @@ -25,93 +25,85 @@ # include #endif -#ifdef __cplusplus -extern "C" { -#endif - -inline _LIBCPP_HIDE_FROM_ABI_C int isalnum_l(int __c, locale_t) { return ::isalnum(__c); } +inline _LIBCPP_HIDE_FROM_ABI int isalnum_l(int __c, locale_t) { return ::isalnum(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int isalpha_l(int __c, locale_t) { return ::isalpha(__c); } +inline _LIBCPP_HIDE_FROM_ABI int isalpha_l(int __c, locale_t) { return ::isalpha(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int isblank_l(int __c, locale_t) { return ::isblank(__c); } +inline _LIBCPP_HIDE_FROM_ABI int isblank_l(int __c, locale_t) { return ::isblank(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iscntrl_l(int __c, locale_t) { return ::iscntrl(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iscntrl_l(int __c, locale_t) { return ::iscntrl(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int isdigit_l(int __c, locale_t) { return ::isdigit(__c); } +inline _LIBCPP_HIDE_FROM_ABI int isdigit_l(int __c, locale_t) { return ::isdigit(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int isgraph_l(int __c, locale_t) { return ::isgraph(__c); } +inline _LIBCPP_HIDE_FROM_ABI int isgraph_l(int __c, locale_t) { return ::isgraph(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int islower_l(int __c, locale_t) { return ::islower(__c); } +inline _LIBCPP_HIDE_FROM_ABI int islower_l(int __c, locale_t) { return ::islower(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int isprint_l(int __c, locale_t) { return ::isprint(__c); } +inline _LIBCPP_HIDE_FROM_ABI int isprint_l(int __c, locale_t) { return ::isprint(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int ispunct_l(int __c, locale_t) { return ::ispunct(__c); } +inline _LIBCPP_HIDE_FROM_ABI int ispunct_l(int __c, locale_t) { return ::ispunct(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int isspace_l(int __c, locale_t) { return ::isspace(__c); } +inline _LIBCPP_HIDE_FROM_ABI int isspace_l(int __c, locale_t) { return ::isspace(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int isupper_l(int __c, locale_t) { return ::isupper(__c); } +inline _LIBCPP_HIDE_FROM_ABI int isupper_l(int __c, locale_t) { return ::isupper(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int isxdigit_l(int __c, locale_t) { return ::isxdigit(__c); } +inline _LIBCPP_HIDE_FROM_ABI int isxdigit_l(int __c, locale_t) { return ::isxdigit(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int toupper_l(int __c, locale_t) { return ::toupper(__c); } +inline _LIBCPP_HIDE_FROM_ABI int toupper_l(int __c, locale_t) { return ::toupper(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int tolower_l(int __c, locale_t) { return ::tolower(__c); } +inline _LIBCPP_HIDE_FROM_ABI int tolower_l(int __c, locale_t) { return ::tolower(__c); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI_C int iswalnum_l(wint_t __c, locale_t) { return ::iswalnum(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswalnum_l(wint_t __c, locale_t) { return ::iswalnum(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswalpha_l(wint_t __c, locale_t) { return ::iswalpha(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswalpha_l(wint_t __c, locale_t) { return ::iswalpha(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswblank_l(wint_t __c, locale_t) { return ::iswblank(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswblank_l(wint_t __c, locale_t) { return ::iswblank(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswcntrl_l(wint_t __c, locale_t) { return ::iswcntrl(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswcntrl_l(wint_t __c, locale_t) { return ::iswcntrl(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswdigit_l(wint_t __c, locale_t) { return ::iswdigit(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswdigit_l(wint_t __c, locale_t) { return ::iswdigit(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswgraph_l(wint_t __c, locale_t) { return ::iswgraph(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswgraph_l(wint_t __c, locale_t) { return ::iswgraph(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswlower_l(wint_t __c, locale_t) { return ::iswlower(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswlower_l(wint_t __c, locale_t) { return ::iswlower(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswprint_l(wint_t __c, locale_t) { return ::iswprint(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswprint_l(wint_t __c, locale_t) { return ::iswprint(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswpunct_l(wint_t __c, locale_t) { return ::iswpunct(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswpunct_l(wint_t __c, locale_t) { return ::iswpunct(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswspace_l(wint_t __c, locale_t) { return ::iswspace(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswspace_l(wint_t __c, locale_t) { return ::iswspace(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswupper_l(wint_t __c, locale_t) { return ::iswupper(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswupper_l(wint_t __c, locale_t) { return ::iswupper(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C int iswxdigit_l(wint_t __c, locale_t) { return ::iswxdigit(__c); } +inline _LIBCPP_HIDE_FROM_ABI int iswxdigit_l(wint_t __c, locale_t) { return ::iswxdigit(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C wint_t towupper_l(wint_t __c, locale_t) { return ::towupper(__c); } +inline _LIBCPP_HIDE_FROM_ABI wint_t towupper_l(wint_t __c, locale_t) { return ::towupper(__c); } -inline _LIBCPP_HIDE_FROM_ABI_C wint_t towlower_l(wint_t __c, locale_t) { return ::towlower(__c); } +inline _LIBCPP_HIDE_FROM_ABI wint_t towlower_l(wint_t __c, locale_t) { return ::towlower(__c); } #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI_C int strcoll_l(const char* __s1, const char* __s2, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int strcoll_l(const char* __s1, const char* __s2, locale_t) { return ::strcoll(__s1, __s2); } -inline _LIBCPP_HIDE_FROM_ABI_C size_t strxfrm_l(char* __dest, const char* __src, size_t __n, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI size_t strxfrm_l(char* __dest, const char* __src, size_t __n, locale_t) { return ::strxfrm(__dest, __src, __n); } -inline _LIBCPP_HIDE_FROM_ABI_C size_t +inline _LIBCPP_HIDE_FROM_ABI size_t strftime_l(char* __s, size_t __max, const char* __format, const struct tm* __tm, locale_t) { return ::strftime(__s, __max, __format, __tm); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI_C int wcscoll_l(const wchar_t* __ws1, const wchar_t* __ws2, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI int wcscoll_l(const wchar_t* __ws1, const wchar_t* __ws2, locale_t) { return ::wcscoll(__ws1, __ws2); } -inline _LIBCPP_HIDE_FROM_ABI_C size_t wcsxfrm_l(wchar_t* __dest, const wchar_t* __src, size_t __n, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI size_t wcsxfrm_l(wchar_t* __dest, const wchar_t* __src, size_t __n, locale_t) { return ::wcsxfrm(__dest, __src, __n); } #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS -#ifdef __cplusplus -} -#endif - #endif // _LIBCPP___SUPPORT_XLOCALE_POSIX_L_FALLBACK_H diff --git a/libcxx/include/__support/xlocale/__strtonum_fallback.h b/libcxx/include/__support/xlocale/__strtonum_fallback.h index ae8e13a75849..5dd59500c592 100644 --- a/libcxx/include/__support/xlocale/__strtonum_fallback.h +++ b/libcxx/include/__support/xlocale/__strtonum_fallback.h @@ -22,48 +22,39 @@ # include #endif -#ifdef __cplusplus -extern "C" { -#endif - -inline _LIBCPP_HIDE_FROM_ABI_C float strtof_l(const char* __nptr, char** __endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI float strtof_l(const char* __nptr, char** __endptr, locale_t) { return ::strtof(__nptr, __endptr); } -inline _LIBCPP_HIDE_FROM_ABI_C double strtod_l(const char* __nptr, char** __endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI double strtod_l(const char* __nptr, char** __endptr, locale_t) { return ::strtod(__nptr, __endptr); } -inline _LIBCPP_HIDE_FROM_ABI_C long double strtold_l(const char* __nptr, char** __endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long double strtold_l(const char* __nptr, char** __endptr, locale_t) { return ::strtold(__nptr, __endptr); } -inline _LIBCPP_HIDE_FROM_ABI_C long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) { return ::strtoll(__nptr, __endptr, __base); } -inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long -strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI unsigned long long strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) { return ::strtoull(__nptr, __endptr, __base); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoll_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long long wcstoll_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) { return ::wcstoll(__nptr, __endptr, __base); } -inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long +inline _LIBCPP_HIDE_FROM_ABI unsigned long long wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) { return ::wcstoull(__nptr, __endptr, __base); } -inline _LIBCPP_HIDE_FROM_ABI_C long double wcstold_l(const wchar_t* __nptr, wchar_t** __endptr, locale_t) { +inline _LIBCPP_HIDE_FROM_ABI long double wcstold_l(const wchar_t* __nptr, wchar_t** __endptr, locale_t) { return ::wcstold(__nptr, __endptr); } #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS -#ifdef __cplusplus -} -#endif - #endif // _LIBCPP___SUPPORT_XLOCALE_STRTONUM_FALLBACK_H -- GitLab From 80303cb287e2c52c7bf4923bc61ebe25b2421bdc Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sun, 2 Jun 2024 12:26:10 -0700 Subject: [PATCH 038/678] [clang-format] Handle attributes before lambda return arrow (#94119) Fixes #92657. --- clang/lib/Format/UnwrappedLineParser.cpp | 2 +- clang/unittests/Format/FormatTest.cpp | 1 + clang/unittests/Format/TokenAnnotatorTest.cpp | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 5c0ff0f6132b..053fd3d4df55 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2236,7 +2236,7 @@ bool UnwrappedLineParser::tryToParseLambda() { bool InTemplateParameterList = false; while (FormatTok->isNot(tok::l_brace)) { - if (FormatTok->isTypeName(LangOpts)) { + if (FormatTok->isTypeName(LangOpts) || FormatTok->isAttribute()) { nextToken(); continue; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 59f1ff6a4b29..6057d5b724bf 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -22664,6 +22664,7 @@ TEST_F(FormatTest, FormatsLambdas) { verifyFormat("SomeFunction({[]() -> int *[] { return {}; }});"); verifyFormat("SomeFunction({[]() -> int (*)[] { return {}; }});"); verifyFormat("SomeFunction({[]() -> ns::type { return {}; }});"); + verifyFormat("foo([&](u32 bar) __attribute__((always_inline)) -> void {});"); verifyFormat("return int{[x = x]() { return x; }()};"); // Lambdas with explicit template argument lists. diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 3339a749df3a..df268f49e1ec 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1577,6 +1577,12 @@ TEST_F(TokenAnnotatorTest, UnderstandsLambdas) { EXPECT_TOKEN(Tokens[2], tok::arrow, TT_TrailingReturnArrow); EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_LambdaLBrace); + Tokens = annotate("foo([&](u32 bar) __attribute__((attr)) -> void {});"); + ASSERT_EQ(Tokens.size(), 22u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::l_square, TT_LambdaLSquare); + EXPECT_TOKEN(Tokens[15], tok::arrow, TT_TrailingReturnArrow); + EXPECT_TOKEN(Tokens[17], tok::l_brace, TT_LambdaLBrace); + Tokens = annotate("[] () {}"); ASSERT_EQ(Tokens.size(), 11u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare); -- GitLab From f06f0164199d4a968d8336937cd5ef2c05946d8d Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sun, 2 Jun 2024 12:44:40 -0700 Subject: [PATCH 039/678] [clang-format][NFC] Add missing parens of __attribute in unit tests --- clang/unittests/Format/FormatTest.cpp | 2 +- clang/unittests/Format/TokenAnnotatorTest.cpp | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 6057d5b724bf..004ecb63f662 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -14928,7 +14928,7 @@ TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { verifyFormat("union Z {\n int n;\n} x;"); verifyFormat("class MACRO Z {\n} n;"); verifyFormat("class MACRO(X) Z {\n} n;"); - verifyFormat("class __attribute__(X) Z {\n} n;"); + verifyFormat("class __attribute__((X)) Z {\n} n;"); verifyFormat("class __declspec(X) Z {\n} n;"); verifyFormat("class A##B##C {\n} n;"); verifyFormat("class alignas(16) Z {\n} n;"); diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index df268f49e1ec..a3b2569d8063 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1994,11 +1994,11 @@ TEST_F(TokenAnnotatorTest, UnderstandHashInMacro) { TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacros) { // '__attribute__' has special handling. - auto Tokens = annotate("__attribute__(X) void Foo(void);"); - ASSERT_EQ(Tokens.size(), 11u) << Tokens; + auto Tokens = annotate("__attribute__((X)) void Foo(void);"); + ASSERT_EQ(Tokens.size(), 13u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw___attribute, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_AttributeLParen); - EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_AttributeRParen); + EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen); // Generic macro has no special handling in this location. Tokens = annotate("A(X) void Foo(void);"); @@ -2020,11 +2020,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacros) { TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacrosOnObjCDecl) { // '__attribute__' has special handling. - auto Tokens = annotate("__attribute__(X) @interface Foo"); - ASSERT_EQ(Tokens.size(), 8u) << Tokens; + auto Tokens = annotate("__attribute__((X)) @interface Foo"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_TOKEN(Tokens[0], tok::kw___attribute, TT_Unknown); EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_AttributeLParen); - EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_AttributeRParen); + EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_AttributeRParen); // Generic macro has no special handling in this location. Tokens = annotate("A(X) @interface Foo"); @@ -2048,11 +2048,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacrosOnObjCDecl) { TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacrosOnObjCMethodDecl) { // '__attribute__' has special handling. - auto Tokens = annotate("- (id)init __attribute__(X);"); - ASSERT_EQ(Tokens.size(), 11u) << Tokens; + auto Tokens = annotate("- (id)init __attribute__((X));"); + ASSERT_EQ(Tokens.size(), 13u) << Tokens; EXPECT_TOKEN(Tokens[5], tok::kw___attribute, TT_Unknown); EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_AttributeLParen); - EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_AttributeRParen); + EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_AttributeRParen); // Generic macro has no special handling in this location. Tokens = annotate("- (id)init A(X);"); @@ -2076,11 +2076,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacrosOnObjCMethodDecl) { TEST_F(TokenAnnotatorTest, UnderstandsAttributeMacrosOnObjCProperty) { // '__attribute__' has special handling. - auto Tokens = annotate("@property(weak) id delegate __attribute__(X);"); - ASSERT_EQ(Tokens.size(), 13u) << Tokens; + auto Tokens = annotate("@property(weak) id delegate __attribute__((X));"); + ASSERT_EQ(Tokens.size(), 15u) << Tokens; EXPECT_TOKEN(Tokens[7], tok::kw___attribute, TT_Unknown); EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_AttributeLParen); - EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_AttributeRParen); + EXPECT_TOKEN(Tokens[12], tok::r_paren, TT_AttributeRParen); // Generic macro has no special handling in this location. Tokens = annotate("@property(weak) id delegate A(X);"); -- GitLab From 4ce65423be0ba1d90c11b6a79981d6314e1cf36d Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sun, 2 Jun 2024 13:30:32 -0700 Subject: [PATCH 040/678] [memprof] Use const ref for IndexedRecord (#94114) The type of *Iter here is "const IndexedMemProfRecord &" as defined in RecordLookupTrait. Assigning *Iter to a variable of type "const IndexedMemProfRecord &" avoids a copy, reducing the cycle and instruction counts by 1.8% and 0.2%, respectively, with "llvm-profdata show" modified to deserialize all MemProfRecords. Note that RecordLookupTrait has an internal copy of IndexedMemProfRecord, so we don't have to worry about a dangling reference to a temporary. --- llvm/lib/ProfileData/InstrProfReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index 1e6671629468..8298d3d37295 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -1613,7 +1613,7 @@ IndexedMemProfReader::getMemProfRecord(const uint64_t FuncNameHash) const { instrprof_error::unknown_function, "memprof record not found for function hash " + Twine(FuncNameHash)); - const memprof::IndexedMemProfRecord IndexedRecord = *Iter; + const memprof::IndexedMemProfRecord &IndexedRecord = *Iter; switch (Version) { case memprof::Version0: case memprof::Version1: -- GitLab From ab08df2292334d4980b3e81829a20904e59e13c9 Mon Sep 17 00:00:00 2001 From: Joshua Cao Date: Sun, 2 Jun 2024 15:02:11 -0700 Subject: [PATCH 041/678] [IR] Do not set `none` for function uwtable (#93387) This avoids the pitfall where we set the uwtable to none: ``` func.setUWTableKind(llvm::UWTableKind::None) ``` `Attribute::getAsString()` would see an unknown attribute and fail an assertion. In this patch, we assert that we do not see a None uwtable kind. This also skips the check of `UWTableKind::Async`. It is dominated by the check of `UWTableKind::Default`, which has the same enum value (nfc). --- llvm/include/llvm/IR/Function.h | 5 ++++- llvm/lib/CodeGen/MachineOutliner.cpp | 3 +-- llvm/lib/IR/Attributes.cpp | 9 ++------- llvm/unittests/IR/FunctionTest.cpp | 23 +++++++++++++++++++++++ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index cb514cde95b5..5468cedb0815 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -654,7 +654,10 @@ public: return getUWTableKind() != UWTableKind::None; } void setUWTableKind(UWTableKind K) { - addFnAttr(Attribute::getWithUWTableKind(getContext(), K)); + if (K == UWTableKind::None) + removeFnAttr(Attribute::UWTable); + else + addFnAttr(Attribute::getWithUWTableKind(getContext(), K)); } /// True if this function needs an unwind table. bool needsUnwindTableEntry() const { diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp index dc2f5ef15206..f174dd857def 100644 --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -717,8 +717,7 @@ MachineFunction *MachineOutliner::createOutlinedFunction( [](UWTableKind K, const outliner::Candidate &C) { return std::max(K, C.getMF()->getFunction().getUWTableKind()); }); - if (UW != UWTableKind::None) - F->setUWTableKind(UW); + F->setUWTableKind(UW); BasicBlock *EntryBB = BasicBlock::Create(C, "entry", F); IRBuilder<> Builder(EntryBB); diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index c8d6bdd42387..7a3c9a99ee4d 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -526,13 +526,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { if (hasAttribute(Attribute::UWTable)) { UWTableKind Kind = getUWTableKind(); - if (Kind != UWTableKind::None) { - return Kind == UWTableKind::Default - ? "uwtable" - : ("uwtable(" + - Twine(Kind == UWTableKind::Sync ? "sync" : "async") + ")") - .str(); - } + assert(Kind != UWTableKind::None && "uwtable attribute should not be none"); + return Kind == UWTableKind::Default ? "uwtable" : "uwtable(sync)"; } if (hasAttribute(Attribute::AllocKind)) { diff --git a/llvm/unittests/IR/FunctionTest.cpp b/llvm/unittests/IR/FunctionTest.cpp index 8e77dfbb9dbd..9aaff3ea3383 100644 --- a/llvm/unittests/IR/FunctionTest.cpp +++ b/llvm/unittests/IR/FunctionTest.cpp @@ -486,4 +486,27 @@ TEST(FunctionTest, EraseBBs) { It = F->erase(F->begin(), F->end()); EXPECT_EQ(F->size(), 0u); } + +TEST(FunctionTest, UWTable) { + LLVMContext Ctx; + std::unique_ptr M = parseIR(Ctx, R"( + define void @foo() { + bb1: + ret void + } +)"); + + Function &F = *M->getFunction("foo"); + + EXPECT_FALSE(F.hasUWTable()); + EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None); + + F.setUWTableKind(UWTableKind::Async); + EXPECT_TRUE(F.hasUWTable()); + EXPECT_TRUE(F.getUWTableKind() == UWTableKind::Async); + + F.setUWTableKind(UWTableKind::None); + EXPECT_FALSE(F.hasUWTable()); + EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None); +} } // end namespace -- GitLab From 2fbc9f217e5fe8db8444a87dbd7138a768b8aa85 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sun, 2 Jun 2024 16:44:05 -0700 Subject: [PATCH 042/678] [clang-format][doc] Clean up quotes, etc. --- clang/docs/ClangFormatStyleOptions.rst | 69 +++++++++++++------------- clang/include/clang/Format/Format.h | 69 +++++++++++++------------- 2 files changed, 68 insertions(+), 70 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 1a7d0e6a05e3..677dac25df68 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -1799,8 +1799,8 @@ the configuration (without a prefix: ``Auto``). Never merge functions into a single line. * ``SFS_InlineOnly`` (in configuration: ``InlineOnly``) - Only merge functions defined inside a class. Same as "inline", - except it does not implies "empty": i.e. top level empty functions + Only merge functions defined inside a class. Same as ``inline``, + except it does not implies ``empty``: i.e. top level empty functions are not merged either. .. code-block:: c++ @@ -1825,7 +1825,7 @@ the configuration (without a prefix: ``Auto``). } * ``SFS_Inline`` (in configuration: ``Inline``) - Only merge functions defined inside a class. Implies "empty". + Only merge functions defined inside a class. Implies ``empty``. .. code-block:: c++ @@ -2042,7 +2042,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - AttributeMacros: ['__capability', '__output', '__unused'] + AttributeMacros: [__capability, __output, __unused] .. _BinPackArguments: @@ -3802,7 +3802,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - ForEachMacros: ['RANGES_FOR', 'FOREACH'] + ForEachMacros: [RANGES_FOR, FOREACH] For example: BOOST_FOREACH. @@ -3825,7 +3825,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - IfMacros: ['IF'] + IfMacros: [IF] For example: `KJ_IF_MAYBE `_ @@ -4374,7 +4374,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - JavaImportGroups: ['com.example', 'com', 'org'] + JavaImportGroups: [com.example, com, org] .. code-block:: java @@ -4438,7 +4438,7 @@ the configuration (without a prefix: ``Auto``). VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, - } from 'some/module.js' + } from "some/module.js" false: import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js" @@ -5088,7 +5088,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - QualifierOrder: ['inline', 'static', 'type', 'const'] + QualifierOrder: [inline, static, type, const] .. code-block:: c++ @@ -5117,16 +5117,16 @@ the configuration (without a prefix: ``Auto``). .. note:: - it MUST contain 'type'. + It must contain ``type``. - Items to the left of 'type' will be placed to the left of the type and - aligned in the order supplied. Items to the right of 'type' will be + Items to the left of ``type`` will be placed to the left of the type and + aligned in the order supplied. Items to the right of ``type`` will be placed to the right of the type and aligned in the order supplied. .. code-block:: yaml - QualifierOrder: ['inline', 'static', 'type', 'const', 'volatile' ] + QualifierOrder: [inline, static, type, const, volatile] .. _RawStringFormats: @@ -5138,10 +5138,10 @@ the configuration (without a prefix: ``Auto``). name will be reformatted assuming the specified language based on the style for that language defined in the .clang-format file. If no style has been defined in the .clang-format file for the specific language, a - predefined style given by 'BasedOnStyle' is used. If 'BasedOnStyle' is not - found, the formatting is based on llvm style. A matching delimiter takes - precedence over a matching enclosing function name for determining the - language of the raw string contents. + predefined style given by ``BasedOnStyle`` is used. If ``BasedOnStyle`` is + not found, the formatting is based on ``LLVM`` style. A matching delimiter + takes precedence over a matching enclosing function name for determining + the language of the raw string contents. If a canonical delimiter is specified, occurrences of other delimiters for the same language will be updated to the canonical if possible. @@ -5156,17 +5156,17 @@ the configuration (without a prefix: ``Auto``). RawStringFormats: - Language: TextProto Delimiters: - - 'pb' - - 'proto' + - pb + - proto EnclosingFunctions: - - 'PARSE_TEXT_PROTO' + - PARSE_TEXT_PROTO BasedOnStyle: google - Language: Cpp Delimiters: - - 'cc' - - 'cpp' - BasedOnStyle: llvm - CanonicalDelimiter: 'cc' + - cc + - cpp + BasedOnStyle: LLVM + CanonicalDelimiter: cc .. _ReferenceAlignment: @@ -5533,7 +5533,7 @@ the configuration (without a prefix: ``Auto``). This determines the maximum length of short namespaces by counting unwrapped lines (i.e. containing neither opening nor closing - namespace brace) and makes "FixNamespaceComments" omit adding + namespace brace) and makes ``FixNamespaceComments`` omit adding end comments for those. .. code-block:: c++ @@ -5645,7 +5645,7 @@ the configuration (without a prefix: ``Auto``). * ``SUD_Lexicographic`` (in configuration: ``Lexicographic``) Using declarations are sorted in the order defined as follows: - Split the strings by "::" and discard any initial empty strings. Sort + Split the strings by ``::`` and discard any initial empty strings. Sort the lists of names lexicographically, and within those groups, names are in case-insensitive lexicographic order. @@ -5659,7 +5659,7 @@ the configuration (without a prefix: ``Auto``). * ``SUD_LexicographicNumeric`` (in configuration: ``LexicographicNumeric``) Using declarations are sorted in the order defined as follows: - Split the strings by "::" and discard any initial empty strings. The + Split the strings by ``::`` and discard any initial empty strings. The last element of each list is a non-namespace name; all others are namespace names. Sort the lists of names lexicographically, where the sort order of individual names is that all non-namespace names come @@ -5699,7 +5699,7 @@ the configuration (without a prefix: ``Auto``). .. _SpaceAfterTemplateKeyword: **SpaceAfterTemplateKeyword** (``Boolean``) :versionbadge:`clang-format 4` :ref:`¶ ` - If ``true``, a space will be inserted after the 'template' keyword. + If ``true``, a space will be inserted after the ``template`` keyword. .. code-block:: c++ @@ -5860,7 +5860,7 @@ the configuration (without a prefix: ``Auto``). * ``SBPO_NonEmptyParentheses`` (in configuration: ``NonEmptyParentheses``) Put a space before opening parentheses only if the parentheses are not - empty i.e. '()' + empty. .. code-block:: c++ @@ -6245,7 +6245,7 @@ the configuration (without a prefix: ``Auto``). true: false: x = ( int32 )y vs. x = (int32)y - * ``bool InEmptyParentheses`` Put a space in parentheses only if the parentheses are empty i.e. '()' + * ``bool InEmptyParentheses`` Insert a space in empty parentheses, i.e. ``()``. .. code-block:: c++ @@ -6409,10 +6409,9 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml TableGenBreakInsideDAGArg: BreakAll - TableGenBreakingDAGArgOperators: ['ins', 'outs'] - + TableGenBreakingDAGArgOperators: [ins, outs] makes the line break only occurs inside DAGArgs beginning with the - specified identifiers 'ins' and 'outs'. + specified identifiers ``ins`` and ``outs``. .. code-block:: c++ @@ -6450,7 +6449,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - TypenameMacros: ['STACK_OF', 'LIST'] + TypenameMacros: [STACK_OF, LIST] For example: OpenSSL STACK_OF, BSD LIST_ENTRY. @@ -6518,7 +6517,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - WhitespaceSensitiveMacros: ['STRINGIZE', 'PP_STRINGIZE'] + WhitespaceSensitiveMacros: [STRINGIZE, PP_STRINGIZE] For example: BOOST_PP_STRINGIZE diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index eb6647038403..1e220ce0749b 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -814,8 +814,8 @@ struct FormatStyle { enum ShortFunctionStyle : int8_t { /// Never merge functions into a single line. SFS_None, - /// Only merge functions defined inside a class. Same as "inline", - /// except it does not implies "empty": i.e. top level empty functions + /// Only merge functions defined inside a class. Same as ``inline``, + /// except it does not implies ``empty``: i.e. top level empty functions /// are not merged either. /// \code /// class Foo { @@ -836,7 +836,7 @@ struct FormatStyle { /// } /// \endcode SFS_Empty, - /// Only merge functions defined inside a class. Implies "empty". + /// Only merge functions defined inside a class. Implies ``empty``. /// \code /// class Foo { /// void f() { foo(); } @@ -1167,7 +1167,7 @@ struct FormatStyle { /// /// In the .clang-format configuration file, this can be configured like: /// \code{.yaml} - /// AttributeMacros: ['__capability', '__output', '__unused'] + /// AttributeMacros: [__capability, __output, __unused] /// \endcode /// /// \version 12 @@ -2631,7 +2631,7 @@ struct FormatStyle { /// /// In the .clang-format configuration file, this can be configured like: /// \code{.yaml} - /// ForEachMacros: ['RANGES_FOR', 'FOREACH'] + /// ForEachMacros: [RANGES_FOR, FOREACH] /// \endcode /// /// For example: BOOST_FOREACH. @@ -2653,7 +2653,7 @@ struct FormatStyle { /// /// In the .clang-format configuration file, this can be configured like: /// \code{.yaml} - /// IfMacros: ['IF'] + /// IfMacros: [IF] /// \endcode /// /// For example: `KJ_IF_MAYBE @@ -3030,7 +3030,7 @@ struct FormatStyle { /// in the following yaml example. This will result in imports being /// formatted as in the Java example below. /// \code{.yaml} - /// JavaImportGroups: ['com.example', 'com', 'org'] + /// JavaImportGroups: [com.example, com, org] /// \endcode /// /// \code{.java} @@ -3086,7 +3086,7 @@ struct FormatStyle { /// VeryLongImportsAreAnnoying, /// VeryLongImportsAreAnnoying, /// VeryLongImportsAreAnnoying, - /// } from 'some/module.js' + /// } from "some/module.js" /// /// false: /// import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js" @@ -3615,7 +3615,7 @@ struct FormatStyle { /// Change specifiers/qualifiers to be aligned based on ``QualifierOrder``. /// With: /// \code{.yaml} - /// QualifierOrder: ['inline', 'static', 'type', 'const'] + /// QualifierOrder: [inline, static, type, const] /// \endcode /// /// \code @@ -3650,15 +3650,15 @@ struct FormatStyle { /// * type /// /// \note - /// it MUST contain 'type'. + /// It \b must contain ``type``. /// \endnote /// - /// Items to the left of 'type' will be placed to the left of the type and - /// aligned in the order supplied. Items to the right of 'type' will be + /// Items to the left of ``type`` will be placed to the left of the type and + /// aligned in the order supplied. Items to the right of ``type`` will be /// placed to the right of the type and aligned in the order supplied. /// /// \code{.yaml} - /// QualifierOrder: ['inline', 'static', 'type', 'const', 'volatile' ] + /// QualifierOrder: [inline, static, type, const, volatile] /// \endcode /// \version 14 std::vector QualifierOrder; @@ -3692,10 +3692,10 @@ struct FormatStyle { /// name will be reformatted assuming the specified language based on the /// style for that language defined in the .clang-format file. If no style has /// been defined in the .clang-format file for the specific language, a - /// predefined style given by 'BasedOnStyle' is used. If 'BasedOnStyle' is not - /// found, the formatting is based on llvm style. A matching delimiter takes - /// precedence over a matching enclosing function name for determining the - /// language of the raw string contents. + /// predefined style given by ``BasedOnStyle`` is used. If ``BasedOnStyle`` is + /// not found, the formatting is based on ``LLVM`` style. A matching delimiter + /// takes precedence over a matching enclosing function name for determining + /// the language of the raw string contents. /// /// If a canonical delimiter is specified, occurrences of other delimiters for /// the same language will be updated to the canonical if possible. @@ -3708,17 +3708,17 @@ struct FormatStyle { /// RawStringFormats: /// - Language: TextProto /// Delimiters: - /// - 'pb' - /// - 'proto' + /// - pb + /// - proto /// EnclosingFunctions: - /// - 'PARSE_TEXT_PROTO' + /// - PARSE_TEXT_PROTO /// BasedOnStyle: google /// - Language: Cpp /// Delimiters: - /// - 'cc' - /// - 'cpp' - /// BasedOnStyle: llvm - /// CanonicalDelimiter: 'cc' + /// - cc + /// - cpp + /// BasedOnStyle: LLVM + /// CanonicalDelimiter: cc /// \endcode /// \version 6 std::vector RawStringFormats; @@ -4046,7 +4046,7 @@ struct FormatStyle { /// /// This determines the maximum length of short namespaces by counting /// unwrapped lines (i.e. containing neither opening nor closing - /// namespace brace) and makes "FixNamespaceComments" omit adding + /// namespace brace) and makes ``FixNamespaceComments`` omit adding /// end comments for those. /// \code /// ShortNamespaceLines: 1 vs. ShortNamespaceLines: 0 @@ -4138,7 +4138,7 @@ struct FormatStyle { /// \endcode SUD_Never, /// Using declarations are sorted in the order defined as follows: - /// Split the strings by "::" and discard any initial empty strings. Sort + /// Split the strings by ``::`` and discard any initial empty strings. Sort /// the lists of names lexicographically, and within those groups, names are /// in case-insensitive lexicographic order. /// \code @@ -4150,7 +4150,7 @@ struct FormatStyle { /// \endcode SUD_Lexicographic, /// Using declarations are sorted in the order defined as follows: - /// Split the strings by "::" and discard any initial empty strings. The + /// Split the strings by ``::`` and discard any initial empty strings. The /// last element of each list is a non-namespace name; all others are /// namespace names. Sort the lists of names lexicographically, where the /// sort order of individual names is that all non-namespace names come @@ -4186,7 +4186,7 @@ struct FormatStyle { /// \version 9 bool SpaceAfterLogicalNot; - /// If \c true, a space will be inserted after the 'template' keyword. + /// If \c true, a space will be inserted after the ``template`` keyword. /// \code /// true: false: /// template void foo(); vs. template void foo(); @@ -4316,7 +4316,7 @@ struct FormatStyle { /// \endcode SBPO_ControlStatementsExceptControlMacros, /// Put a space before opening parentheses only if the parentheses are not - /// empty i.e. '()' + /// empty. /// \code /// void() { /// if (true) { @@ -4668,7 +4668,7 @@ struct FormatStyle { /// x = ( int32 )y vs. x = (int32)y /// \endcode bool InCStyleCasts; - /// Put a space in parentheses only if the parentheses are empty i.e. '()' + /// Insert a space in empty parentheses, i.e. ``()``. /// \code /// true: false: /// void f( ) { vs. void f() { @@ -4804,11 +4804,10 @@ struct FormatStyle { /// For example the configuration, /// \code{.yaml} /// TableGenBreakInsideDAGArg: BreakAll - /// TableGenBreakingDAGArgOperators: ['ins', 'outs'] + /// TableGenBreakingDAGArgOperators: [ins, outs] /// \endcode - /// /// makes the line break only occurs inside DAGArgs beginning with the - /// specified identifiers 'ins' and 'outs'. + /// specified identifiers ``ins`` and ``outs``. /// /// \code /// let DAGArgIns = (ins @@ -4873,7 +4872,7 @@ struct FormatStyle { /// /// In the .clang-format configuration file, this can be configured like: /// \code{.yaml} - /// TypenameMacros: ['STACK_OF', 'LIST'] + /// TypenameMacros: [STACK_OF, LIST] /// \endcode /// /// For example: OpenSSL STACK_OF, BSD LIST_ENTRY. @@ -4929,7 +4928,7 @@ struct FormatStyle { /// /// In the .clang-format configuration file, this can be configured like: /// \code{.yaml} - /// WhitespaceSensitiveMacros: ['STRINGIZE', 'PP_STRINGIZE'] + /// WhitespaceSensitiveMacros: [STRINGIZE, PP_STRINGIZE] /// \endcode /// /// For example: BOOST_PP_STRINGIZE -- GitLab From d7d2d4f53fc79b4b58e8d8d08151b577c3699d4a Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sun, 2 Jun 2024 18:03:12 -0700 Subject: [PATCH 043/678] [clang-format] Fix documentation build error https://github.com/llvm/llvm-project/actions/runs/9342063971/job/25709589592 --- clang/include/clang/Format/Format.h | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 1e220ce0749b..9bae252df366 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4806,6 +4806,7 @@ struct FormatStyle { /// TableGenBreakInsideDAGArg: BreakAll /// TableGenBreakingDAGArgOperators: [ins, outs] /// \endcode + /// /// makes the line break only occurs inside DAGArgs beginning with the /// specified identifiers ``ins`` and ``outs``. /// -- GitLab From f779ec7c13bdfccd29655d13a325f34c60797a76 Mon Sep 17 00:00:00 2001 From: Enna1 Date: Mon, 3 Jun 2024 10:21:07 +0800 Subject: [PATCH 044/678] [BPI] Cache LoopExitBlocks to improve compile time (#93451) The `LoopBlock` stored in `LoopWorkList` consist of basic block and its loop data information. When iterate `LoopWorkList`, if estimated weight of a loop is not stored in `EstimatedLoopWeight`, `getLoopExitBlocks()` is called to get all exit blocks of the loop. The estimated weight of a loop is calculated by iterating over edges leading from basic block to all exit blocks of the loop. If at least one edge has unknown estimated weight, the estimated weight of loop is unknown and will not be stored in `EstimatedLoopWeight`. `LoopWorkList` can contain different blocks in a same loop, so there is wasted work that calls `getLoopExitBlocks()` for same loop multiple times. Since computing the exit blocks of loop is expensive and the loop structure is not mutated in Branch Probability Analysis, we can cache the result and improve compile time. With this change, the overall compile time for a file containing a very large loop is dropped by around 82%. --- llvm/lib/Analysis/BranchProbabilityInfo.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Analysis/BranchProbabilityInfo.cpp b/llvm/lib/Analysis/BranchProbabilityInfo.cpp index cd3e3a499132..50dcd5f45233 100644 --- a/llvm/lib/Analysis/BranchProbabilityInfo.cpp +++ b/llvm/lib/Analysis/BranchProbabilityInfo.cpp @@ -810,6 +810,7 @@ void BranchProbabilityInfo::computeEestimateBlockWeight( const Function &F, DominatorTree *DT, PostDominatorTree *PDT) { SmallVector BlockWorkList; SmallVector LoopWorkList; + SmallDenseMap> LoopExitBlocks; // By doing RPO we make sure that all predecessors already have weights // calculated before visiting theirs successors. @@ -828,12 +829,14 @@ void BranchProbabilityInfo::computeEestimateBlockWeight( do { while (!LoopWorkList.empty()) { const LoopBlock LoopBB = LoopWorkList.pop_back_val(); - - if (EstimatedLoopWeight.count(LoopBB.getLoopData())) + const LoopData LD = LoopBB.getLoopData(); + if (EstimatedLoopWeight.count(LD)) continue; - SmallVector Exits; - getLoopExitBlocks(LoopBB, Exits); + auto Res = LoopExitBlocks.try_emplace(LD); + SmallVectorImpl &Exits = Res.first->second; + if (Res.second) + getLoopExitBlocks(LoopBB, Exits); auto LoopWeight = getMaxEstimatedEdgeWeight( LoopBB, make_range(Exits.begin(), Exits.end())); @@ -842,7 +845,7 @@ void BranchProbabilityInfo::computeEestimateBlockWeight( if (LoopWeight <= static_cast(BlockExecWeight::UNREACHABLE)) LoopWeight = static_cast(BlockExecWeight::LOWEST_NON_ZERO); - EstimatedLoopWeight.insert({LoopBB.getLoopData(), *LoopWeight}); + EstimatedLoopWeight.insert({LD, *LoopWeight}); // Add all blocks entering the loop into working list. getLoopEnterBlocks(LoopBB, BlockWorkList); } -- GitLab From e12bf36d237f8ef16c25c266785f6d01fb50dbc1 Mon Sep 17 00:00:00 2001 From: Dhruv Chawla Date: Mon, 3 Jun 2024 10:42:10 +0530 Subject: [PATCH 045/678] [GISel][CombinerHelper] Combine op(trunc(x), trunc(y)) -> trunc(op(x, y)) (#89023) --- .../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 16 + .../AArch64/GlobalISel/combine-op-trunc.mir | 315 ++++++++++++++++++ .../AArch64/GlobalISel/combine-select.mir | 30 +- .../prelegalizercombiner-hoist-same-hands.mir | 7 +- llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll | 191 ++++++----- llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll | 195 ++++++----- .../test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll | 10 +- .../test/CodeGen/AMDGPU/GlobalISel/usubsat.ll | 10 +- llvm/test/CodeGen/AMDGPU/GlobalISel/xnor.ll | 20 +- 9 files changed, 550 insertions(+), 244 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/combine-op-trunc.mir diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index b516608aa53c..02d85958fc7b 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -3158,6 +3158,22 @@ bool CombinerHelper::matchHoistLogicOpWithSameOpcodeHands( // Match: logic (ext X), (ext Y) --> ext (logic X, Y) break; } + case TargetOpcode::G_TRUNC: { + // Match: logic (trunc X), (trunc Y) -> trunc (logic X, Y) + const MachineFunction *MF = MI.getMF(); + const DataLayout &DL = MF->getDataLayout(); + LLVMContext &Ctx = MF->getFunction().getContext(); + + LLT DstTy = MRI.getType(Dst); + const TargetLowering &TLI = getTargetLowering(); + + // Be extra careful sinking truncate. If it's free, there's no benefit in + // widening a binop. + if (TLI.isZExtFree(DstTy, XTy, DL, Ctx) && + TLI.isTruncateFree(XTy, DstTy, DL, Ctx)) + return false; + break; + } case TargetOpcode::G_AND: case TargetOpcode::G_ASHR: case TargetOpcode::G_LSHR: diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-op-trunc.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-op-trunc.mir new file mode 100644 index 000000000000..6a16b5b8b9e7 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-op-trunc.mir @@ -0,0 +1,315 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -o - -mtriple=aarch64-unknown-unknown -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s | FileCheck %s + +# Truncs with a single use get folded. + +# and(trunc(x), trunc(y)) -> trunc(and(x, y)) +--- +name: and_trunc +body: | + bb.0: + liveins: $w0, $w1 + ; CHECK-LABEL: name: and_trunc + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[COPY1]] + ; CHECK-NEXT: $w0 = COPY [[AND]](s32) + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %2:_(s16) = G_TRUNC %0 + %3:_(s16) = G_TRUNC %1 + %4:_(s16) = G_AND %2, %3 + %5:_(s32) = G_ANYEXT %4 + $w0 = COPY %5 +... +--- +name: and_trunc_vector +body: | + bb.0: + liveins: $q0, $q1 + ; CHECK-LABEL: name: and_trunc_vector + ; CHECK: liveins: $q0, $q1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<4 x s32>) = G_AND [[COPY]], [[COPY1]] + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[AND]](<4 x s32>) + ; CHECK-NEXT: $x0 = COPY [[TRUNC]](<4 x s16>) + %0:_(<4 x s32>) = COPY $q0 + %1:_(<4 x s32>) = COPY $q1 + %2:_(<4 x s16>) = G_TRUNC %0 + %3:_(<4 x s16>) = G_TRUNC %1 + %4:_(<4 x s16>) = G_AND %2, %3 + $x0 = COPY %4 +... + +# or(trunc(x), trunc(y)) -> trunc(or(x, y)) +--- +name: or_trunc +body: | + bb.0: + liveins: $w0, $w1 + ; CHECK-LABEL: name: or_trunc + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[COPY]], [[COPY1]] + ; CHECK-NEXT: $w0 = COPY [[OR]](s32) + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %2:_(s16) = G_TRUNC %0 + %3:_(s16) = G_TRUNC %1 + %4:_(s16) = G_OR %2, %3 + %5:_(s32) = G_ANYEXT %4 + $w0 = COPY %5 +... +--- +name: or_trunc_vector +body: | + bb.0: + liveins: $q0, $q1 + ; CHECK-LABEL: name: or_trunc_vector + ; CHECK: liveins: $q0, $q1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<4 x s32>) = G_OR [[COPY]], [[COPY1]] + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[OR]](<4 x s32>) + ; CHECK-NEXT: $x0 = COPY [[TRUNC]](<4 x s16>) + %0:_(<4 x s32>) = COPY $q0 + %1:_(<4 x s32>) = COPY $q1 + %2:_(<4 x s16>) = G_TRUNC %0 + %3:_(<4 x s16>) = G_TRUNC %1 + %4:_(<4 x s16>) = G_OR %2, %3 + $x0 = COPY %4 +... + +# xor(trunc(x), trunc(y)) -> trunc(xor(x, y)) +--- +name: xor_trunc +body: | + bb.0: + liveins: $w0, $w1 + ; CHECK-LABEL: name: xor_trunc + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[COPY]], [[COPY1]] + ; CHECK-NEXT: $w0 = COPY [[XOR]](s32) + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %2:_(s16) = G_TRUNC %0 + %3:_(s16) = G_TRUNC %1 + %4:_(s16) = G_XOR %2, %3 + %5:_(s32) = G_ANYEXT %4 + $w0 = COPY %5 +... +--- +name: xor_trunc_vector +body: | + bb.0: + liveins: $q0, $q1 + ; CHECK-LABEL: name: xor_trunc_vector + ; CHECK: liveins: $q0, $q1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 + ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<4 x s32>) = G_XOR [[COPY]], [[COPY1]] + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[XOR]](<4 x s32>) + ; CHECK-NEXT: $x0 = COPY [[TRUNC]](<4 x s16>) + %0:_(<4 x s32>) = COPY $q0 + %1:_(<4 x s32>) = COPY $q1 + %2:_(<4 x s16>) = G_TRUNC %0 + %3:_(<4 x s16>) = G_TRUNC %1 + %4:_(<4 x s16>) = G_XOR %2, %3 + $x0 = COPY %4 +... + +# Truncs with multiple uses do not get folded. +--- +name: or_trunc_multiuse_1 +body: | + bb.0: + liveins: $w0, $w1, $x2 + ; CHECK-LABEL: name: or_trunc_multiuse_1 + ; CHECK: liveins: $w0, $w1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x2 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32) + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32) + ; CHECK-NEXT: G_STORE [[TRUNC]](s16), [[COPY2]](p0) :: (store (s16)) + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s16) = G_OR [[TRUNC]], [[TRUNC1]] + ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[OR]](s16) + ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32) + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %5:_(p0) = COPY $x2 + %2:_(s16) = G_TRUNC %0 + %3:_(s16) = G_TRUNC %1 + G_STORE %2, %5 :: (store (s16)) + %4:_(s16) = G_OR %2, %3 + %6:_(s32) = G_ANYEXT %4 + $w0 = COPY %6 +... +--- +name: and_trunc_multiuse_2 +body: | + bb.0: + liveins: $w0, $w1, $x2 + ; CHECK-LABEL: name: and_trunc_multiuse_2 + ; CHECK: liveins: $w0, $w1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x2 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32) + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32) + ; CHECK-NEXT: G_STORE [[TRUNC]](s16), [[COPY2]](p0) :: (store (s16)) + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s16) = G_AND [[TRUNC]], [[TRUNC1]] + ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[AND]](s16) + ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32) + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %5:_(p0) = COPY $x2 + %2:_(s16) = G_TRUNC %0 + %3:_(s16) = G_TRUNC %1 + G_STORE %2, %5 :: (store (s16)) + %4:_(s16) = G_AND %2, %3 + %6:_(s32) = G_ANYEXT %4 + $w0 = COPY %6 +... +--- +name: xor_trunc_vector_multiuse +body: | + bb.0: + liveins: $w0, $w1, $x2 + ; CHECK-LABEL: name: xor_trunc_vector_multiuse + ; CHECK: liveins: $w0, $w1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x2 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[COPY]](<4 x s32>) + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[COPY1]](<4 x s32>) + ; CHECK-NEXT: G_STORE [[TRUNC]](<4 x s16>), [[COPY2]](p0) :: (store (<4 x s16>)) + ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<4 x s16>) = G_XOR [[TRUNC]], [[TRUNC1]] + ; CHECK-NEXT: $x0 = COPY [[XOR]](<4 x s16>) + %0:_(<4 x s32>) = COPY $q0 + %1:_(<4 x s32>) = COPY $q1 + %5:_(p0) = COPY $x2 + %2:_(<4 x s16>) = G_TRUNC %0 + %3:_(<4 x s16>) = G_TRUNC %1 + G_STORE %2, %5 :: (store (<4 x s16>)) + %4:_(<4 x s16>) = G_XOR %2, %3 + $x0 = COPY %4 +... + +# Freezes should get pushed through truncs. + +# This optimizes the pattern where `select(cond, T, 0)` gets converted to +# `and(cond, freeze(T))`. + +# and(freeze(trunc(x)), trunc(y)) -> trunc(and(freeze(x), y)) +--- +name: and_trunc_freeze +body: | + bb.0: + liveins: $w0, $w1 + ; CHECK-LABEL: name: and_trunc_freeze + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[COPY]] + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[FREEZE]], [[COPY1]] + ; CHECK-NEXT: $w0 = COPY [[AND]](s32) + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %2:_(s16) = G_TRUNC %0 + %3:_(s16) = G_TRUNC %1 + %6:_(s16) = G_FREEZE %2 + %4:_(s16) = G_AND %6, %3 + %5:_(s32) = G_ANYEXT %4 + $w0 = COPY %5 +... + +# and(freeze(trunc(x)), freeze(trunc(y))) -> trunc(and(freeze(x), freeze(y))) +--- +name: and_trunc_freeze_both +body: | + bb.0: + liveins: $w0, $w1 + ; CHECK-LABEL: name: and_trunc_freeze_both + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[COPY]] + ; CHECK-NEXT: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[COPY1]] + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[FREEZE]], [[FREEZE1]] + ; CHECK-NEXT: $w0 = COPY [[AND]](s32) + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %2:_(s16) = G_TRUNC %0 + %3:_(s16) = G_TRUNC %1 + %6:_(s16) = G_FREEZE %2 + %7:_(s16) = G_FREEZE %3 + %4:_(s16) = G_AND %6, %7 + %5:_(s32) = G_ANYEXT %4 + $w0 = COPY %5 +... + +# The freeze fold is less important for G_OR and G_XOR, however it can still +# trigger. +--- +name: or_trunc_freeze +body: | + bb.0: + liveins: $w0, $w1 + ; CHECK-LABEL: name: or_trunc_freeze + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[COPY]] + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[FREEZE]], [[COPY1]] + ; CHECK-NEXT: $w0 = COPY [[OR]](s32) + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %2:_(s16) = G_TRUNC %0 + %3:_(s16) = G_TRUNC %1 + %6:_(s16) = G_FREEZE %2 + %4:_(s16) = G_OR %6, %3 + %5:_(s32) = G_ANYEXT %4 + $w0 = COPY %5 +... +--- +name: xor_trunc_freeze_both +body: | + bb.0: + liveins: $w0, $w1 + ; CHECK-LABEL: name: xor_trunc_freeze_both + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1 + ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[COPY]] + ; CHECK-NEXT: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[COPY1]] + ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[FREEZE]], [[FREEZE1]] + ; CHECK-NEXT: $w0 = COPY [[XOR]](s32) + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %2:_(s16) = G_TRUNC %0 + %3:_(s16) = G_TRUNC %1 + %6:_(s16) = G_FREEZE %2 + %7:_(s16) = G_FREEZE %3 + %4:_(s16) = G_XOR %6, %7 + %5:_(s32) = G_ANYEXT %4 + $w0 = COPY %5 +... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir index 074d4ecbd878..86fa12aa064a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir @@ -1,7 +1,8 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py -# RUN: llc -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown- --aarch64postlegalizercombiner-only-enable-rule="select_to_logical" %s -o - | FileCheck %s +# RUN: llc -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s # RUN: llc -debugify-and-strip-all-safe -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s # REQUIRES: asserts + --- # select (c, x, x) -> x name: test_combine_select_same_res @@ -116,10 +117,9 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x2 - ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64) ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY1]] - ; CHECK-NEXT: %f:_(s1) = G_TRUNC [[FREEZE]](s64) - ; CHECK-NEXT: %sel:_(s1) = G_OR %c, %f + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[COPY]], [[FREEZE]] + ; CHECK-NEXT: %sel:_(s1) = G_TRUNC [[OR]](s64) ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s1) ; CHECK-NEXT: $w0 = COPY %ext(s32) %0:_(s64) = COPY $x0 @@ -143,10 +143,9 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x2 - ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64) ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY1]] - ; CHECK-NEXT: %f:_(s1) = G_TRUNC [[FREEZE]](s64) - ; CHECK-NEXT: %sel:_(s1) = G_OR %c, %f + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[COPY]], [[FREEZE]] + ; CHECK-NEXT: %sel:_(s1) = G_TRUNC [[OR]](s64) ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s1) ; CHECK-NEXT: $w0 = COPY %ext(s32) %0:_(s64) = COPY $x0 @@ -171,12 +170,9 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d2 - ; CHECK-NEXT: %c:_(<2 x s1>) = G_TRUNC [[COPY]](<2 x s32>) ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(<2 x s32>) = G_FREEZE [[COPY1]] - ; CHECK-NEXT: %f:_(<2 x s1>) = G_TRUNC [[FREEZE]](<2 x s32>) - ; CHECK-NEXT: %sel:_(<2 x s1>) = G_OR %c, %f - ; CHECK-NEXT: %ext:_(<2 x s32>) = G_ANYEXT %sel(<2 x s1>) - ; CHECK-NEXT: $d0 = COPY %ext(<2 x s32>) + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s32>) = G_OR [[COPY]], [[FREEZE]] + ; CHECK-NEXT: $d0 = COPY [[OR]](<2 x s32>) %0:_(<2 x s32>) = COPY $d0 %1:_(<2 x s32>) = COPY $d1 %2:_(<2 x s32>) = COPY $d2 @@ -200,10 +196,9 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64) ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY1]] - ; CHECK-NEXT: %t:_(s1) = G_TRUNC [[FREEZE]](s64) - ; CHECK-NEXT: %sel:_(s1) = G_AND %c, %t + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[FREEZE]] + ; CHECK-NEXT: %sel:_(s1) = G_TRUNC [[AND]](s64) ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s1) ; CHECK-NEXT: $w0 = COPY %ext(s32) %0:_(s64) = COPY $x0 @@ -228,10 +223,9 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64) ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY1]] - ; CHECK-NEXT: %t:_(s1) = G_TRUNC [[FREEZE]](s64) - ; CHECK-NEXT: %sel:_(s1) = G_AND %c, %t + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY]], [[FREEZE]] + ; CHECK-NEXT: %sel:_(s1) = G_TRUNC [[AND]](s64) ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s1) ; CHECK-NEXT: $w0 = COPY %ext(s32) %0:_(s64) = COPY $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-hoist-same-hands.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-hoist-same-hands.mir index 48fc042d7c73..7f2ae6ee2480 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-hoist-same-hands.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-hoist-same-hands.mir @@ -268,10 +268,9 @@ body: | ; CHECK: liveins: $w0, $w1 ; CHECK: %x_wide:_(s32) = COPY $w0 ; CHECK: %y_wide:_(s32) = COPY $w1 - ; CHECK: %x:_(s1) = G_TRUNC %x_wide(s32) - ; CHECK: %y:_(s1) = G_TRUNC %y_wide(s32) - ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR %x, %y - ; CHECK: %logic_op:_(s64) = G_SEXT [[OR]](s1) + ; CHECK: %8:_(s32) = G_OR %x_wide, %y_wide + ; CHECK: %7:_(s1) = G_TRUNC %8(s32) + ; CHECK: %logic_op:_(s64) = G_SEXT %7(s1) ; CHECK: $x0 = COPY %logic_op(s64) ; CHECK: RET_ReallyLR implicit $x0 %x_wide:_(s32) = COPY $w0 diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll index f9b98059be0b..06930388901b 100644 --- a/llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll +++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll @@ -1804,113 +1804,110 @@ define i24 @v_fshl_i24(i24 %lhs, i24 %rhs, i24 %amt) { define amdgpu_ps i48 @s_fshl_v2i24(i48 inreg %lhs.arg, i48 inreg %rhs.arg, i48 inreg %amt.arg) { ; GFX6-LABEL: s_fshl_v2i24: ; GFX6: ; %bb.0: +; GFX6-NEXT: v_cvt_f32_ubyte0_e32 v2, 24 +; GFX6-NEXT: v_rcp_iflag_f32_e32 v2, v2 ; GFX6-NEXT: s_lshr_b32 s6, s0, 16 -; GFX6-NEXT: s_lshr_b32 s7, s0, 24 -; GFX6-NEXT: s_and_b32 s9, s0, 0xff -; GFX6-NEXT: s_bfe_u32 s0, s0, 0x80008 -; GFX6-NEXT: v_cvt_f32_ubyte0_e32 v0, 24 -; GFX6-NEXT: s_lshl_b32 s0, s0, 8 +; GFX6-NEXT: s_lshr_b32 s7, s1, 8 +; GFX6-NEXT: s_bfe_u32 s9, s0, 0x80008 +; GFX6-NEXT: v_mul_f32_e32 v2, 0x4f7ffffe, v2 +; GFX6-NEXT: v_cvt_u32_f32_e32 v2, v2 +; GFX6-NEXT: s_and_b32 s8, s0, 0xff +; GFX6-NEXT: s_lshl_b32 s9, s9, 8 ; GFX6-NEXT: s_and_b32 s6, s6, 0xff -; GFX6-NEXT: v_rcp_iflag_f32_e32 v0, v0 -; GFX6-NEXT: s_or_b32 s0, s9, s0 +; GFX6-NEXT: s_and_b32 s1, s1, 0xff +; GFX6-NEXT: v_mov_b32_e32 v0, s0 +; GFX6-NEXT: s_and_b32 s0, s7, 0xff +; GFX6-NEXT: s_or_b32 s8, s8, s9 ; GFX6-NEXT: s_and_b32 s6, 0xffff, s6 -; GFX6-NEXT: s_lshr_b32 s8, s1, 8 +; GFX6-NEXT: v_alignbit_b32 v0, s1, v0, 24 ; GFX6-NEXT: s_and_b32 s0, 0xffff, s0 +; GFX6-NEXT: s_and_b32 s8, 0xffff, s8 ; GFX6-NEXT: s_lshl_b32 s6, s6, 16 +; GFX6-NEXT: v_and_b32_e32 v0, 0xffff, v0 +; GFX6-NEXT: s_lshl_b32 s0, s0, 16 +; GFX6-NEXT: v_mov_b32_e32 v3, 0xffffffe8 +; GFX6-NEXT: s_or_b32 s6, s8, s6 +; GFX6-NEXT: v_or_b32_e32 v0, s0, v0 +; GFX6-NEXT: s_lshr_b32 s0, s2, 16 +; GFX6-NEXT: s_lshr_b32 s1, s3, 8 +; GFX6-NEXT: s_bfe_u32 s8, s2, 0x80008 +; GFX6-NEXT: v_mul_lo_u32 v3, v2, v3 +; GFX6-NEXT: s_and_b32 s7, s2, 0xff +; GFX6-NEXT: s_lshl_b32 s8, s8, 8 +; GFX6-NEXT: s_and_b32 s0, s0, 0xff +; GFX6-NEXT: s_and_b32 s3, s3, 0xff +; GFX6-NEXT: v_mov_b32_e32 v1, s2 ; GFX6-NEXT: s_and_b32 s1, s1, 0xff -; GFX6-NEXT: s_or_b32 s0, s0, s6 -; GFX6-NEXT: s_lshl_b32 s1, s1, 8 -; GFX6-NEXT: s_and_b32 s6, s8, 0xff -; GFX6-NEXT: s_or_b32 s1, s7, s1 -; GFX6-NEXT: s_and_b32 s6, 0xffff, s6 -; GFX6-NEXT: v_mul_f32_e32 v0, 0x4f7ffffe, v0 +; GFX6-NEXT: s_or_b32 s7, s7, s8 +; GFX6-NEXT: s_and_b32 s0, 0xffff, s0 +; GFX6-NEXT: v_alignbit_b32 v1, s3, v1, 24 +; GFX6-NEXT: s_and_b32 s1, 0xffff, s1 +; GFX6-NEXT: s_and_b32 s7, 0xffff, s7 +; GFX6-NEXT: s_lshl_b32 s0, s0, 16 +; GFX6-NEXT: v_and_b32_e32 v1, 0xffff, v1 +; GFX6-NEXT: s_lshl_b32 s1, s1, 16 +; GFX6-NEXT: s_or_b32 s0, s7, s0 +; GFX6-NEXT: v_or_b32_e32 v1, s1, v1 +; GFX6-NEXT: s_lshr_b32 s1, s4, 16 +; GFX6-NEXT: s_bfe_u32 s7, s4, 0x80008 +; GFX6-NEXT: v_mul_hi_u32 v3, v2, v3 +; GFX6-NEXT: s_and_b32 s3, s4, 0xff +; GFX6-NEXT: s_lshl_b32 s7, s7, 8 +; GFX6-NEXT: s_and_b32 s1, s1, 0xff +; GFX6-NEXT: s_or_b32 s3, s3, s7 ; GFX6-NEXT: s_and_b32 s1, 0xffff, s1 -; GFX6-NEXT: s_lshl_b32 s6, s6, 16 -; GFX6-NEXT: v_cvt_u32_f32_e32 v0, v0 -; GFX6-NEXT: s_or_b32 s1, s1, s6 -; GFX6-NEXT: s_lshr_b32 s6, s2, 16 -; GFX6-NEXT: s_lshr_b32 s7, s2, 24 -; GFX6-NEXT: s_and_b32 s9, s2, 0xff -; GFX6-NEXT: s_bfe_u32 s2, s2, 0x80008 -; GFX6-NEXT: s_lshl_b32 s2, s2, 8 -; GFX6-NEXT: s_and_b32 s6, s6, 0xff -; GFX6-NEXT: s_or_b32 s2, s9, s2 -; GFX6-NEXT: s_and_b32 s6, 0xffff, s6 -; GFX6-NEXT: v_mov_b32_e32 v1, 0xffffffe8 -; GFX6-NEXT: s_lshr_b32 s8, s3, 8 -; GFX6-NEXT: s_and_b32 s2, 0xffff, s2 -; GFX6-NEXT: s_lshl_b32 s6, s6, 16 -; GFX6-NEXT: s_and_b32 s3, s3, 0xff -; GFX6-NEXT: v_mul_lo_u32 v1, v0, v1 -; GFX6-NEXT: s_or_b32 s2, s2, s6 -; GFX6-NEXT: s_lshl_b32 s3, s3, 8 -; GFX6-NEXT: s_and_b32 s6, s8, 0xff -; GFX6-NEXT: s_or_b32 s3, s7, s3 -; GFX6-NEXT: s_and_b32 s6, 0xffff, s6 ; GFX6-NEXT: s_and_b32 s3, 0xffff, s3 -; GFX6-NEXT: s_lshl_b32 s6, s6, 16 -; GFX6-NEXT: s_or_b32 s3, s3, s6 -; GFX6-NEXT: s_lshr_b32 s6, s4, 16 -; GFX6-NEXT: s_lshr_b32 s7, s4, 24 -; GFX6-NEXT: s_and_b32 s9, s4, 0xff -; GFX6-NEXT: s_bfe_u32 s4, s4, 0x80008 -; GFX6-NEXT: v_mul_hi_u32 v1, v0, v1 -; GFX6-NEXT: s_lshl_b32 s4, s4, 8 -; GFX6-NEXT: s_and_b32 s6, s6, 0xff -; GFX6-NEXT: s_or_b32 s4, s9, s4 -; GFX6-NEXT: s_and_b32 s6, 0xffff, s6 -; GFX6-NEXT: s_and_b32 s4, 0xffff, s4 -; GFX6-NEXT: s_lshl_b32 s6, s6, 16 -; GFX6-NEXT: s_or_b32 s4, s4, s6 -; GFX6-NEXT: v_add_i32_e32 v0, vcc, v0, v1 -; GFX6-NEXT: v_mul_hi_u32 v1, s4, v0 -; GFX6-NEXT: s_lshr_b32 s8, s5, 8 -; GFX6-NEXT: s_and_b32 s5, s5, 0xff -; GFX6-NEXT: s_lshl_b32 s5, s5, 8 -; GFX6-NEXT: v_mul_lo_u32 v1, v1, 24 -; GFX6-NEXT: s_and_b32 s6, s8, 0xff -; GFX6-NEXT: s_or_b32 s5, s7, s5 -; GFX6-NEXT: s_and_b32 s6, 0xffff, s6 -; GFX6-NEXT: s_and_b32 s5, 0xffff, s5 -; GFX6-NEXT: s_lshl_b32 s6, s6, 16 -; GFX6-NEXT: s_or_b32 s5, s5, s6 -; GFX6-NEXT: v_sub_i32_e32 v1, vcc, s4, v1 -; GFX6-NEXT: v_subrev_i32_e32 v2, vcc, 24, v1 -; GFX6-NEXT: v_mul_hi_u32 v0, s5, v0 -; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v1 -; GFX6-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc -; GFX6-NEXT: v_subrev_i32_e32 v2, vcc, 24, v1 -; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v1 -; GFX6-NEXT: v_mul_lo_u32 v0, v0, 24 -; GFX6-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc -; GFX6-NEXT: v_sub_i32_e32 v2, vcc, 23, v1 -; GFX6-NEXT: v_and_b32_e32 v1, 0xffffff, v1 -; GFX6-NEXT: v_lshl_b32_e32 v1, s0, v1 -; GFX6-NEXT: s_lshr_b32 s0, s2, 1 +; GFX6-NEXT: s_lshl_b32 s1, s1, 16 +; GFX6-NEXT: s_or_b32 s1, s3, s1 +; GFX6-NEXT: v_add_i32_e32 v2, vcc, v2, v3 +; GFX6-NEXT: v_mul_hi_u32 v3, s1, v2 +; GFX6-NEXT: s_lshr_b32 s2, s5, 8 +; GFX6-NEXT: s_and_b32 s3, s5, 0xff +; GFX6-NEXT: v_mov_b32_e32 v4, s4 +; GFX6-NEXT: s_and_b32 s2, s2, 0xff +; GFX6-NEXT: v_alignbit_b32 v4, s3, v4, 24 +; GFX6-NEXT: s_and_b32 s2, 0xffff, s2 +; GFX6-NEXT: v_and_b32_e32 v4, 0xffff, v4 +; GFX6-NEXT: v_mul_lo_u32 v3, v3, 24 +; GFX6-NEXT: s_lshl_b32 s2, s2, 16 +; GFX6-NEXT: v_or_b32_e32 v4, s2, v4 +; GFX6-NEXT: v_mul_hi_u32 v2, v4, v2 +; GFX6-NEXT: v_sub_i32_e32 v3, vcc, s1, v3 +; GFX6-NEXT: v_subrev_i32_e32 v5, vcc, 24, v3 +; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v3 +; GFX6-NEXT: v_mul_lo_u32 v2, v2, 24 +; GFX6-NEXT: v_cndmask_b32_e32 v3, v3, v5, vcc +; GFX6-NEXT: v_subrev_i32_e32 v5, vcc, 24, v3 +; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v3 +; GFX6-NEXT: v_cndmask_b32_e32 v3, v3, v5, vcc +; GFX6-NEXT: v_sub_i32_e32 v2, vcc, v4, v2 +; GFX6-NEXT: v_sub_i32_e32 v5, vcc, 23, v3 +; GFX6-NEXT: v_subrev_i32_e32 v4, vcc, 24, v2 +; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v2 +; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc +; GFX6-NEXT: v_subrev_i32_e32 v4, vcc, 24, v2 +; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v2 +; GFX6-NEXT: v_and_b32_e32 v3, 0xffffff, v3 +; GFX6-NEXT: s_lshr_b32 s0, s0, 1 +; GFX6-NEXT: v_and_b32_e32 v5, 0xffffff, v5 +; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc +; GFX6-NEXT: v_lshl_b32_e32 v3, s6, v3 +; GFX6-NEXT: v_lshr_b32_e32 v5, s0, v5 +; GFX6-NEXT: v_sub_i32_e32 v4, vcc, 23, v2 ; GFX6-NEXT: v_and_b32_e32 v2, 0xffffff, v2 -; GFX6-NEXT: v_lshr_b32_e32 v2, s0, v2 -; GFX6-NEXT: v_sub_i32_e32 v0, vcc, s5, v0 +; GFX6-NEXT: v_or_b32_e32 v3, v3, v5 +; GFX6-NEXT: v_lshlrev_b32_e32 v0, v2, v0 +; GFX6-NEXT: v_lshrrev_b32_e32 v1, 1, v1 +; GFX6-NEXT: v_and_b32_e32 v2, 0xffffff, v4 +; GFX6-NEXT: v_lshrrev_b32_e32 v1, v2, v1 +; GFX6-NEXT: v_bfe_u32 v2, v3, 8, 8 +; GFX6-NEXT: v_or_b32_e32 v0, v0, v1 +; GFX6-NEXT: v_and_b32_e32 v1, 0xff, v3 +; GFX6-NEXT: v_lshlrev_b32_e32 v2, 8, v2 +; GFX6-NEXT: v_or_b32_e32 v1, v1, v2 +; GFX6-NEXT: v_bfe_u32 v2, v3, 16, 8 +; GFX6-NEXT: v_lshlrev_b32_e32 v2, 16, v2 ; GFX6-NEXT: v_or_b32_e32 v1, v1, v2 -; GFX6-NEXT: v_subrev_i32_e32 v2, vcc, 24, v0 -; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v0 -; GFX6-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc -; GFX6-NEXT: v_subrev_i32_e32 v2, vcc, 24, v0 -; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v0 -; GFX6-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc -; GFX6-NEXT: v_sub_i32_e32 v2, vcc, 23, v0 -; GFX6-NEXT: v_and_b32_e32 v0, 0xffffff, v0 -; GFX6-NEXT: s_lshr_b32 s0, s3, 1 -; GFX6-NEXT: v_and_b32_e32 v2, 0xffffff, v2 -; GFX6-NEXT: v_lshl_b32_e32 v0, s1, v0 -; GFX6-NEXT: v_lshr_b32_e32 v2, s0, v2 -; GFX6-NEXT: v_bfe_u32 v3, v1, 8, 8 -; GFX6-NEXT: v_or_b32_e32 v0, v0, v2 -; GFX6-NEXT: v_and_b32_e32 v2, 0xff, v1 -; GFX6-NEXT: v_lshlrev_b32_e32 v3, 8, v3 -; GFX6-NEXT: v_bfe_u32 v1, v1, 16, 8 -; GFX6-NEXT: v_or_b32_e32 v2, v2, v3 -; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v1 -; GFX6-NEXT: v_or_b32_e32 v1, v2, v1 ; GFX6-NEXT: v_and_b32_e32 v2, 0xff, v0 ; GFX6-NEXT: v_lshlrev_b32_e32 v2, 24, v2 ; GFX6-NEXT: v_or_b32_e32 v1, v1, v2 diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll index c8455665e7b4..ff93cddafc87 100644 --- a/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll +++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll @@ -1815,113 +1815,110 @@ define i24 @v_fshr_i24(i24 %lhs, i24 %rhs, i24 %amt) { define amdgpu_ps i48 @s_fshr_v2i24(i48 inreg %lhs.arg, i48 inreg %rhs.arg, i48 inreg %amt.arg) { ; GFX6-LABEL: s_fshr_v2i24: ; GFX6: ; %bb.0: -; GFX6-NEXT: v_cvt_f32_ubyte0_e32 v0, 24 -; GFX6-NEXT: v_rcp_iflag_f32_e32 v0, v0 +; GFX6-NEXT: v_cvt_f32_ubyte0_e32 v2, 24 +; GFX6-NEXT: v_rcp_iflag_f32_e32 v2, v2 +; GFX6-NEXT: s_lshr_b32 s7, s1, 8 +; GFX6-NEXT: s_bfe_u32 s9, s0, 0x80008 +; GFX6-NEXT: s_and_b32 s1, s1, 0xff +; GFX6-NEXT: v_mul_f32_e32 v2, 0x4f7ffffe, v2 +; GFX6-NEXT: v_cvt_u32_f32_e32 v2, v2 +; GFX6-NEXT: v_mov_b32_e32 v0, s0 +; GFX6-NEXT: v_mov_b32_e32 v3, 0xffffffe8 ; GFX6-NEXT: s_lshr_b32 s6, s0, 16 -; GFX6-NEXT: s_lshr_b32 s7, s0, 24 -; GFX6-NEXT: s_lshr_b32 s8, s1, 8 -; GFX6-NEXT: s_and_b32 s9, s0, 0xff -; GFX6-NEXT: s_bfe_u32 s0, s0, 0x80008 +; GFX6-NEXT: s_and_b32 s8, s0, 0xff +; GFX6-NEXT: s_lshl_b32 s9, s9, 8 +; GFX6-NEXT: v_alignbit_b32 v0, s1, v0, 24 +; GFX6-NEXT: s_and_b32 s0, s7, 0xff +; GFX6-NEXT: s_lshr_b32 s1, s2, 16 +; GFX6-NEXT: s_lshr_b32 s7, s3, 8 +; GFX6-NEXT: s_bfe_u32 s10, s2, 0x80008 +; GFX6-NEXT: v_mul_lo_u32 v3, v2, v3 +; GFX6-NEXT: s_or_b32 s8, s8, s9 +; GFX6-NEXT: s_and_b32 s9, s2, 0xff +; GFX6-NEXT: s_lshl_b32 s10, s10, 8 ; GFX6-NEXT: s_and_b32 s1, s1, 0xff -; GFX6-NEXT: v_mul_f32_e32 v0, 0x4f7ffffe, v0 -; GFX6-NEXT: s_lshl_b32 s0, s0, 8 -; GFX6-NEXT: s_lshl_b32 s1, s1, 8 -; GFX6-NEXT: v_cvt_u32_f32_e32 v0, v0 -; GFX6-NEXT: s_or_b32 s0, s9, s0 -; GFX6-NEXT: s_or_b32 s1, s7, s1 -; GFX6-NEXT: s_and_b32 s7, s8, 0xff -; GFX6-NEXT: s_lshr_b32 s8, s2, 16 -; GFX6-NEXT: s_lshr_b32 s9, s2, 24 -; GFX6-NEXT: s_and_b32 s11, s2, 0xff -; GFX6-NEXT: s_bfe_u32 s2, s2, 0x80008 -; GFX6-NEXT: s_lshl_b32 s2, s2, 8 -; GFX6-NEXT: s_and_b32 s8, s8, 0xff -; GFX6-NEXT: s_or_b32 s2, s11, s2 -; GFX6-NEXT: s_and_b32 s8, 0xffff, s8 -; GFX6-NEXT: v_mov_b32_e32 v1, 0xffffffe8 -; GFX6-NEXT: s_lshr_b32 s10, s3, 8 +; GFX6-NEXT: s_and_b32 s3, s3, 0xff +; GFX6-NEXT: v_mov_b32_e32 v1, s2 +; GFX6-NEXT: s_and_b32 s2, s7, 0xff +; GFX6-NEXT: s_or_b32 s9, s9, s10 +; GFX6-NEXT: s_and_b32 s1, 0xffff, s1 +; GFX6-NEXT: v_alignbit_b32 v1, s3, v1, 24 +; GFX6-NEXT: s_and_b32 s2, 0xffff, s2 +; GFX6-NEXT: s_and_b32 s9, 0xffff, s9 +; GFX6-NEXT: s_lshl_b32 s1, s1, 16 +; GFX6-NEXT: v_and_b32_e32 v1, 0xffff, v1 +; GFX6-NEXT: s_lshl_b32 s2, s2, 16 +; GFX6-NEXT: s_or_b32 s1, s9, s1 +; GFX6-NEXT: v_or_b32_e32 v1, s2, v1 +; GFX6-NEXT: s_lshr_b32 s2, s4, 16 +; GFX6-NEXT: s_bfe_u32 s9, s4, 0x80008 +; GFX6-NEXT: v_mul_hi_u32 v3, v2, v3 +; GFX6-NEXT: s_and_b32 s7, s4, 0xff +; GFX6-NEXT: s_lshl_b32 s9, s9, 8 +; GFX6-NEXT: s_and_b32 s2, s2, 0xff +; GFX6-NEXT: s_or_b32 s7, s7, s9 ; GFX6-NEXT: s_and_b32 s2, 0xffff, s2 -; GFX6-NEXT: s_lshl_b32 s8, s8, 16 +; GFX6-NEXT: s_and_b32 s7, 0xffff, s7 +; GFX6-NEXT: s_lshl_b32 s2, s2, 16 +; GFX6-NEXT: s_or_b32 s2, s7, s2 +; GFX6-NEXT: v_add_i32_e32 v2, vcc, v2, v3 +; GFX6-NEXT: v_mul_hi_u32 v3, s2, v2 +; GFX6-NEXT: s_lshr_b32 s3, s5, 8 +; GFX6-NEXT: s_and_b32 s5, s5, 0xff +; GFX6-NEXT: v_mov_b32_e32 v4, s4 ; GFX6-NEXT: s_and_b32 s3, s3, 0xff -; GFX6-NEXT: v_mul_lo_u32 v1, v0, v1 -; GFX6-NEXT: s_or_b32 s2, s2, s8 -; GFX6-NEXT: s_lshl_b32 s3, s3, 8 -; GFX6-NEXT: s_and_b32 s8, s10, 0xff -; GFX6-NEXT: s_or_b32 s3, s9, s3 -; GFX6-NEXT: s_and_b32 s8, 0xffff, s8 +; GFX6-NEXT: v_alignbit_b32 v4, s5, v4, 24 ; GFX6-NEXT: s_and_b32 s3, 0xffff, s3 -; GFX6-NEXT: s_lshl_b32 s8, s8, 16 -; GFX6-NEXT: s_or_b32 s3, s3, s8 -; GFX6-NEXT: s_lshr_b32 s8, s4, 16 -; GFX6-NEXT: s_lshr_b32 s9, s4, 24 -; GFX6-NEXT: s_and_b32 s11, s4, 0xff -; GFX6-NEXT: s_bfe_u32 s4, s4, 0x80008 -; GFX6-NEXT: v_mul_hi_u32 v1, v0, v1 -; GFX6-NEXT: s_lshl_b32 s4, s4, 8 -; GFX6-NEXT: s_and_b32 s8, s8, 0xff -; GFX6-NEXT: s_or_b32 s4, s11, s4 -; GFX6-NEXT: s_and_b32 s8, 0xffff, s8 -; GFX6-NEXT: s_and_b32 s4, 0xffff, s4 -; GFX6-NEXT: s_lshl_b32 s8, s8, 16 -; GFX6-NEXT: s_or_b32 s4, s4, s8 -; GFX6-NEXT: v_add_i32_e32 v0, vcc, v0, v1 -; GFX6-NEXT: v_mul_hi_u32 v1, s4, v0 -; GFX6-NEXT: s_lshr_b32 s10, s5, 8 -; GFX6-NEXT: s_and_b32 s5, s5, 0xff -; GFX6-NEXT: s_lshl_b32 s5, s5, 8 -; GFX6-NEXT: v_mul_lo_u32 v1, v1, 24 -; GFX6-NEXT: s_and_b32 s8, s10, 0xff -; GFX6-NEXT: s_or_b32 s5, s9, s5 -; GFX6-NEXT: s_and_b32 s8, 0xffff, s8 -; GFX6-NEXT: s_and_b32 s5, 0xffff, s5 -; GFX6-NEXT: s_lshl_b32 s8, s8, 16 -; GFX6-NEXT: s_or_b32 s5, s5, s8 -; GFX6-NEXT: v_sub_i32_e32 v1, vcc, s4, v1 -; GFX6-NEXT: v_subrev_i32_e32 v2, vcc, 24, v1 -; GFX6-NEXT: v_mul_hi_u32 v0, s5, v0 -; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v1 -; GFX6-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc -; GFX6-NEXT: v_subrev_i32_e32 v2, vcc, 24, v1 +; GFX6-NEXT: v_and_b32_e32 v4, 0xffff, v4 +; GFX6-NEXT: v_mul_lo_u32 v3, v3, 24 +; GFX6-NEXT: s_lshl_b32 s3, s3, 16 +; GFX6-NEXT: v_or_b32_e32 v4, s3, v4 +; GFX6-NEXT: v_mul_hi_u32 v2, v4, v2 +; GFX6-NEXT: v_sub_i32_e32 v3, vcc, s2, v3 +; GFX6-NEXT: v_subrev_i32_e32 v5, vcc, 24, v3 +; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v3 +; GFX6-NEXT: v_mul_lo_u32 v2, v2, 24 +; GFX6-NEXT: v_cndmask_b32_e32 v3, v3, v5, vcc +; GFX6-NEXT: v_subrev_i32_e32 v5, vcc, 24, v3 +; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v3 +; GFX6-NEXT: v_cndmask_b32_e32 v3, v3, v5, vcc +; GFX6-NEXT: v_sub_i32_e32 v2, vcc, v4, v2 +; GFX6-NEXT: v_sub_i32_e32 v5, vcc, 23, v3 +; GFX6-NEXT: v_subrev_i32_e32 v4, vcc, 24, v2 +; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v2 ; GFX6-NEXT: s_and_b32 s6, s6, 0xff -; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v1 -; GFX6-NEXT: v_mul_lo_u32 v0, v0, 24 -; GFX6-NEXT: s_and_b32 s0, 0xffff, s0 +; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc +; GFX6-NEXT: s_and_b32 s8, 0xffff, s8 ; GFX6-NEXT: s_and_b32 s6, 0xffff, s6 -; GFX6-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc -; GFX6-NEXT: v_sub_i32_e32 v2, vcc, 23, v1 -; GFX6-NEXT: s_lshl_b32 s4, s6, 17 -; GFX6-NEXT: s_lshl_b32 s0, s0, 1 -; GFX6-NEXT: s_or_b32 s0, s4, s0 -; GFX6-NEXT: v_and_b32_e32 v2, 0xffffff, v2 -; GFX6-NEXT: v_and_b32_e32 v1, 0xffffff, v1 -; GFX6-NEXT: v_lshl_b32_e32 v2, s0, v2 -; GFX6-NEXT: v_lshr_b32_e32 v1, s2, v1 -; GFX6-NEXT: v_sub_i32_e32 v0, vcc, s5, v0 -; GFX6-NEXT: v_or_b32_e32 v1, v2, v1 -; GFX6-NEXT: v_subrev_i32_e32 v2, vcc, 24, v0 -; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v0 -; GFX6-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc -; GFX6-NEXT: v_subrev_i32_e32 v2, vcc, 24, v0 -; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v0 -; GFX6-NEXT: s_and_b32 s1, 0xffff, s1 -; GFX6-NEXT: s_and_b32 s7, 0xffff, s7 -; GFX6-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc -; GFX6-NEXT: v_sub_i32_e32 v2, vcc, 23, v0 -; GFX6-NEXT: s_lshl_b32 s0, s7, 17 -; GFX6-NEXT: s_lshl_b32 s1, s1, 1 -; GFX6-NEXT: s_or_b32 s0, s0, s1 +; GFX6-NEXT: v_subrev_i32_e32 v4, vcc, 24, v2 +; GFX6-NEXT: s_lshl_b32 s2, s6, 17 +; GFX6-NEXT: s_lshl_b32 s3, s8, 1 +; GFX6-NEXT: v_cmp_le_u32_e32 vcc, 24, v2 +; GFX6-NEXT: v_and_b32_e32 v0, 0xffff, v0 +; GFX6-NEXT: s_and_b32 s0, 0xffff, s0 +; GFX6-NEXT: s_or_b32 s2, s2, s3 +; GFX6-NEXT: v_and_b32_e32 v5, 0xffffff, v5 +; GFX6-NEXT: v_and_b32_e32 v3, 0xffffff, v3 +; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc +; GFX6-NEXT: v_lshl_b32_e32 v5, s2, v5 +; GFX6-NEXT: v_lshr_b32_e32 v3, s1, v3 +; GFX6-NEXT: v_sub_i32_e32 v4, vcc, 23, v2 +; GFX6-NEXT: s_lshl_b32 s0, s0, 17 +; GFX6-NEXT: v_lshlrev_b32_e32 v0, 1, v0 +; GFX6-NEXT: v_or_b32_e32 v3, v5, v3 +; GFX6-NEXT: v_or_b32_e32 v0, s0, v0 +; GFX6-NEXT: v_and_b32_e32 v4, 0xffffff, v4 ; GFX6-NEXT: v_and_b32_e32 v2, 0xffffff, v2 -; GFX6-NEXT: v_and_b32_e32 v0, 0xffffff, v0 -; GFX6-NEXT: v_lshl_b32_e32 v2, s0, v2 -; GFX6-NEXT: v_lshr_b32_e32 v0, s3, v0 -; GFX6-NEXT: v_bfe_u32 v3, v1, 8, 8 -; GFX6-NEXT: v_or_b32_e32 v0, v2, v0 -; GFX6-NEXT: v_and_b32_e32 v2, 0xff, v1 -; GFX6-NEXT: v_lshlrev_b32_e32 v3, 8, v3 -; GFX6-NEXT: v_bfe_u32 v1, v1, 16, 8 -; GFX6-NEXT: v_or_b32_e32 v2, v2, v3 -; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v1 -; GFX6-NEXT: v_or_b32_e32 v1, v2, v1 +; GFX6-NEXT: v_lshlrev_b32_e32 v0, v4, v0 +; GFX6-NEXT: v_lshrrev_b32_e32 v1, v2, v1 +; GFX6-NEXT: v_bfe_u32 v2, v3, 8, 8 +; GFX6-NEXT: v_or_b32_e32 v0, v0, v1 +; GFX6-NEXT: v_and_b32_e32 v1, 0xff, v3 +; GFX6-NEXT: v_lshlrev_b32_e32 v2, 8, v2 +; GFX6-NEXT: v_or_b32_e32 v1, v1, v2 +; GFX6-NEXT: v_bfe_u32 v2, v3, 16, 8 +; GFX6-NEXT: v_lshlrev_b32_e32 v2, 16, v2 +; GFX6-NEXT: v_or_b32_e32 v1, v1, v2 ; GFX6-NEXT: v_and_b32_e32 v2, 0xff, v0 ; GFX6-NEXT: v_lshlrev_b32_e32 v2, 24, v2 ; GFX6-NEXT: v_or_b32_e32 v1, v1, v2 diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll index 1821d29d4b05..788692c94b0c 100644 --- a/llvm/test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll +++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll @@ -192,9 +192,7 @@ define i16 @v_uaddsat_v2i8(i16 %lhs.arg, i16 %rhs.arg) { ; GFX6-NEXT: v_min_u32_e32 v2, v3, v2 ; GFX6-NEXT: v_add_i32_e32 v1, vcc, v1, v2 ; GFX6-NEXT: v_lshrrev_b32_e32 v1, 24, v1 -; GFX6-NEXT: v_lshrrev_b32_e32 v0, 24, v0 -; GFX6-NEXT: v_lshlrev_b32_e32 v1, 8, v1 -; GFX6-NEXT: v_or_b32_e32 v0, v0, v1 +; GFX6-NEXT: v_alignbit_b32 v0, v1, v0, 24 ; GFX6-NEXT: s_setpc_b64 s[30:31] ; ; GFX8-LABEL: v_uaddsat_v2i8: @@ -290,9 +288,9 @@ define amdgpu_ps i16 @s_uaddsat_v2i8(i16 inreg %lhs.arg, i16 inreg %rhs.arg) { ; GFX6-NEXT: s_min_u32 s2, s3, s2 ; GFX6-NEXT: s_add_i32 s1, s1, s2 ; GFX6-NEXT: s_lshr_b32 s1, s1, 24 -; GFX6-NEXT: s_lshr_b32 s0, s0, 24 -; GFX6-NEXT: s_lshl_b32 s1, s1, 8 -; GFX6-NEXT: s_or_b32 s0, s0, s1 +; GFX6-NEXT: v_mov_b32_e32 v0, s0 +; GFX6-NEXT: v_alignbit_b32 v0, s1, v0, 24 +; GFX6-NEXT: v_readfirstlane_b32 s0, v0 ; GFX6-NEXT: ; return to shader part epilog ; ; GFX8-LABEL: s_uaddsat_v2i8: diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/usubsat.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/usubsat.ll index a60370cd460f..0042d34e235d 100644 --- a/llvm/test/CodeGen/AMDGPU/GlobalISel/usubsat.ll +++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/usubsat.ll @@ -186,9 +186,7 @@ define i16 @v_usubsat_v2i8(i16 %lhs.arg, i16 %rhs.arg) { ; GFX6-NEXT: v_min_u32_e32 v2, v1, v2 ; GFX6-NEXT: v_sub_i32_e32 v1, vcc, v1, v2 ; GFX6-NEXT: v_lshrrev_b32_e32 v1, 24, v1 -; GFX6-NEXT: v_lshrrev_b32_e32 v0, 24, v0 -; GFX6-NEXT: v_lshlrev_b32_e32 v1, 8, v1 -; GFX6-NEXT: v_or_b32_e32 v0, v0, v1 +; GFX6-NEXT: v_alignbit_b32 v0, v1, v0, 24 ; GFX6-NEXT: s_setpc_b64 s[30:31] ; ; GFX8-LABEL: v_usubsat_v2i8: @@ -282,9 +280,9 @@ define amdgpu_ps i16 @s_usubsat_v2i8(i16 inreg %lhs.arg, i16 inreg %rhs.arg) { ; GFX6-NEXT: s_min_u32 s2, s1, s2 ; GFX6-NEXT: s_sub_i32 s1, s1, s2 ; GFX6-NEXT: s_lshr_b32 s1, s1, 24 -; GFX6-NEXT: s_lshr_b32 s0, s0, 24 -; GFX6-NEXT: s_lshl_b32 s1, s1, 8 -; GFX6-NEXT: s_or_b32 s0, s0, s1 +; GFX6-NEXT: v_mov_b32_e32 v0, s0 +; GFX6-NEXT: v_alignbit_b32 v0, s1, v0, 24 +; GFX6-NEXT: v_readfirstlane_b32 s0, v0 ; GFX6-NEXT: ; return to shader part epilog ; ; GFX8-LABEL: s_usubsat_v2i8: diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/xnor.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/xnor.ll index cec73b7c3617..6bb4e2d3dbe2 100644 --- a/llvm/test/CodeGen/AMDGPU/GlobalISel/xnor.ll +++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/xnor.ll @@ -26,13 +26,10 @@ entry: define amdgpu_ps i32 @scalar_xnor_v2i16_one_use(<2 x i16> inreg %a, <2 x i16> inreg %b) { ; GFX7-LABEL: scalar_xnor_v2i16_one_use: ; GFX7: ; %bb.0: ; %entry +; GFX7-NEXT: s_xor_b64 s[0:1], s[0:1], s[2:3] ; GFX7-NEXT: s_lshl_b32 s1, s1, 16 ; GFX7-NEXT: s_and_b32 s0, s0, 0xffff ; GFX7-NEXT: s_or_b32 s0, s1, s0 -; GFX7-NEXT: s_lshl_b32 s1, s3, 16 -; GFX7-NEXT: s_and_b32 s2, s2, 0xffff -; GFX7-NEXT: s_or_b32 s1, s1, s2 -; GFX7-NEXT: s_xor_b32 s0, s0, s1 ; GFX7-NEXT: s_xor_b32 s0, s0, -1 ; GFX7-NEXT: ; return to shader part epilog ; @@ -117,22 +114,17 @@ define amdgpu_ps i64 @scalar_xnor_i64_one_use(i64 inreg %a, i64 inreg %b) { define amdgpu_ps i64 @scalar_xnor_v4i16_one_use(<4 x i16> inreg %a, <4 x i16> inreg %b) { ; GFX7-LABEL: scalar_xnor_v4i16_one_use: ; GFX7: ; %bb.0: +; GFX7-NEXT: s_xor_b64 s[0:1], s[0:1], s[4:5] +; GFX7-NEXT: s_xor_b64 s[2:3], s[2:3], s[6:7] ; GFX7-NEXT: s_lshl_b32 s1, s1, 16 ; GFX7-NEXT: s_and_b32 s0, s0, 0xffff +; GFX7-NEXT: s_mov_b32 s8, -1 ; GFX7-NEXT: s_or_b32 s0, s1, s0 ; GFX7-NEXT: s_lshl_b32 s1, s3, 16 ; GFX7-NEXT: s_and_b32 s2, s2, 0xffff +; GFX7-NEXT: s_mov_b32 s9, s8 ; GFX7-NEXT: s_or_b32 s1, s1, s2 -; GFX7-NEXT: s_lshl_b32 s2, s5, 16 -; GFX7-NEXT: s_and_b32 s3, s4, 0xffff -; GFX7-NEXT: s_or_b32 s2, s2, s3 -; GFX7-NEXT: s_lshl_b32 s3, s7, 16 -; GFX7-NEXT: s_and_b32 s4, s6, 0xffff -; GFX7-NEXT: s_or_b32 s3, s3, s4 -; GFX7-NEXT: s_mov_b32 s4, -1 -; GFX7-NEXT: s_mov_b32 s5, s4 -; GFX7-NEXT: s_xor_b64 s[0:1], s[0:1], s[2:3] -; GFX7-NEXT: s_xor_b64 s[0:1], s[0:1], s[4:5] +; GFX7-NEXT: s_xor_b64 s[0:1], s[0:1], s[8:9] ; GFX7-NEXT: ; return to shader part epilog ; ; GFX8-LABEL: scalar_xnor_v4i16_one_use: -- GitLab From 718331f55529469586c99a55e4b382a1c7485842 Mon Sep 17 00:00:00 2001 From: hev Date: Mon, 3 Jun 2024 13:23:35 +0800 Subject: [PATCH 046/678] [LoongArch] Custom legalize i32 operations for LA64 to reduce signed extensions (#93811) --- .../LoongArch/LoongArchISelLowering.cpp | 20 +++++++++++++ .../Target/LoongArch/LoongArchInstrInfo.td | 5 +--- llvm/test/CodeGen/LoongArch/alsl.ll | 6 ++-- .../LoongArch/atomicrmw-uinc-udec-wrap.ll | 4 +-- .../CodeGen/LoongArch/ir-instruction/add.ll | 18 +++++++----- .../CodeGen/LoongArch/ir-instruction/and.ll | 2 +- .../CodeGen/LoongArch/ir-instruction/call.ll | 2 +- .../LoongArch/ir-instruction/load-store.ll | 4 +-- .../CodeGen/LoongArch/ir-instruction/sub.ll | 2 +- .../CodeGen/LoongArch/select-to-shiftand.ll | 5 ++-- llvm/test/CodeGen/LoongArch/sextw-removal.ll | 29 ++++++++++++------- 11 files changed, 63 insertions(+), 34 deletions(-) diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 8a87c82a205b..51384f25d245 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -121,6 +121,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM, // Set operations for LA64 only. if (Subtarget.is64Bit()) { + setOperationAction(ISD::ADD, MVT::i32, Custom); + setOperationAction(ISD::SUB, MVT::i32, Custom); setOperationAction(ISD::SHL, MVT::i32, Custom); setOperationAction(ISD::SRA, MVT::i32, Custom); setOperationAction(ISD::SRL, MVT::i32, Custom); @@ -1723,6 +1725,18 @@ static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp, return DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), NewRes); } +// Converts the given 32-bit operation to a i64 operation with signed extension +// semantic to reduce the signed extension instructions. +static SDValue customLegalizeToWOpWithSExt(SDNode *N, SelectionDAG &DAG) { + SDLoc DL(N); + SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0)); + SDValue NewOp1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1)); + SDValue NewWOp = DAG.getNode(N->getOpcode(), DL, MVT::i64, NewOp0, NewOp1); + SDValue NewRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, NewWOp, + DAG.getValueType(MVT::i32)); + return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, NewRes); +} + // Helper function that emits error message for intrinsics with/without chain // and return a UNDEF or and the chain as the results. static void emitErrorAndReplaceIntrinsicResults( @@ -1846,6 +1860,12 @@ void LoongArchTargetLowering::ReplaceNodeResults( switch (N->getOpcode()) { default: llvm_unreachable("Don't know how to legalize this operation"); + case ISD::ADD: + case ISD::SUB: + assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() && + "Unexpected custom legalisation"); + Results.push_back(customLegalizeToWOpWithSExt(N, DAG)); + break; case ISD::UDIV: case ISD::UREM: assert(VT == MVT::i32 && Subtarget.is64Bit() && diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td index 35ea9f07866d..66bd74e068b9 100644 --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -441,7 +441,7 @@ def simm16_lsl16 : Operand, // A 32-bit signed immediate expressible with a pair of `addu16i.d + addi` for // use in additions. def simm32_hi16_lo12: Operand, ImmLeaf(Imm - SignExtend64<12>(Imm)); + return !isInt<12>(Imm) && isShiftedInt<16, 16>(Imm - SignExtend64<12>(Imm)); }]>; def BareSymbol : AsmOperandClass { @@ -1106,11 +1106,8 @@ foreach Idx = 1...3 in { let Predicates = [IsLA64] in { def : PatGprGpr; -def : PatGprGpr_32; def : PatGprImm; -def : PatGprImm_32; def : PatGprGpr; -def : PatGprGpr_32; def : PatGprGpr; def : PatGprGpr_32; def : PatGprGpr; diff --git a/llvm/test/CodeGen/LoongArch/alsl.ll b/llvm/test/CodeGen/LoongArch/alsl.ll index 6db9a179d65d..34baccc60d54 100644 --- a/llvm/test/CodeGen/LoongArch/alsl.ll +++ b/llvm/test/CodeGen/LoongArch/alsl.ll @@ -42,7 +42,7 @@ define i32 @alsl_i32(i32 signext %a, i32 signext %b) nounwind { ; ; LA64-LABEL: alsl_i32: ; LA64: # %bb.0: # %entry -; LA64-NEXT: alsl.d $a0, $a0, $a1, 3 +; LA64-NEXT: alsl.w $a0, $a0, $a1, 3 ; LA64-NEXT: ret entry: %mul = mul nsw i32 %a, 8 @@ -178,7 +178,7 @@ define i32 @mul_add_i32(i32 signext %a, i32 signext %b) nounwind { ; LA64: # %bb.0: # %entry ; LA64-NEXT: slli.d $a2, $a0, 3 ; LA64-NEXT: alsl.d $a0, $a0, $a2, 2 -; LA64-NEXT: add.d $a0, $a1, $a0 +; LA64-NEXT: add.w $a0, $a1, $a0 ; LA64-NEXT: ret entry: %mul = mul nsw i32 %a, 12 @@ -325,7 +325,7 @@ define i32 @alsl_neg_i32(i32 signext %a, i32 signext %b) nounwind { ; LA64-LABEL: alsl_neg_i32: ; LA64: # %bb.0: # %entry ; LA64-NEXT: alsl.d $a0, $a0, $a0, 3 -; LA64-NEXT: sub.d $a0, $a1, $a0 +; LA64-NEXT: sub.w $a0, $a1, $a0 ; LA64-NEXT: ret entry: %mul = mul nsw i32 %a, -9 diff --git a/llvm/test/CodeGen/LoongArch/atomicrmw-uinc-udec-wrap.ll b/llvm/test/CodeGen/LoongArch/atomicrmw-uinc-udec-wrap.ll index 5ca6d8699135..854518ed1fc9 100644 --- a/llvm/test/CodeGen/LoongArch/atomicrmw-uinc-udec-wrap.ll +++ b/llvm/test/CodeGen/LoongArch/atomicrmw-uinc-udec-wrap.ll @@ -112,7 +112,7 @@ define i32 @atomicrmw_uinc_wrap_i32(ptr %ptr, i32 %val) { ; LA64-NEXT: # =>This Loop Header: Depth=1 ; LA64-NEXT: # Child Loop BB2_3 Depth 2 ; LA64-NEXT: move $a3, $a2 -; LA64-NEXT: addi.d $a2, $a2, 1 +; LA64-NEXT: addi.w $a2, $a2, 1 ; LA64-NEXT: sltu $a4, $a3, $a1 ; LA64-NEXT: xori $a4, $a4, 1 ; LA64-NEXT: masknez $a4, $a2, $a4 @@ -298,7 +298,7 @@ define i32 @atomicrmw_udec_wrap_i32(ptr %ptr, i32 %val) { ; LA64-NEXT: # =>This Loop Header: Depth=1 ; LA64-NEXT: # Child Loop BB6_3 Depth 2 ; LA64-NEXT: move $a4, $a2 -; LA64-NEXT: addi.d $a2, $a2, -1 +; LA64-NEXT: addi.w $a2, $a2, -1 ; LA64-NEXT: sltui $a5, $a4, 1 ; LA64-NEXT: sltu $a6, $a3, $a4 ; LA64-NEXT: masknez $a2, $a2, $a6 diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/add.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/add.ll index c10d4949438f..f156f8d6afce 100644 --- a/llvm/test/CodeGen/LoongArch/ir-instruction/add.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/add.ll @@ -54,7 +54,7 @@ define i32 @add_i32(i32 %x, i32 %y) { ; ; LA64-LABEL: add_i32: ; LA64: # %bb.0: -; LA64-NEXT: add.d $a0, $a0, $a1 +; LA64-NEXT: add.w $a0, $a0, $a1 ; LA64-NEXT: ret %add = add i32 %x, %y ret i32 %add @@ -144,7 +144,7 @@ define i32 @add_i32_3(i32 %x) { ; ; LA64-LABEL: add_i32_3: ; LA64: # %bb.0: -; LA64-NEXT: addi.d $a0, $a0, 3 +; LA64-NEXT: addi.w $a0, $a0, 3 ; LA64-NEXT: ret %add = add i32 %x, 3 ret i32 %add @@ -195,6 +195,7 @@ define i32 @add_i32_0x12340000(i32 %x) { ; LA64-LABEL: add_i32_0x12340000: ; LA64: # %bb.0: ; LA64-NEXT: addu16i.d $a0, $a0, 4660 +; LA64-NEXT: addi.w $a0, $a0, 0 ; LA64-NEXT: ret %add = add i32 %x, 305397760 ret i32 %add @@ -244,6 +245,7 @@ define i32 @add_i32_0x7fff0000(i32 %x) { ; LA64-LABEL: add_i32_0x7fff0000: ; LA64: # %bb.0: ; LA64-NEXT: addu16i.d $a0, $a0, 32767 +; LA64-NEXT: addi.w $a0, $a0, 0 ; LA64-NEXT: ret %add = add i32 %x, 2147418112 ret i32 %add @@ -293,6 +295,7 @@ define i32 @add_i32_minus_0x80000000(i32 %x) { ; LA64-LABEL: add_i32_minus_0x80000000: ; LA64: # %bb.0: ; LA64-NEXT: addu16i.d $a0, $a0, -32768 +; LA64-NEXT: addi.w $a0, $a0, 0 ; LA64-NEXT: ret %add = add i32 %x, -2147483648 ret i32 %add @@ -343,6 +346,7 @@ define i32 @add_i32_minus_0x10000(i32 %x) { ; LA64-LABEL: add_i32_minus_0x10000: ; LA64: # %bb.0: ; LA64-NEXT: addu16i.d $a0, $a0, -1 +; LA64-NEXT: addi.w $a0, $a0, 0 ; LA64-NEXT: ret %add = add i32 %x, -65536 ret i32 %add @@ -396,7 +400,7 @@ define i32 @add_i32_0x7fff07ff(i32 %x) { ; LA64-LABEL: add_i32_0x7fff07ff: ; LA64: # %bb.0: ; LA64-NEXT: addu16i.d $a0, $a0, 32767 -; LA64-NEXT: addi.d $a0, $a0, 2047 +; LA64-NEXT: addi.w $a0, $a0, 2047 ; LA64-NEXT: ret %add = add i32 %x, 2147420159 ret i32 %add @@ -450,7 +454,7 @@ define i32 @add_i32_0x7ffef800(i32 %x) { ; LA64-LABEL: add_i32_0x7ffef800: ; LA64: # %bb.0: ; LA64-NEXT: addu16i.d $a0, $a0, 32767 -; LA64-NEXT: addi.d $a0, $a0, -2048 +; LA64-NEXT: addi.w $a0, $a0, -2048 ; LA64-NEXT: ret %add = add i32 %x, 2147416064 ret i32 %add @@ -525,7 +529,7 @@ define i32 @add_i32_minus_0x23450679(i32 %x) { ; LA64-LABEL: add_i32_minus_0x23450679: ; LA64: # %bb.0: ; LA64-NEXT: addu16i.d $a0, $a0, -9029 -; LA64-NEXT: addi.d $a0, $a0, -1657 +; LA64-NEXT: addi.w $a0, $a0, -1657 ; LA64-NEXT: ret %add = add i32 %x, -591726201 ret i32 %add @@ -580,7 +584,7 @@ define i32 @add_i32_minus_0x2345fedd(i32 %x) { ; LA64-LABEL: add_i32_minus_0x2345fedd: ; LA64: # %bb.0: ; LA64-NEXT: addu16i.d $a0, $a0, -9030 -; LA64-NEXT: addi.d $a0, $a0, 291 +; LA64-NEXT: addi.w $a0, $a0, 291 ; LA64-NEXT: ret %add = add i32 %x, -591789789 ret i32 %add @@ -680,7 +684,7 @@ define i32 @add_i32_minus_0x80000800(i32 %x) { ; LA64: # %bb.0: ; LA64-NEXT: lu12i.w $a1, 524287 ; LA64-NEXT: ori $a1, $a1, 2048 -; LA64-NEXT: add.d $a0, $a0, $a1 +; LA64-NEXT: add.w $a0, $a0, $a1 ; LA64-NEXT: ret %add = add i32 %x, -2147485696 ret i32 %add diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll index 730d2609e64d..9f534439b4f5 100644 --- a/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll @@ -444,7 +444,7 @@ define i32 @and_add_lsr(i32 %x, i32 %y) { ; ; LA64-LABEL: and_add_lsr: ; LA64: # %bb.0: -; LA64-NEXT: addi.d $a0, $a0, -1 +; LA64-NEXT: addi.w $a0, $a0, -1 ; LA64-NEXT: bstrpick.d $a1, $a1, 31, 20 ; LA64-NEXT: and $a0, $a1, $a0 ; LA64-NEXT: ret diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll index 697f7f79aa00..e2d1c556aaf9 100644 --- a/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll @@ -34,7 +34,7 @@ define i32 @defined_function(i32 %a) nounwind { ; ; LA64-LABEL: defined_function: ; LA64: # %bb.0: -; LA64-NEXT: addi.d $a0, $a0, 1 +; LA64-NEXT: addi.w $a0, $a0, 1 ; LA64-NEXT: ret %1 = add i32 %a, 1 ret i32 %1 diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll index 1b3cda5547da..387d9333b90f 100644 --- a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll @@ -32,7 +32,7 @@ define i32 @load_store_global() nounwind { ; LA64NOPIC-NEXT: pcalau12i $a0, %pc_hi20(G) ; LA64NOPIC-NEXT: addi.d $a1, $a0, %pc_lo12(G) ; LA64NOPIC-NEXT: ld.w $a0, $a1, 0 -; LA64NOPIC-NEXT: addi.d $a0, $a0, 1 +; LA64NOPIC-NEXT: addi.w $a0, $a0, 1 ; LA64NOPIC-NEXT: st.w $a0, $a1, 0 ; LA64NOPIC-NEXT: ret ; @@ -41,7 +41,7 @@ define i32 @load_store_global() nounwind { ; LA64PIC-NEXT: pcalau12i $a0, %pc_hi20(.LG$local) ; LA64PIC-NEXT: addi.d $a1, $a0, %pc_lo12(.LG$local) ; LA64PIC-NEXT: ld.w $a0, $a1, 0 -; LA64PIC-NEXT: addi.d $a0, $a0, 1 +; LA64PIC-NEXT: addi.w $a0, $a0, 1 ; LA64PIC-NEXT: st.w $a0, $a1, 0 ; LA64PIC-NEXT: ret %v = load i32, ptr @G diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/sub.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/sub.ll index a593a66441b7..12543f857a19 100644 --- a/llvm/test/CodeGen/LoongArch/ir-instruction/sub.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/sub.ll @@ -54,7 +54,7 @@ define i32 @sub_i32(i32 %x, i32 %y) { ; ; LA64-LABEL: sub_i32: ; LA64: # %bb.0: -; LA64-NEXT: sub.d $a0, $a0, $a1 +; LA64-NEXT: sub.w $a0, $a0, $a1 ; LA64-NEXT: ret %sub = sub i32 %x, %y ret i32 %sub diff --git a/llvm/test/CodeGen/LoongArch/select-to-shiftand.ll b/llvm/test/CodeGen/LoongArch/select-to-shiftand.ll index a40e31c5d303..f95f1fb7df79 100644 --- a/llvm/test/CodeGen/LoongArch/select-to-shiftand.ll +++ b/llvm/test/CodeGen/LoongArch/select-to-shiftand.ll @@ -198,10 +198,9 @@ define i32 @sub_clamp_zero_i32(i32 signext %x, i32 signext %y) { ; ; LA64-LABEL: sub_clamp_zero_i32: ; LA64: # %bb.0: -; LA64-NEXT: sub.d $a2, $a0, $a1 ; LA64-NEXT: sub.w $a0, $a0, $a1 -; LA64-NEXT: srai.d $a0, $a0, 31 -; LA64-NEXT: andn $a0, $a2, $a0 +; LA64-NEXT: srai.d $a1, $a0, 31 +; LA64-NEXT: andn $a0, $a0, $a1 ; LA64-NEXT: ret %sub = sub nsw i32 %x, %y %cmp = icmp sgt i32 %sub, 0 diff --git a/llvm/test/CodeGen/LoongArch/sextw-removal.ll b/llvm/test/CodeGen/LoongArch/sextw-removal.ll index d95a5bd298f5..502b6cf88099 100644 --- a/llvm/test/CodeGen/LoongArch/sextw-removal.ll +++ b/llvm/test/CodeGen/LoongArch/sextw-removal.ll @@ -793,7 +793,9 @@ define signext i32 @test14(i32 signext %0, i32 signext %1) { ; NORMV-NEXT: blt $a4, $a5, .LBB13_5 ; NORMV-NEXT: # %bb.3: # in Loop: Header=BB13_2 Depth=1 ; NORMV-NEXT: add.d $a0, $a3, $a0 -; NORMV-NEXT: addi.w $a3, $a3, 1 +; NORMV-NEXT: addi.d $a3, $a3, 1 +; NORMV-NEXT: addi.w $a3, $a3, 0 +; NORMV-NEXT: addi.d $a0, $a0, 0 ; NORMV-NEXT: blt $a3, $a1, .LBB13_2 ; NORMV-NEXT: .LBB13_4: ; NORMV-NEXT: addi.w $a0, $a0, 0 @@ -861,7 +863,9 @@ define signext i32 @test14b(i32 %0, i32 signext %1) { ; NORMV-NEXT: blt $a4, $a5, .LBB14_5 ; NORMV-NEXT: # %bb.3: # in Loop: Header=BB14_2 Depth=1 ; NORMV-NEXT: add.d $a0, $a3, $a0 -; NORMV-NEXT: addi.w $a3, $a3, 1 +; NORMV-NEXT: addi.d $a3, $a3, 1 +; NORMV-NEXT: addi.w $a3, $a3, 0 +; NORMV-NEXT: addi.d $a0, $a0, 0 ; NORMV-NEXT: blt $a3, $a1, .LBB14_2 ; NORMV-NEXT: .LBB14_4: ; NORMV-NEXT: addi.w $a0, $a0, 0 @@ -929,7 +933,9 @@ define signext i32 @test14c(i32 zeroext %0, i32 signext %1) { ; NORMV-NEXT: blt $a4, $a5, .LBB15_5 ; NORMV-NEXT: # %bb.3: # in Loop: Header=BB15_2 Depth=1 ; NORMV-NEXT: add.d $a0, $a3, $a0 -; NORMV-NEXT: addi.w $a3, $a3, 1 +; NORMV-NEXT: addi.d $a3, $a3, 1 +; NORMV-NEXT: addi.w $a3, $a3, 0 +; NORMV-NEXT: addi.d $a0, $a0, 0 ; NORMV-NEXT: blt $a3, $a1, .LBB15_2 ; NORMV-NEXT: .LBB15_4: ; NORMV-NEXT: addi.w $a0, $a0, 0 @@ -996,7 +1002,9 @@ define signext i32 @test14d(i31 zeroext %0, i32 signext %1) { ; NORMV-NEXT: blt $a4, $a5, .LBB16_5 ; NORMV-NEXT: # %bb.3: # in Loop: Header=BB16_2 Depth=1 ; NORMV-NEXT: add.d $a0, $a3, $a0 -; NORMV-NEXT: addi.w $a3, $a3, 1 +; NORMV-NEXT: addi.d $a3, $a3, 1 +; NORMV-NEXT: addi.w $a3, $a3, 0 +; NORMV-NEXT: addi.d $a0, $a0, 0 ; NORMV-NEXT: blt $a3, $a1, .LBB16_2 ; NORMV-NEXT: .LBB16_4: ; NORMV-NEXT: addi.w $a0, $a0, 0 @@ -1122,8 +1130,8 @@ define signext i32 @bug(i32 signext %x) { ; CHECK-NEXT: masknez $a1, $a1, $a2 ; CHECK-NEXT: maskeqz $a2, $a4, $a2 ; CHECK-NEXT: or $a1, $a2, $a1 -; CHECK-NEXT: srai.d $a0, $a0, 31 ; CHECK-NEXT: nor $a0, $a0, $zero +; CHECK-NEXT: srli.d $a0, $a0, 31 ; CHECK-NEXT: add.w $a0, $a1, $a0 ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB18_2: @@ -1176,13 +1184,13 @@ define signext i32 @bug(i32 signext %x) { ; NORMV-NEXT: masknez $a1, $a1, $a2 ; NORMV-NEXT: maskeqz $a2, $a4, $a2 ; NORMV-NEXT: or $a1, $a2, $a1 -; NORMV-NEXT: srai.d $a0, $a0, 31 ; NORMV-NEXT: nor $a0, $a0, $zero +; NORMV-NEXT: srli.d $a0, $a0, 31 ; NORMV-NEXT: add.d $a0, $a1, $a0 ; NORMV-NEXT: addi.w $a0, $a0, 0 ; NORMV-NEXT: ret ; NORMV-NEXT: .LBB18_2: -; NORMV-NEXT: addi.w $a0, $zero, 0 +; NORMV-NEXT: move $a0, $zero ; NORMV-NEXT: ret entry: %tobool.not = icmp eq i32 %x, 0 @@ -1345,7 +1353,7 @@ declare zeroext i16 @bat(i32 signext) define signext i32 @sextw_sh2add(i1 zeroext %0, ptr %1, i32 signext %2, i32 signext %3, i32 signext %4) { ; CHECK-LABEL: sextw_sh2add: ; CHECK: # %bb.0: -; CHECK-NEXT: alsl.d $a2, $a2, $a3, 2 +; CHECK-NEXT: alsl.w $a2, $a2, $a3, 2 ; CHECK-NEXT: beqz $a0, .LBB21_2 ; CHECK-NEXT: # %bb.1: ; CHECK-NEXT: st.w $a2, $a1, 0 @@ -1355,12 +1363,13 @@ define signext i32 @sextw_sh2add(i1 zeroext %0, ptr %1, i32 signext %2, i32 sign ; ; NORMV-LABEL: sextw_sh2add: ; NORMV: # %bb.0: -; NORMV-NEXT: alsl.d $a2, $a2, $a3, 2 +; NORMV-NEXT: alsl.w $a2, $a2, $a3, 2 ; NORMV-NEXT: beqz $a0, .LBB21_2 ; NORMV-NEXT: # %bb.1: ; NORMV-NEXT: st.w $a2, $a1, 0 ; NORMV-NEXT: .LBB21_2: -; NORMV-NEXT: add.w $a0, $a2, $a4 +; NORMV-NEXT: add.d $a0, $a2, $a4 +; NORMV-NEXT: addi.w $a0, $a0, 0 ; NORMV-NEXT: ret %6 = shl i32 %2, 2 %7 = add i32 %6, %3 -- GitLab From f367eaa4647404414ab256d2ac3c4d4f6c6d1363 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sun, 2 Jun 2024 22:59:19 -0700 Subject: [PATCH 047/678] [memprof] Add accessors to Frame::SymbolName (#94085) This patch adds accessors to Frame::SymbolName so that we can change the underlying type of SymbolName without affecting downstream users once they switch to the new accessors. Note that SymbolName is only used for debugging. Changing the type of SymbolName from std::optional to std::unique_ptr cuts down sizeof(Frame) by half -- from 64 bytes to 32 bytes. (std::optional sets aside the storage in case T is instantiated.) During deserialization, the memory usage is dominated by Frames. Shrinking the type cuts down the memory usage and deserialization time nearly by half. --- llvm/include/llvm/ProfileData/MemProf.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/ProfileData/MemProf.h b/llvm/include/llvm/ProfileData/MemProf.h index 0e00b243c157..406144d9db1e 100644 --- a/llvm/include/llvm/ProfileData/MemProf.h +++ b/llvm/include/llvm/ProfileData/MemProf.h @@ -237,6 +237,17 @@ struct Frame { bool operator!=(const Frame &Other) const { return !operator==(Other); } + bool hasSymbolName() const { return SymbolName.has_value(); } + + StringRef getSymbolName() const { + assert(SymbolName.has_value()); + return *SymbolName; + } + + std::string getSymbolNameOr(StringRef Alt) const { + return std::string(hasSymbolName() ? getSymbolName() : Alt); + } + // Write the contents of the frame to the ostream \p OS. void serialize(raw_ostream &OS) const { using namespace support; @@ -279,7 +290,7 @@ struct Frame { void printYAML(raw_ostream &OS) const { OS << " -\n" << " Function: " << Function << "\n" - << " SymbolName: " << SymbolName.value_or("") << "\n" + << " SymbolName: " << getSymbolNameOr("") << "\n" << " LineOffset: " << LineOffset << "\n" << " Column: " << Column << "\n" << " Inline: " << IsInlineFrame << "\n"; -- GitLab From 10e7671d9adf1da2f08d67fde6585c707ac4c1d2 Mon Sep 17 00:00:00 2001 From: AtariDreams Date: Mon, 3 Jun 2024 02:24:54 -0400 Subject: [PATCH 048/678] Reland "[InstCombine] Fold (sub nuw X, (Y << nuw Z)) >>u exact Z --> (X >>u exact Z) sub nuw Y" (#93571) This is the same fold as ((X << nuw Z) sub nuw Y) >>u exact Z --> X sub nuw (Y >>u exact Z), but with the sub operands swapped. Alive2 Proof: https://alive2.llvm.org/ce/z/pT-RxG --- .../InstCombine/InstCombineShifts.cpp | 11 ++ llvm/test/Transforms/InstCombine/lshr.ll | 113 ++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index fbc02cddfb00..9ff817da7936 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -1275,6 +1275,17 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) { return NewSub; } + // (sub nuw X, (Y << nuw Z)) >>u exact Z --> (X >>u exact Z) sub nuw Y + if (I.isExact() && + match(Op0, m_OneUse(m_NUWSub(m_Value(X), + m_NUWShl(m_Value(Y), m_Specific(Op1)))))) { + Value *NewLshr = Builder.CreateLShr(X, Op1, "", /*isExact=*/true); + auto *NewSub = BinaryOperator::CreateNUWSub(NewLshr, Y); + NewSub->setHasNoSignedWrap( + cast(Op0)->hasNoSignedWrap()); + return NewSub; + } + auto isSuitableBinOpcode = [](Instruction::BinaryOps BinOpcode) { switch (BinOpcode) { default: diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll index 039276449094..60f03733ebd9 100644 --- a/llvm/test/Transforms/InstCombine/lshr.ll +++ b/llvm/test/Transforms/InstCombine/lshr.ll @@ -464,6 +464,119 @@ define i32 @shl_sub_lshr(i32 %x, i32 %c, i32 %y) { ret i32 %lshr } +define i32 @shl_sub_lshr_reverse(i32 %x, i32 %c, i32 %y) { +; CHECK-LABEL: @shl_sub_lshr_reverse( +; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[Y:%.*]], [[C:%.*]] +; CHECK-NEXT: [[LSHR:%.*]] = sub nuw nsw i32 [[TMP1]], [[X:%.*]] +; CHECK-NEXT: ret i32 [[LSHR]] +; + %shl = shl nuw i32 %x, %c + %sub = sub nuw nsw i32 %y, %shl + %lshr = lshr exact i32 %sub, %c + ret i32 %lshr +} + +define i32 @shl_sub_lshr_reverse_no_nsw(i32 %x, i32 %c, i32 %y) { +; CHECK-LABEL: @shl_sub_lshr_reverse_no_nsw( +; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[Y:%.*]], [[C:%.*]] +; CHECK-NEXT: [[LSHR:%.*]] = sub nuw i32 [[TMP1]], [[X:%.*]] +; CHECK-NEXT: ret i32 [[LSHR]] +; + %shl = shl nuw i32 %x, %c + %sub = sub nuw i32 %y, %shl + %lshr = lshr exact i32 %sub, %c + ret i32 %lshr +} + +define i32 @shl_sub_lshr_reverse_nsw_on_op1(i32 %x, i32 %c, i32 %y) { +; CHECK-LABEL: @shl_sub_lshr_reverse_nsw_on_op1( +; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[Y:%.*]], [[C:%.*]] +; CHECK-NEXT: [[LSHR:%.*]] = sub nuw i32 [[TMP1]], [[X:%.*]] +; CHECK-NEXT: ret i32 [[LSHR]] +; + %shl = shl nuw nsw i32 %x, %c + %sub = sub nuw i32 %y, %shl + %lshr = lshr exact i32 %sub, %c + ret i32 %lshr +} + +; Negative test + +define i32 @shl_sub_lshr_reverse_no_exact(i32 %x, i32 %c, i32 %y) { +; CHECK-LABEL: @shl_sub_lshr_reverse_no_exact( +; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[C:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[Y:%.*]], [[SHL]] +; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[SUB]], [[C]] +; CHECK-NEXT: ret i32 [[LSHR]] +; + %shl = shl nuw i32 %x, %c + %sub = sub nuw nsw i32 %y, %shl + %lshr = lshr i32 %sub, %c + ret i32 %lshr +} + +; Negative test + +define i32 @shl_sub_lshr_reverse_multiuse(i32 %x, i32 %c, i32 %y) { +; CHECK-LABEL: @shl_sub_lshr_reverse_multiuse( +; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[C:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[Y:%.*]], [[SHL]] +; CHECK-NEXT: call void @use(i32 [[SUB]]) +; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 [[SUB]], [[C]] +; CHECK-NEXT: ret i32 [[LSHR]] +; + %shl = shl nuw i32 %x, %c + %sub = sub nuw i32 %y, %shl + call void @use(i32 %sub) + %lshr = lshr exact i32 %sub, %c + ret i32 %lshr +} + +define i32 @shl_sub_lshr_reverse_multiuse2(i32 %x, i32 %c, i32 %y) { +; CHECK-LABEL: @shl_sub_lshr_reverse_multiuse2( +; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[C:%.*]] +; CHECK-NEXT: call void @use(i32 [[SHL]]) +; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[Y:%.*]], [[C]] +; CHECK-NEXT: [[LSHR:%.*]] = sub nuw i32 [[TMP1]], [[X]] +; CHECK-NEXT: ret i32 [[LSHR]] +; + %shl = shl nuw i32 %x, %c + call void @use(i32 %shl) + %sub = sub nuw i32 %y, %shl + %lshr = lshr exact i32 %sub, %c + ret i32 %lshr +} + +; Negative test + +define i32 @shl_sub_lshr_reverse_no_nuw(i32 %x, i32 %c, i32 %y) { +; CHECK-LABEL: @shl_sub_lshr_reverse_no_nuw( +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[C:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[Y:%.*]], [[SHL]] +; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 [[SUB]], [[C]] +; CHECK-NEXT: ret i32 [[LSHR]] +; + %shl = shl i32 %x, %c + %sub = sub nuw i32 %y, %shl + %lshr = lshr exact i32 %sub, %c + ret i32 %lshr +} + +; Negative test + +define i32 @shl_sub_lshr_reverse_no_nsw_2(i32 %x, i32 %c, i32 %y) { +; CHECK-LABEL: @shl_sub_lshr_reverse_no_nsw_2( +; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i32 [[X:%.*]], [[C:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y:%.*]], [[SHL]] +; CHECK-NEXT: [[LSHR:%.*]] = lshr exact i32 [[SUB]], [[C]] +; CHECK-NEXT: ret i32 [[LSHR]] +; + %shl = shl nuw nsw i32 %x, %c + %sub = sub i32 %y, %shl + %lshr = lshr exact i32 %sub, %c + ret i32 %lshr +} + define i32 @shl_or_lshr(i32 %x, i32 %c, i32 %y) { ; CHECK-LABEL: @shl_or_lshr( ; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]] -- GitLab From aaa4ff88d6a2ef69053211e7bbee623f24723b51 Mon Sep 17 00:00:00 2001 From: David Stone Date: Mon, 3 Jun 2024 00:49:04 -0600 Subject: [PATCH 049/678] [clang][Modules] Remove unnecessary includes of `Module.h` (#93417) --- .../clangd/unittests/ReplayPeambleTests.cpp | 10 +++++++--- clang/include/clang/APINotes/APINotesManager.h | 2 +- .../ExtractAPI/Serialization/SymbolGraphSerializer.h | 1 - clang/include/clang/Serialization/ASTWriter.h | 1 - clang/include/clang/Serialization/ModuleManager.h | 1 - clang/lib/APINotes/APINotesManager.cpp | 1 + clang/lib/AST/ASTDumper.cpp | 1 - clang/lib/CodeGen/CodeGenModule.h | 1 - clang/lib/ExtractAPI/API.cpp | 1 - .../header_exportable_declarations.cpp | 2 -- 10 files changed, 9 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/ReplayPeambleTests.cpp b/clang-tools-extra/clangd/unittests/ReplayPeambleTests.cpp index 147d9abe6913..32942e6bbfdc 100644 --- a/clang-tools-extra/clangd/unittests/ReplayPeambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/ReplayPeambleTests.cpp @@ -25,7 +25,6 @@ #include "clang/AST/DeclTemplate.h" #include "clang/Basic/FileEntry.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TokenKinds.h" @@ -42,7 +41,11 @@ #include #include -namespace clang::clangd { +namespace clang { + +class Module; + +namespace clangd { namespace { struct Inclusion { Inclusion(const SourceManager &SM, SourceLocation HashLoc, @@ -170,4 +173,5 @@ TEST(ReplayPreambleTest, IncludesAndSkippedFiles) { } } } // namespace -} // namespace clang::clangd +} // namespace clangd +} // namespace clang diff --git a/clang/include/clang/APINotes/APINotesManager.h b/clang/include/clang/APINotes/APINotesManager.h index 18375c9e51a1..98592438e90e 100644 --- a/clang/include/clang/APINotes/APINotesManager.h +++ b/clang/include/clang/APINotes/APINotesManager.h @@ -9,7 +9,6 @@ #ifndef LLVM_CLANG_APINOTES_APINOTESMANAGER_H #define LLVM_CLANG_APINOTES_APINOTESMANAGER_H -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -24,6 +23,7 @@ namespace clang { class DirectoryEntry; class FileEntry; class LangOptions; +class Module; class SourceManager; namespace api_notes { diff --git a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h index 27e9167ca1ad..f8759bf2d8f2 100644 --- a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h +++ b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h @@ -17,7 +17,6 @@ #ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H #define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H -#include "clang/Basic/Module.h" #include "clang/ExtractAPI/API.h" #include "clang/ExtractAPI/APIIgnoresList.h" #include "clang/ExtractAPI/Serialization/APISetVisitor.h" diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 88192e439a3f..fcc007d6f863 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -18,7 +18,6 @@ #include "clang/AST/Decl.h" #include "clang/AST/Type.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaConsumer.h" diff --git a/clang/include/clang/Serialization/ModuleManager.h b/clang/include/clang/Serialization/ModuleManager.h index 3bd379acf7ed..d770bc52eaf4 100644 --- a/clang/include/clang/Serialization/ModuleManager.h +++ b/clang/include/clang/Serialization/ModuleManager.h @@ -15,7 +15,6 @@ #define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H #include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Serialization/ModuleFile.h" #include "llvm/ADT/DenseMap.h" diff --git a/clang/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp index 789bb97d81de..039d09fa7cf5 100644 --- a/clang/lib/APINotes/APINotesManager.cpp +++ b/clang/lib/APINotes/APINotesManager.cpp @@ -12,6 +12,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceMgrAdapter.h" #include "clang/Basic/Version.h" diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index 6efc5bb92e28..c8973fdeda35 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -17,7 +17,6 @@ #include "clang/AST/DeclLookups.h" #include "clang/AST/JSONNodeDumper.h" #include "clang/Basic/Builtins.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/raw_ostream.h" diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 0f68418130ea..dc24971a3c18 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -24,7 +24,6 @@ #include "clang/AST/Mangle.h" #include "clang/Basic/ABI.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/Module.h" #include "clang/Basic/NoSanitizeList.h" #include "clang/Basic/ProfileList.h" #include "clang/Basic/TargetInfo.h" diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp index 96bef967d859..ab1108f663de 100644 --- a/clang/lib/ExtractAPI/API.cpp +++ b/clang/lib/ExtractAPI/API.cpp @@ -14,7 +14,6 @@ #include "clang/ExtractAPI/API.h" #include "clang/AST/RawCommentList.h" -#include "clang/Basic/Module.h" #include "clang/Index/USRGeneration.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" diff --git a/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp index 0a48f855fba0..6124bd30b19f 100644 --- a/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp +++ b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp @@ -9,8 +9,6 @@ #include "clang-tidy/ClangTidyCheck.h" #include "clang-tidy/ClangTidyModuleRegistry.h" -#include "clang/Basic/Module.h" - #include "llvm/ADT/ArrayRef.h" #include "header_exportable_declarations.hpp" -- GitLab From 5161a3f6e5e92c78c33aed5e38e0680a1a9b088e Mon Sep 17 00:00:00 2001 From: martinboehme Date: Mon, 3 Jun 2024 08:59:09 +0200 Subject: [PATCH 050/678] [clang][dataflow] Rewrite `getReferencedDecls()` with a `RecursiveASTVisitor`. (#93461) We previously had a hand-rolled recursive traversal here that was exactly what `RecursiveASTVistor` does anyway. Using the visitor not only eliminates the explicit traversal logic but also allows us to introduce a common visitor base class for `getReferencedDecls()` and `ResultObjectVisitor`, ensuring that the two are consistent in terms of the nodes they visit. Inconsistency between these two has caused crashes in the past when `ResultObjectVisitor` tried to propagate result object locations to entities that weren't modeled becasue `getReferencedDecls()` didn't visit them. --- .../clang/Analysis/FlowSensitive/ASTOps.h | 47 ++++++++ clang/lib/Analysis/FlowSensitive/ASTOps.cpp | 114 +++++++++--------- .../FlowSensitive/DataflowEnvironment.cpp | 37 +----- 3 files changed, 108 insertions(+), 90 deletions(-) diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h index 05748f300a93..925b99af9141 100644 --- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h +++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h @@ -15,6 +15,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/Analysis/FlowSensitive/StorageLocation.h" #include "llvm/ADT/DenseSet.h" @@ -80,6 +81,52 @@ private: std::optional ImplicitValueInitForUnion; }; +/// Specialization of `RecursiveASTVisitor` that visits those nodes that are +/// relevant to the dataflow analysis; generally, these are the ones that also +/// appear in the CFG. +/// To start the traversal, call `TraverseStmt()` on the statement or body of +/// the function to analyze. Don't call `TraverseDecl()` on the function itself; +/// this won't work as `TraverseDecl()` contains code to avoid traversing nested +/// functions. +template +class AnalysisASTVisitor : public RecursiveASTVisitor { +public: + bool shouldVisitImplicitCode() { return true; } + + bool shouldVisitLambdaBody() const { return false; } + + bool TraverseDecl(Decl *D) { + // Don't traverse nested record or function declarations. + // - We won't be analyzing code contained in these anyway + // - We don't model fields that are used only in these nested declaration, + // so trying to propagate a result object to initializers of such fields + // would cause an error. + if (isa_and_nonnull(D) || isa_and_nonnull(D)) + return true; + + return RecursiveASTVisitor::TraverseDecl(D); + } + + // Don't traverse expressions in unevaluated contexts, as we don't model + // fields that are only used in these. + // Note: The operand of the `noexcept` operator is an unevaluated operand, but + // nevertheless it appears in the Clang CFG, so we don't exclude it here. + bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; } + bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; } + bool TraverseCXXTypeidExpr(CXXTypeidExpr *) { return true; } + bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) { + return true; + } + + bool TraverseBindingDecl(BindingDecl *BD) { + // `RecursiveASTVisitor` doesn't traverse holding variables for + // `BindingDecl`s by itself, so we need to tell it to. + if (VarDecl *HoldingVar = BD->getHoldingVar()) + TraverseDecl(HoldingVar); + return RecursiveASTVisitor::TraverseBindingDecl(BD); + } +}; + /// A collection of several types of declarations, all referenced from the same /// function. struct ReferencedDecls { diff --git a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp index bd1676583ecc..38b5f51b7b2f 100644 --- a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp +++ b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp @@ -188,90 +188,96 @@ static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) { return nullptr; } -static void getReferencedDecls(const Decl &D, ReferencedDecls &Referenced) { - insertIfGlobal(D, Referenced.Globals); - insertIfFunction(D, Referenced.Functions); - if (const auto *Decomp = dyn_cast(&D)) - for (const auto *B : Decomp->bindings()) - if (auto *ME = dyn_cast_or_null(B->getBinding())) - // FIXME: should we be using `E->getFoundDecl()`? - if (const auto *FD = dyn_cast(ME->getMemberDecl())) - Referenced.Fields.insert(FD); -} +class ReferencedDeclsVisitor + : public AnalysisASTVisitor { +public: + ReferencedDeclsVisitor(ReferencedDecls &Referenced) + : Referenced(Referenced) {} + + void TraverseConstructorInits(const CXXConstructorDecl *Ctor) { + for (const CXXCtorInitializer *Init : Ctor->inits()) { + if (Init->isMemberInitializer()) { + Referenced.Fields.insert(Init->getMember()); + } else if (Init->isIndirectMemberInitializer()) { + for (const auto *I : Init->getIndirectMember()->chain()) + Referenced.Fields.insert(cast(I)); + } + + Expr *InitExpr = Init->getInit(); + + // Also collect declarations referenced in `InitExpr`. + TraverseStmt(InitExpr); -/// Traverses `S` and inserts into `Referenced` any declarations that are -/// declared in or referenced from sub-statements. -static void getReferencedDecls(const Stmt &S, ReferencedDecls &Referenced) { - for (auto *Child : S.children()) - if (Child != nullptr) - getReferencedDecls(*Child, Referenced); - if (const auto *DefaultArg = dyn_cast(&S)) - getReferencedDecls(*DefaultArg->getExpr(), Referenced); - if (const auto *DefaultInit = dyn_cast(&S)) - getReferencedDecls(*DefaultInit->getExpr(), Referenced); - - if (auto *DS = dyn_cast(&S)) { - if (DS->isSingleDecl()) - getReferencedDecls(*DS->getSingleDecl(), Referenced); - else - for (auto *D : DS->getDeclGroup()) - getReferencedDecls(*D, Referenced); - } else if (auto *E = dyn_cast(&S)) { + // If this is a `CXXDefaultInitExpr`, also collect declarations referenced + // within the default expression. + if (auto *DefaultInit = dyn_cast(InitExpr)) + TraverseStmt(DefaultInit->getExpr()); + } + } + + bool VisitDecl(Decl *D) { + insertIfGlobal(*D, Referenced.Globals); + insertIfFunction(*D, Referenced.Functions); + return true; + } + + bool VisitDeclRefExpr(DeclRefExpr *E) { insertIfGlobal(*E->getDecl(), Referenced.Globals); insertIfFunction(*E->getDecl(), Referenced.Functions); - } else if (const auto *C = dyn_cast(&S)) { + return true; + } + + bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) { // If this is a method that returns a member variable but does nothing else, // model the field of the return value. if (MemberExpr *E = getMemberForAccessor(*C)) if (const auto *FD = dyn_cast(E->getMemberDecl())) Referenced.Fields.insert(FD); - } else if (auto *E = dyn_cast(&S)) { + return true; + } + + bool VisitMemberExpr(MemberExpr *E) { // FIXME: should we be using `E->getFoundDecl()`? const ValueDecl *VD = E->getMemberDecl(); insertIfGlobal(*VD, Referenced.Globals); insertIfFunction(*VD, Referenced.Functions); if (const auto *FD = dyn_cast(VD)) Referenced.Fields.insert(FD); - } else if (auto *InitList = dyn_cast(&S)) { + return true; + } + + bool VisitInitListExpr(InitListExpr *InitList) { if (InitList->getType()->isRecordType()) for (const auto *FD : getFieldsForInitListExpr(InitList)) Referenced.Fields.insert(FD); - } else if (auto *ParenInitList = dyn_cast(&S)) { + return true; + } + + bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) { if (ParenInitList->getType()->isRecordType()) for (const auto *FD : getFieldsForInitListExpr(ParenInitList)) Referenced.Fields.insert(FD); + return true; } -} + +private: + ReferencedDecls &Referenced; +}; ReferencedDecls getReferencedDecls(const FunctionDecl &FD) { ReferencedDecls Result; - // Look for global variable and field references in the - // constructor-initializers. - if (const auto *CtorDecl = dyn_cast(&FD)) { - for (const auto *Init : CtorDecl->inits()) { - if (Init->isMemberInitializer()) { - Result.Fields.insert(Init->getMember()); - } else if (Init->isIndirectMemberInitializer()) { - for (const auto *I : Init->getIndirectMember()->chain()) - Result.Fields.insert(cast(I)); - } - const Expr *E = Init->getInit(); - assert(E != nullptr); - getReferencedDecls(*E, Result); - } - // Add all fields mentioned in default member initializers. - for (const FieldDecl *F : CtorDecl->getParent()->fields()) - if (const auto *I = F->getInClassInitializer()) - getReferencedDecls(*I, Result); - } - getReferencedDecls(*FD.getBody(), Result); + ReferencedDeclsVisitor Visitor(Result); + Visitor.TraverseStmt(FD.getBody()); + if (const auto *CtorDecl = dyn_cast(&FD)) + Visitor.TraverseConstructorInits(CtorDecl); return Result; } ReferencedDecls getReferencedDecls(const Stmt &S) { ReferencedDecls Result; - getReferencedDecls(S, Result); + ReferencedDeclsVisitor Visitor(Result); + Visitor.TraverseStmt(const_cast(&S)); return Result; } diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 338a85525b38..0d7967c8b934 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -297,7 +297,7 @@ namespace { // Visitor that builds a map from record prvalues to result objects. // For each result object that it encounters, it propagates the storage location // of the result object to all record prvalues that can initialize it. -class ResultObjectVisitor : public RecursiveASTVisitor { +class ResultObjectVisitor : public AnalysisASTVisitor { public: // `ResultObjectMap` will be filled with a map from record prvalues to result // object. If this visitor will traverse a function that returns a record by @@ -310,10 +310,6 @@ public: : ResultObjectMap(ResultObjectMap), LocForRecordReturnVal(LocForRecordReturnVal), DACtx(DACtx) {} - bool shouldVisitImplicitCode() { return true; } - - bool shouldVisitLambdaBody() const { return false; } - // Traverse all member and base initializers of `Ctor`. This function is not // called by `RecursiveASTVisitor`; it should be called manually if we are // analyzing a constructor. `ThisPointeeLoc` is the storage location that @@ -342,37 +338,6 @@ public: } } - bool TraverseDecl(Decl *D) { - // Don't traverse nested record or function declarations. - // - We won't be analyzing code contained in these anyway - // - We don't model fields that are used only in these nested declaration, - // so trying to propagate a result object to initializers of such fields - // would cause an error. - if (isa_and_nonnull(D) || isa_and_nonnull(D)) - return true; - - return RecursiveASTVisitor::TraverseDecl(D); - } - - // Don't traverse expressions in unevaluated contexts, as we don't model - // fields that are only used in these. - // Note: The operand of the `noexcept` operator is an unevaluated operand, but - // nevertheless it appears in the Clang CFG, so we don't exclude it here. - bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; } - bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; } - bool TraverseCXXTypeidExpr(CXXTypeidExpr *) { return true; } - bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) { - return true; - } - - bool TraverseBindingDecl(BindingDecl *BD) { - // `RecursiveASTVisitor` doesn't traverse holding variables for - // `BindingDecl`s by itself, so we need to tell it to. - if (VarDecl *HoldingVar = BD->getHoldingVar()) - TraverseDecl(HoldingVar); - return RecursiveASTVisitor::TraverseBindingDecl(BD); - } - bool VisitVarDecl(VarDecl *VD) { if (VD->getType()->isRecordType() && VD->hasInit()) PropagateResultObject( -- GitLab From a68638bf6a6a5cb60947753ccaf7d1de80f6c89e Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Mon, 3 Jun 2024 14:37:47 +0800 Subject: [PATCH 051/678] [C++20] [Modules] [Reduced BMI] Handling Deduction Guide in reduced BMI carefully Close https://github.com/llvm/llvm-project/issues/93859 The direct pattern of the issue is that, in a reduced BMI, we're going to wrtie a class but we didn't write the deduction guide. Although we handled deduction guide, but we tried to record the found deduction guide from `noload_lookup` directly. It is slightly problematic if the found deduction guide is from AST. e.g., ``` module; export module m; import xxx; // Also contains the class and the deduction guide ... ``` Then when we writes the class in the current file, we tried to record the deduction guide, but `noload_lookup` returns the deduction guide from the AST file then we didn't record the local deduction guide. Then mismatch happens. To mitiagte the problem, we tried to record the canonical declaration for the decution guide. --- clang/lib/Serialization/ASTWriterDecl.cpp | 2 +- clang/test/Modules/pr93859.cppm | 146 ++++++++++++++++++++++ 2 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 clang/test/Modules/pr93859.cppm diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index bbd16dbdb8ff..5a6ab4408eb2 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1733,7 +1733,7 @@ void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { if (Writer.isGeneratingReducedBMI()) { auto Name = Context.DeclarationNames.getCXXDeductionGuideName(D); for (auto *DG : D->getDeclContext()->noload_lookup(Name)) - Writer.GetDeclRef(DG); + Writer.GetDeclRef(DG->getCanonicalDecl()); } Code = serialization::DECL_CLASS_TEMPLATE; diff --git a/clang/test/Modules/pr93859.cppm b/clang/test/Modules/pr93859.cppm new file mode 100644 index 000000000000..d1d45bb97530 --- /dev/null +++ b/clang/test/Modules/pr93859.cppm @@ -0,0 +1,146 @@ +// Reduced from https://github.com/llvm/llvm-project/issues/93859 +// +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/reduced_std.cppm -emit-reduced-module-interface -o %t/reduced_std.pcm +// RUN: %clang_cc1 -std=c++20 %t/Misc.cppm -emit-reduced-module-interface -o %t/Misc.pcm \ +// RUN: -fprebuilt-module-path=%t +// RUN: %clang_cc1 -std=c++20 %t/Instance.cppm -emit-reduced-module-interface -o %t/Instance.pcm \ +// RUN: -fprebuilt-module-path=%t +// RUN: %clang_cc1 -std=c++20 %t/Device.cppm -emit-reduced-module-interface -o %t/Device.pcm \ +// RUN: -fprebuilt-module-path=%t +// RUN: %clang_cc1 -std=c++20 %t/Overlay.cppm -emit-reduced-module-interface -o %t/Overlay.pcm \ +// RUN: -fprebuilt-module-path=%t +// RUN: %clang_cc1 -std=c++20 %t/App.cppm -emit-module-interface -o /dev/null \ +// RUN: -fexperimental-modules-reduced-bmi -fmodule-output=%t/App.pcm \ +// RUN: -fprebuilt-module-path=%t +// RUN: %clang_cc1 -std=c++20 %t/test.cc -fsyntax-only -verify \ +// RUN: -fprebuilt-module-path=%t + +//--- header.h +namespace std { + +template +struct pair +{ + _T1 first; + _T2 second; + + constexpr pair() + : first(), second() {} + + constexpr pair(_T1 const& __t1, _T2 const& __t2) + : first(__t1), second(__t2) {} +}; + +template +pair(_T1, _T2) -> pair<_T1, _T2>; + +template +class __tree_const_iterator { +public: + template + friend class __tree; +}; + +template +class __tree { +public: + typedef _Tp value_type; + typedef __tree_const_iterator const_iterator; + + template + friend class map; +}; + +template +class set { +public: + typedef __tree<_Key> __base; + + typedef typename __base::const_iterator iterator; + + set() {} + + pair + insert(const _Key& __v); +}; + +template +inline constexpr _OutputIterator +copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { + return pair{__first, __last}.second; +} + +} + +//--- reduced_std.cppm +module; +#include "header.h" +export module reduced_std; + +export namespace std { + using std::set; + using std::copy; +} + +//--- Misc.cppm +export module Misc; +import reduced_std; + +export void check_result(int res) { + std::set extensions; + extensions.insert('f'); +} + +//--- Instance.cppm +export module Instance; +import reduced_std; + +export class Instance { +public: + Instance() { + std::set extensions; + extensions.insert("foo"); + } +}; + +//--- Device.cppm +export module Device; +import reduced_std; +import Instance; +import Misc; + +std::set wtf_set; + +//--- Overlay.cppm +export module Overlay; + +import reduced_std; +import Device; + +void overlay_vector_use() { + std::set nums; + nums.insert(1); +} + +//--- App.cppm +module; +#include "header.h" +export module App; +import Overlay; + +std::set fs; + +//--- test.cc +// expected-no-diagnostics +import reduced_std; +import App; + +void render() { + unsigned *oidxs = nullptr; + unsigned idxs[] = {0, 1, 2, 0, 2, 3}; + std::copy(idxs, idxs + 6, oidxs); +} -- GitLab From ef4c91c44311f96f174609219e126011ec085d1f Mon Sep 17 00:00:00 2001 From: David Green Date: Mon, 3 Jun 2024 08:23:14 +0100 Subject: [PATCH 052/678] [ARM] Rewrite vdiv_combine.ll test. NFC Instcombine will convert the fdiv by constant to fmul. This cleans up the vdiv_combine.ll test and adds fmul variants of the existing fdiv test. --- llvm/test/CodeGen/ARM/vdiv_combine.ll | 392 +++++++++++++++++++------- 1 file changed, 297 insertions(+), 95 deletions(-) diff --git a/llvm/test/CodeGen/ARM/vdiv_combine.ll b/llvm/test/CodeGen/ARM/vdiv_combine.ll index d71604dcb8ce..c8721e700a33 100644 --- a/llvm/test/CodeGen/ARM/vdiv_combine.ll +++ b/llvm/test/CodeGen/ARM/vdiv_combine.ll @@ -1,144 +1,174 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s -@in = global float 0x400921FA00000000, align 4 -@iin = global i32 -1023, align 4 -@uin = global i32 1023, align 4 - -declare void @foo_int32x4_t(<4 x i32>) - ; Test signed conversion. -; CHECK: t1 -; CHECK-NOT: {{vdiv|vmul}} -define void @t1() nounwind { +define arm_aapcs_vfpcc <2 x float> @t1(<2 x i32> %vecinit2.i) nounwind { +; CHECK-LABEL: t1: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 d0, d0, #3 +; CHECK-NEXT: bx lr entry: - %tmp = load i32, ptr @iin, align 4 - %vecinit.i = insertelement <2 x i32> undef, i32 %tmp, i32 0 - %vecinit2.i = insertelement <2 x i32> %vecinit.i, i32 %tmp, i32 1 %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> %div.i = fdiv <2 x float> %vcvt.i, - tail call void @foo_float32x2_t(<2 x float> %div.i) nounwind - ret void + ret <2 x float> %div.i } -declare void @foo_float32x2_t(<2 x float>) - ; Test unsigned conversion. -; CHECK: t2 -; CHECK-NOT: {{vdiv|vmul}} -define void @t2() nounwind { +define arm_aapcs_vfpcc <2 x float> @t2(<2 x i32> %vecinit2.i) nounwind { +; CHECK-LABEL: t2: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.u32 d0, d0, #3 +; CHECK-NEXT: bx lr entry: - %tmp = load i32, ptr @uin, align 4 - %vecinit.i = insertelement <2 x i32> undef, i32 %tmp, i32 0 - %vecinit2.i = insertelement <2 x i32> %vecinit.i, i32 %tmp, i32 1 %vcvt.i = uitofp <2 x i32> %vecinit2.i to <2 x float> %div.i = fdiv <2 x float> %vcvt.i, - tail call void @foo_float32x2_t(<2 x float> %div.i) nounwind - ret void + ret <2 x float> %div.i } ; Test which should not fold due to non-power of 2. -; CHECK: t3 -; CHECK: {{vdiv|vmul}} -define void @t3() nounwind { +define arm_aapcs_vfpcc <2 x float> @t3(<2 x i32> %vecinit2.i) nounwind { +; CHECK-LABEL: t3: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 d2, d0 +; CHECK-NEXT: vldr s2, LCPI2_0 +; CHECK-NEXT: vdiv.f32 s1, s5, s2 +; CHECK-NEXT: vdiv.f32 s0, s4, s2 +; CHECK-NEXT: bx lr +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: @ %bb.1: +; CHECK-NEXT: .data_region +; CHECK-NEXT: LCPI2_0: +; CHECK-NEXT: .long 0x40d9999a @ float 6.80000019 +; CHECK-NEXT: .end_data_region entry: - %tmp = load i32, ptr @iin, align 4 - %vecinit.i = insertelement <2 x i32> undef, i32 %tmp, i32 0 - %vecinit2.i = insertelement <2 x i32> %vecinit.i, i32 %tmp, i32 1 %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> %div.i = fdiv <2 x float> %vcvt.i, - tail call void @foo_float32x2_t(<2 x float> %div.i) nounwind - ret void + ret <2 x float> %div.i } ; Test which should not fold due to power of 2 out of range. -; CHECK: t4 -; CHECK: {{vdiv|vmul}} -define void @t4() nounwind { +define arm_aapcs_vfpcc <2 x float> @t4(<2 x i32> %vecinit2.i) nounwind { +; CHECK-LABEL: t4: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 d2, d0 +; CHECK-NEXT: vldr s2, LCPI3_0 +; CHECK-NEXT: vdiv.f32 s1, s5, s2 +; CHECK-NEXT: vdiv.f32 s0, s4, s2 +; CHECK-NEXT: bx lr +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: @ %bb.1: +; CHECK-NEXT: .data_region +; CHECK-NEXT: LCPI3_0: +; CHECK-NEXT: .long 0x50000000 @ float 8.58993459E+9 +; CHECK-NEXT: .end_data_region entry: - %tmp = load i32, ptr @iin, align 4 - %vecinit.i = insertelement <2 x i32> undef, i32 %tmp, i32 0 - %vecinit2.i = insertelement <2 x i32> %vecinit.i, i32 %tmp, i32 1 %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> %div.i = fdiv <2 x float> %vcvt.i, - tail call void @foo_float32x2_t(<2 x float> %div.i) nounwind - ret void + ret <2 x float> %div.i } ; Test case where const is max power of 2 (i.e., 2^32). -; CHECK: t5 -; CHECK-NOT: {{vdiv|vmul}} -define void @t5() nounwind { +define arm_aapcs_vfpcc <2 x float> @t5(<2 x i32> %vecinit2.i) nounwind { +; CHECK-LABEL: t5: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 d0, d0, #32 +; CHECK-NEXT: bx lr entry: - %tmp = load i32, ptr @iin, align 4 - %vecinit.i = insertelement <2 x i32> undef, i32 %tmp, i32 0 - %vecinit2.i = insertelement <2 x i32> %vecinit.i, i32 %tmp, i32 1 %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> %div.i = fdiv <2 x float> %vcvt.i, - tail call void @foo_float32x2_t(<2 x float> %div.i) nounwind - ret void + ret <2 x float> %div.i } ; Test quadword. -; CHECK: t6 -; CHECK-NOT: {{vdiv|vmul}} -define void @t6() nounwind { +define arm_aapcs_vfpcc <4 x float> @t6(<4 x i32> %vecinit6.i) nounwind { +; CHECK-LABEL: t6: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 q0, q0, #3 +; CHECK-NEXT: bx lr entry: - %tmp = load i32, ptr @iin, align 4 - %vecinit.i = insertelement <4 x i32> undef, i32 %tmp, i32 0 - %vecinit2.i = insertelement <4 x i32> %vecinit.i, i32 %tmp, i32 1 - %vecinit4.i = insertelement <4 x i32> %vecinit2.i, i32 %tmp, i32 2 - %vecinit6.i = insertelement <4 x i32> %vecinit4.i, i32 %tmp, i32 3 %vcvt.i = sitofp <4 x i32> %vecinit6.i to <4 x float> %div.i = fdiv <4 x float> %vcvt.i, - tail call void @foo_float32x4_t(<4 x float> %div.i) nounwind - ret void + ret <4 x float> %div.i } -declare void @foo_float32x4_t(<4 x float>) - -define <4 x float> @fix_unsigned_i16_to_float(<4 x i16> %in) { +define arm_aapcs_vfpcc <4 x float> @fix_unsigned_i16_to_float(<4 x i16> %in) { ; CHECK-LABEL: fix_unsigned_i16_to_float: -; CHECK: vmovl.u16 [[TMP:q[0-9]+]], {{d[0-9]+}} -; CHECK: vcvt.f32.u32 {{q[0-9]+}}, [[TMP]], #1 - - %conv = uitofp <4 x i16> %in to <4 x float> - %shift = fdiv <4 x float> %conv, - ret <4 x float> %shift +; CHECK: @ %bb.0: +; CHECK-NEXT: vmovl.u16 q8, d0 +; CHECK-NEXT: vcvt.f32.u32 q0, q8, #1 +; CHECK-NEXT: bx lr + %conv = uitofp <4 x i16> %in to <4 x float> + %shift = fdiv <4 x float> %conv, + ret <4 x float> %shift } -define <4 x float> @fix_signed_i16_to_float(<4 x i16> %in) { +define arm_aapcs_vfpcc <4 x float> @fix_signed_i16_to_float(<4 x i16> %in) { ; CHECK-LABEL: fix_signed_i16_to_float: -; CHECK: vmovl.s16 [[TMP:q[0-9]+]], {{d[0-9]+}} -; CHECK: vcvt.f32.s32 {{q[0-9]+}}, [[TMP]], #1 - - %conv = sitofp <4 x i16> %in to <4 x float> - %shift = fdiv <4 x float> %conv, - ret <4 x float> %shift +; CHECK: @ %bb.0: +; CHECK-NEXT: vmovl.s16 q8, d0 +; CHECK-NEXT: vcvt.f32.s32 q0, q8, #1 +; CHECK-NEXT: bx lr + %conv = sitofp <4 x i16> %in to <4 x float> + %shift = fdiv <4 x float> %conv, + ret <4 x float> %shift } -define <2 x float> @fix_i64_to_float(<2 x i64> %in) { +define arm_aapcs_vfpcc <2 x float> @fix_i64_to_float(<2 x i64> %in) { ; CHECK-LABEL: fix_i64_to_float: -; CHECK: bl -; CHECK: bl - - %conv = uitofp <2 x i64> %in to <2 x float> - %shift = fdiv <2 x float> %conv, - ret <2 x float> %shift +; CHECK: @ %bb.0: +; CHECK-NEXT: push {lr} +; CHECK-NEXT: vpush {d8, d9} +; CHECK-NEXT: vorr q4, q0, q0 +; CHECK-NEXT: vmov r0, r1, d9 +; CHECK-NEXT: bl ___floatundisf +; CHECK-NEXT: vmov r2, r1, d8 +; CHECK-NEXT: vmov s18, r0 +; CHECK-NEXT: vmov.f32 s16, #2.000000e+00 +; CHECK-NEXT: mov r0, r2 +; CHECK-NEXT: bl ___floatundisf +; CHECK-NEXT: vmov s2, r0 +; CHECK-NEXT: vdiv.f32 s1, s18, s16 +; CHECK-NEXT: vdiv.f32 s0, s2, s16 +; CHECK-NEXT: vpop {d8, d9} +; CHECK-NEXT: pop {lr} +; CHECK-NEXT: bx lr + %conv = uitofp <2 x i64> %in to <2 x float> + %shift = fdiv <2 x float> %conv, + ret <2 x float> %shift } -define <2 x double> @fix_i64_to_double(<2 x i64> %in) { +define arm_aapcs_vfpcc <2 x double> @fix_i64_to_double(<2 x i64> %in) { ; CHECK-LABEL: fix_i64_to_double: -; CHECK: bl -; CHECK: bl - - %conv = uitofp <2 x i64> %in to <2 x double> - %shift = fdiv <2 x double> %conv, - ret <2 x double> %shift +; CHECK: @ %bb.0: +; CHECK-NEXT: push {lr} +; CHECK-NEXT: vpush {d8, d9} +; CHECK-NEXT: vorr q4, q0, q0 +; CHECK-NEXT: vmov r0, r1, d9 +; CHECK-NEXT: bl ___floatundidf +; CHECK-NEXT: vmov r2, r3, d8 +; CHECK-NEXT: vmov d9, r0, r1 +; CHECK-NEXT: vmov.f64 d8, #2.000000e+00 +; CHECK-NEXT: mov r0, r2 +; CHECK-NEXT: mov r1, r3 +; CHECK-NEXT: bl ___floatundidf +; CHECK-NEXT: vmov d16, r0, r1 +; CHECK-NEXT: vdiv.f64 d1, d9, d8 +; CHECK-NEXT: vdiv.f64 d0, d16, d8 +; CHECK-NEXT: vpop {d8, d9} +; CHECK-NEXT: pop {lr} +; CHECK-NEXT: bx lr + %conv = uitofp <2 x i64> %in to <2 x double> + %shift = fdiv <2 x double> %conv, + ret <2 x double> %shift } ; Don't combine with 8 lanes. Just make sure things don't crash. -; CHECK-LABEL: test7 -define <8 x float> @test7(<8 x i32> %in) nounwind { +define arm_aapcs_vfpcc <8 x float> @test7(<8 x i32> %in) nounwind { +; CHECK-LABEL: test7: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 q0, q0, #3 +; CHECK-NEXT: vcvt.f32.s32 q1, q1, #3 +; CHECK-NEXT: bx lr entry: %vcvt.i = sitofp <8 x i32> %in to <8 x float> %div.i = fdiv <8 x float> %vcvt.i, @@ -146,18 +176,190 @@ entry: } ; Can combine splat with an undef. -; CHECK-LABEL: test8 -; CHECK: vcvt.f32.s32 q{{[0-9]+}}, q{{[0-9]+}}, #1 -define <4 x float> @test8(<4 x i32> %in) { +define arm_aapcs_vfpcc <4 x float> @test8(<4 x i32> %in) { +; CHECK-LABEL: test8: +; CHECK: @ %bb.0: +; CHECK-NEXT: vcvt.f32.s32 q0, q0, #1 +; CHECK-NEXT: bx lr %vcvt.i = sitofp <4 x i32> %in to <4 x float> %div.i = fdiv <4 x float> %vcvt.i, ret <4 x float> %div.i } +define arm_aapcs_vfpcc <3 x float> @test_illegal_int_to_fp(<3 x i32> %in) { ; CHECK-LABEL: test_illegal_int_to_fp: -; CHECK: vcvt.f32.s32 -define <3 x float> @test_illegal_int_to_fp(<3 x i32> %in) { +; CHECK: @ %bb.0: +; CHECK-NEXT: vcvt.f32.s32 q0, q0, #2 +; CHECK-NEXT: bx lr %conv = sitofp <3 x i32> %in to <3 x float> %res = fdiv <3 x float> %conv, ret <3 x float> %res } + + +define arm_aapcs_vfpcc <2 x float> @t1_mul(<2 x i32> %vecinit2.i) local_unnamed_addr #0 { +; CHECK-LABEL: t1_mul: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 d16, d0 +; CHECK-NEXT: vmov.i32 d17, #0x3e000000 +; CHECK-NEXT: vmul.f32 d0, d16, d17 +; CHECK-NEXT: bx lr +entry: + %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> + %div.i = fmul <2 x float> %vcvt.i, + ret <2 x float> %div.i +} + +define arm_aapcs_vfpcc <2 x float> @t2_mul(<2 x i32> %vecinit2.i) local_unnamed_addr #0 { +; CHECK-LABEL: t2_mul: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.u32 d16, d0 +; CHECK-NEXT: vmov.i32 d17, #0x3e000000 +; CHECK-NEXT: vmul.f32 d0, d16, d17 +; CHECK-NEXT: bx lr +entry: + %vcvt.i = uitofp <2 x i32> %vecinit2.i to <2 x float> + %div.i = fmul <2 x float> %vcvt.i, + ret <2 x float> %div.i +} + +define arm_aapcs_vfpcc <2 x float> @t4_mul(<2 x i32> %vecinit2.i) local_unnamed_addr #0 { +; CHECK-LABEL: t4_mul: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 d16, d0 +; CHECK-NEXT: vmov.i32 d17, #0x2f000000 +; CHECK-NEXT: vmul.f32 d0, d16, d17 +; CHECK-NEXT: bx lr +entry: + %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> + %div.i = fmul <2 x float> %vcvt.i, + ret <2 x float> %div.i +} + +define arm_aapcs_vfpcc <2 x float> @t5_mul(<2 x i32> %vecinit2.i) local_unnamed_addr #0 { +; CHECK-LABEL: t5_mul: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 d16, d0 +; CHECK-NEXT: mov r0, #796917760 +; CHECK-NEXT: vdup.32 d17, r0 +; CHECK-NEXT: vmul.f32 d0, d16, d17 +; CHECK-NEXT: bx lr +entry: + %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> + %div.i = fmul <2 x float> %vcvt.i, + ret <2 x float> %div.i +} + +define arm_aapcs_vfpcc <4 x float> @t6_mul(<4 x i32> %vecinit6.i) local_unnamed_addr #0 { +; CHECK-LABEL: t6_mul: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 q8, q0 +; CHECK-NEXT: vmov.i32 q9, #0x3e000000 +; CHECK-NEXT: vmul.f32 q0, q8, q9 +; CHECK-NEXT: bx lr +entry: + %vcvt.i = sitofp <4 x i32> %vecinit6.i to <4 x float> + %div.i = fmul <4 x float> %vcvt.i, + ret <4 x float> %div.i +} + +define arm_aapcs_vfpcc <4 x float> @fix_unsigned_i16_to_float_mul(<4 x i16> %in) local_unnamed_addr #0 { +; CHECK-LABEL: fix_unsigned_i16_to_float_mul: +; CHECK: @ %bb.0: +; CHECK-NEXT: vmovl.u16 q8, d0 +; CHECK-NEXT: vmov.i32 q9, #0x3f000000 +; CHECK-NEXT: vcvt.f32.u32 q8, q8 +; CHECK-NEXT: vmul.f32 q0, q8, q9 +; CHECK-NEXT: bx lr + %conv = uitofp <4 x i16> %in to <4 x float> + %shift = fmul <4 x float> %conv, + ret <4 x float> %shift +} + +define arm_aapcs_vfpcc <4 x float> @fix_signed_i16_to_float_mul(<4 x i16> %in) local_unnamed_addr #0 { +; CHECK-LABEL: fix_signed_i16_to_float_mul: +; CHECK: @ %bb.0: +; CHECK-NEXT: vmovl.s16 q8, d0 +; CHECK-NEXT: vmov.i32 q9, #0x3f000000 +; CHECK-NEXT: vcvt.f32.s32 q8, q8 +; CHECK-NEXT: vmul.f32 q0, q8, q9 +; CHECK-NEXT: bx lr + %conv = sitofp <4 x i16> %in to <4 x float> + %shift = fmul <4 x float> %conv, + ret <4 x float> %shift +} + +define arm_aapcs_vfpcc <2 x float> @fix_i64_to_float_mul(<2 x i64> %in) local_unnamed_addr #0 { +; CHECK-LABEL: fix_i64_to_float_mul: +; CHECK: @ %bb.0: +; CHECK-NEXT: push {lr} +; CHECK-NEXT: vpush {d8, d9} +; CHECK-NEXT: vorr q4, q0, q0 +; CHECK-NEXT: vmov r0, r1, d9 +; CHECK-NEXT: bl ___floatundisf +; CHECK-NEXT: vmov r2, r1, d8 +; CHECK-NEXT: vmov s19, r0 +; CHECK-NEXT: vmov.i32 d8, #0x3f000000 +; CHECK-NEXT: mov r0, r2 +; CHECK-NEXT: bl ___floatundisf +; CHECK-NEXT: vmov s18, r0 +; CHECK-NEXT: vmul.f32 d0, d9, d8 +; CHECK-NEXT: vpop {d8, d9} +; CHECK-NEXT: pop {lr} +; CHECK-NEXT: bx lr + %conv = uitofp <2 x i64> %in to <2 x float> + %shift = fmul <2 x float> %conv, + ret <2 x float> %shift +} + +define arm_aapcs_vfpcc <2 x double> @fix_i64_to_double_mul(<2 x i64> %in) local_unnamed_addr #0 { +; CHECK-LABEL: fix_i64_to_double_mul: +; CHECK: @ %bb.0: +; CHECK-NEXT: push {lr} +; CHECK-NEXT: vpush {d8, d9} +; CHECK-NEXT: vorr q4, q0, q0 +; CHECK-NEXT: vmov r0, r1, d9 +; CHECK-NEXT: bl ___floatundidf +; CHECK-NEXT: vmov r2, r3, d8 +; CHECK-NEXT: vmov d9, r0, r1 +; CHECK-NEXT: vmov.f64 d8, #5.000000e-01 +; CHECK-NEXT: mov r0, r2 +; CHECK-NEXT: mov r1, r3 +; CHECK-NEXT: bl ___floatundidf +; CHECK-NEXT: vmov d16, r0, r1 +; CHECK-NEXT: vmul.f64 d1, d9, d8 +; CHECK-NEXT: vmul.f64 d0, d16, d8 +; CHECK-NEXT: vpop {d8, d9} +; CHECK-NEXT: pop {lr} +; CHECK-NEXT: bx lr + %conv = uitofp <2 x i64> %in to <2 x double> + %shift = fmul <2 x double> %conv, + ret <2 x double> %shift +} + +define arm_aapcs_vfpcc <8 x float> @test7_mul(<8 x i32> %in) local_unnamed_addr #0 { +; CHECK-LABEL: test7_mul: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vcvt.f32.s32 q8, q0 +; CHECK-NEXT: vcvt.f32.s32 q9, q1 +; CHECK-NEXT: vmov.i32 q10, #0x3e000000 +; CHECK-NEXT: vmul.f32 q0, q8, q10 +; CHECK-NEXT: vmul.f32 q1, q9, q10 +; CHECK-NEXT: bx lr +entry: + %vcvt.i = sitofp <8 x i32> %in to <8 x float> + %div.i = fmul <8 x float> %vcvt.i, + ret <8 x float> %div.i +} + +define arm_aapcs_vfpcc <3 x float> @test_illegal_int_to_fp_mul(<3 x i32> %in) local_unnamed_addr #0 { +; CHECK-LABEL: test_illegal_int_to_fp_mul: +; CHECK: @ %bb.0: +; CHECK-NEXT: vcvt.f32.s32 q8, q0 +; CHECK-NEXT: vmov.f32 q9, #2.500000e-01 +; CHECK-NEXT: vmul.f32 q0, q8, q9 +; CHECK-NEXT: bx lr + %conv = sitofp <3 x i32> %in to <3 x float> + %res = fmul <3 x float> %conv, + ret <3 x float> %res +} -- GitLab From 12c85cd31088f64a1afbc5b2133dde2e1d2516d3 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 3 Jun 2024 09:22:25 +0200 Subject: [PATCH 053/678] [bazel]: port for the libc change 142afde0eba4940f2b331274e9a3535fee960f35 --- .../llvm-project-overlay/libc/BUILD.bazel | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 1f7a2f8a9f9f..30044f8bdce7 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -174,6 +174,11 @@ libc_support_library( hdrs = ["hdr/types/time_t.h"], ) +libc_support_library( + name = "types_pid_t", + hdrs = ["hdr/types/pid_t.h"], +) + ############################### Support libraries ############################## libc_support_library( @@ -1146,6 +1151,33 @@ libc_support_library( ], ) +libc_support_library( + name = "__support_threads_sleep", + hdrs = ["src/__support/threads/sleep.h"], +) + +libc_support_library( + name = "__support_threads_raw_mutex", + hdrs = [ + "src/__support/threads/linux/raw_mutex.h", + ], + defines = [ + "LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY", + "LIBC_COPT_RAW_MUTEX_DEFAULT_SPIN_COUNT" + ], + target_compatible_with = select({ + "@platforms//os:linux": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + deps = [ + ":__support_cpp_optional", + ":__support_time_linux", + ":__support_threads_linux_futex_utils", + ":__support_threads_sleep", + ":types_pid_t", + ], +) + libc_support_library( name = "__support_threads_mutex", hdrs = [ @@ -1163,6 +1195,8 @@ libc_support_library( ":__support_cpp_atomic", ":__support_osutil_syscall", ":__support_threads_linux_futex_utils", + ":__support_threads_raw_mutex", + ":types_pid_t", ], ) -- GitLab From a41a20bd47968b16bb84761578628752080e9f24 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Mon, 3 Jun 2024 15:44:04 +0800 Subject: [PATCH 054/678] [NFC] [C++20] [Modules] [Reduced BMI] Reorder Emitting reduced BMI and normal BMI for named modules When we generate the reduced BMI on the fly, the order of the emitting phase is different within `-emit-obj` and `-emit-module-interface`. Although this is meant to be fine, we observed it in https://github.com/llvm/llvm-project/issues/93859 (that the different phase order may cause problems). Also it turns out to be a different fundamental reason to the orders. But it might be fine to make the order of emitting reducing BMI at first to avoid such confusions in the future. --- clang/lib/Frontend/FrontendActions.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 454653a31534..4f064321997a 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -273,9 +273,6 @@ std::unique_ptr GenerateModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::vector> Consumers; - Consumers.push_back(std::make_unique( - CI.getPreprocessor(), CI.getModuleCache(), - CI.getFrontendOpts().OutputFile)); if (CI.getFrontendOpts().GenReducedBMI && !CI.getFrontendOpts().ModuleOutputPath.empty()) { @@ -284,6 +281,10 @@ GenerateModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI, CI.getFrontendOpts().ModuleOutputPath)); } + Consumers.push_back(std::make_unique( + CI.getPreprocessor(), CI.getModuleCache(), + CI.getFrontendOpts().OutputFile)); + return std::make_unique(std::move(Consumers)); } -- GitLab From 5b4445e5e5d09b4bdf0e3c1fab52719bfb3f75e2 Mon Sep 17 00:00:00 2001 From: David Green Date: Mon, 3 Jun 2024 09:03:32 +0100 Subject: [PATCH 055/678] [AArch64] Add a test for converting fdiv by constant to fmul. NFC --- llvm/test/CodeGen/AArch64/fdiv-const.ll | 150 ++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/fdiv-const.ll diff --git a/llvm/test/CodeGen/AArch64/fdiv-const.ll b/llvm/test/CodeGen/AArch64/fdiv-const.ll new file mode 100644 index 000000000000..5a8f73384340 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/fdiv-const.ll @@ -0,0 +1,150 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mtriple=arm64-eabi -mattr=fullfp16,sve | FileCheck %s + +define float @divf32_2(float %a) nounwind { +; CHECK-LABEL: divf32_2: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov s1, #2.00000000 +; CHECK-NEXT: fdiv s0, s0, s1 +; CHECK-NEXT: ret + %r = fdiv float %a, 2.0 + ret float %r +} + +define float @divf32_2_arcp(float %a) nounwind { +; CHECK-LABEL: divf32_2_arcp: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov s1, #0.50000000 +; CHECK-NEXT: fmul s0, s0, s1 +; CHECK-NEXT: ret + %r = fdiv arcp float %a, 2.0 + ret float %r +} + +define float @divf32_p75(float %a) nounwind { +; CHECK-LABEL: divf32_p75: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov s1, #0.75000000 +; CHECK-NEXT: fdiv s0, s0, s1 +; CHECK-NEXT: ret + %r = fdiv float %a, 0.75 + ret float %r +} + +define float @divf32_p75_arcp(float %a) nounwind { +; CHECK-LABEL: divf32_p75_arcp: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #43691 // =0xaaab +; CHECK-NEXT: movk w8, #16298, lsl #16 +; CHECK-NEXT: fmov s1, w8 +; CHECK-NEXT: fmul s0, s0, s1 +; CHECK-NEXT: ret + %r = fdiv arcp float %a, 0.75 + ret float %r +} + +define half @divf16_2(half %a) nounwind { +; CHECK-LABEL: divf16_2: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov h1, #2.00000000 +; CHECK-NEXT: fdiv h0, h0, h1 +; CHECK-NEXT: ret + %r = fdiv half %a, 2.0 + ret half %r +} + +define half @divf16_32768(half %a) nounwind { +; CHECK-LABEL: divf16_32768: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #30720 // =0x7800 +; CHECK-NEXT: fmov h1, w8 +; CHECK-NEXT: fdiv h0, h0, h1 +; CHECK-NEXT: ret + %r = fdiv half %a, 32768.0 + ret half %r +} + +define half @divf16_32768_arcp(half %a) nounwind { +; CHECK-LABEL: divf16_32768_arcp: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #512 // =0x200 +; CHECK-NEXT: fmov h1, w8 +; CHECK-NEXT: fmul h0, h0, h1 +; CHECK-NEXT: ret + %r = fdiv arcp half %a, 32768.0 + ret half %r +} + +define double @divf64_2(double %a) nounwind { +; CHECK-LABEL: divf64_2: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov d1, #2.00000000 +; CHECK-NEXT: fdiv d0, d0, d1 +; CHECK-NEXT: ret + %r = fdiv double %a, 2.0 + ret double %r +} + +define <4 x float> @divv4f32_2(<4 x float> %a) nounwind { +; CHECK-LABEL: divv4f32_2: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v1.4s, #64, lsl #24 +; CHECK-NEXT: fdiv v0.4s, v0.4s, v1.4s +; CHECK-NEXT: ret + %r = fdiv <4 x float> %a, + ret <4 x float> %r +} + +define <4 x float> @divv4f32_2_arcp(<4 x float> %a) nounwind { +; CHECK-LABEL: divv4f32_2_arcp: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v1.4s, #63, lsl #24 +; CHECK-NEXT: fmul v0.4s, v0.4s, v1.4s +; CHECK-NEXT: ret + %r = fdiv arcp <4 x float> %a, + ret <4 x float> %r +} + +define <4 x float> @divv4f32_3(<4 x float> %a) nounwind { +; CHECK-LABEL: divv4f32_3: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov v1.4s, #3.00000000 +; CHECK-NEXT: fdiv v0.4s, v0.4s, v1.4s +; CHECK-NEXT: ret + %r = fdiv <4 x float> %a, + ret <4 x float> %r +} + +define <4 x float> @divv4f32_3_arcp(<4 x float> %a) nounwind { +; CHECK-LABEL: divv4f32_3_arcp: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #43691 // =0xaaab +; CHECK-NEXT: movk w8, #16042, lsl #16 +; CHECK-NEXT: dup v1.4s, w8 +; CHECK-NEXT: fmul v0.4s, v0.4s, v1.4s +; CHECK-NEXT: ret + %r = fdiv arcp <4 x float> %a, + ret <4 x float> %r +} + +define <4 x float> @divv4f32_24816(<4 x float> %a) nounwind { +; CHECK-LABEL: divv4f32_24816: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI12_0 +; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI12_0] +; CHECK-NEXT: fdiv v0.4s, v0.4s, v1.4s +; CHECK-NEXT: ret + %r = fdiv <4 x float> %a, + ret <4 x float> %r +} + +define @divnxv4f32_2( %a) nounwind { +; CHECK-LABEL: divnxv4f32_2: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov z1.s, #2.00000000 +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: fdiv z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %r = fdiv %a, splat (float 2.0) + ret %r +} -- GitLab From f4a7f81a914ca8aceddd9b7a71e36bb0828ae052 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Mon, 3 Jun 2024 00:58:53 -0700 Subject: [PATCH 056/678] [clang-format][doc] Minor cleanup --- clang/docs/ClangFormatStyleOptions.rst | 5 +++-- clang/include/clang/Format/Format.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 677dac25df68..bb00c20922d3 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5117,7 +5117,7 @@ the configuration (without a prefix: ``Auto``). .. note:: - It must contain ``type``. + It **must** contain ``type``. Items to the left of ``type`` will be placed to the left of the type and aligned in the order supplied. Items to the right of ``type`` will be @@ -6410,6 +6410,7 @@ the configuration (without a prefix: ``Auto``). TableGenBreakInsideDAGArg: BreakAll TableGenBreakingDAGArgOperators: [ins, outs] + makes the line break only occurs inside DAGArgs beginning with the specified identifiers ``ins`` and ``outs``. @@ -6537,7 +6538,7 @@ The goal of the clang-format project is more on the side of supporting a limited set of styles really well as opposed to supporting every single style used by a codebase somewhere in the wild. Of course, we do want to support all major projects and thus have established the following bar for adding style -options. Each new style option must .. +options. Each new style option must: * be used in a project of significant size (have dozens of contributors) * have a publicly accessible style guide diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 9bae252df366..4fd6e013df25 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -3650,7 +3650,7 @@ struct FormatStyle { /// * type /// /// \note - /// It \b must contain ``type``. + /// It **must** contain ``type``. /// \endnote /// /// Items to the left of ``type`` will be placed to the left of the type and -- GitLab From 84742cd867b0e7e76da6bdc08cc7c56beac86168 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 3 Jun 2024 01:08:46 -0700 Subject: [PATCH 057/678] [libc++][test] Mark `optional` test functions as `TEST_CONSTEXPR_CXX20` (#94172) [P2231R1](https://wg21.link/P2231R1) "Missing `constexpr` in `std::optional` and `std::variant`" was accepted as a C++20 Defect Report, not a C++17 Defect Report. Accordingly, `test_empty_emplace()` and `check_reset()` should be marked as `TEST_CONSTEXPR_CXX20`. Note that their `static_assert`s are properly guarded: https://github.com/llvm/llvm-project/blob/4ce65423be0ba1d90c11b6a79981d6314e1cf36d/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp#L270-L272 https://github.com/llvm/llvm-project/blob/4ce65423be0ba1d90c11b6a79981d6314e1cf36d/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp#L53-L55 Found while running libc++'s tests with MSVC's STL, as we activate our `constexpr` here for C++20 and above. --- .../optional.object.assign/emplace.pass.cpp | 19 +++++++------ .../optional.object.mod/reset.pass.cpp | 27 +++++++++---------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp index 17a1e94b0ba6..245d8ff3d214 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp @@ -210,16 +210,15 @@ void test_on_test_type() { } } -constexpr bool test_empty_emplace() -{ - optional opt; - auto &v = opt.emplace(42); - static_assert( std::is_same_v, "" ); - assert(*opt == 42); - assert( v == 42); - opt.emplace(); - assert(*opt == 0); - return true; +TEST_CONSTEXPR_CXX20 bool test_empty_emplace() { + optional opt; + auto& v = opt.emplace(42); + static_assert(std::is_same_v, ""); + assert(*opt == 42); + assert(v == 42); + opt.emplace(); + assert(*opt == 0); + return true; } int main(int, char**) diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp index 112ee213b42a..7029b37cbecd 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp @@ -31,20 +31,19 @@ struct X bool X::dtor_called = false; -constexpr bool check_reset() -{ - { - optional opt; - static_assert(noexcept(opt.reset()) == true, ""); - opt.reset(); - assert(static_cast(opt) == false); - } - { - optional opt(3); - opt.reset(); - assert(static_cast(opt) == false); - } - return true; +TEST_CONSTEXPR_CXX20 bool check_reset() { + { + optional opt; + static_assert(noexcept(opt.reset()) == true, ""); + opt.reset(); + assert(static_cast(opt) == false); + } + { + optional opt(3); + opt.reset(); + assert(static_cast(opt) == false); + } + return true; } int main(int, char**) -- GitLab From ccb73e882b2d727877cfda42a14a6979cfd31f04 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Mon, 3 Jun 2024 16:13:55 +0800 Subject: [PATCH 058/678] [serialization] no transitive decl change (#92083) Following of https://github.com/llvm/llvm-project/pull/86912 #### Motivation Example The motivation of the patch series is that, for a module interface unit `X`, when the dependent modules of `X` changes, if the changes is not relevant with `X`, we hope the BMI of `X` won't change. For the specific patch, we hope if the changes was about irrelevant declaration changes, we hope the BMI of `X` won't change. **However**, I found the patch itself is not very useful in practice, since the adding or removing declarations, will change the state of identifiers and types in most cases. That said, for the most simple example, ``` // partA.cppm export module m:partA; // partA.v1.cppm export module m:partA; export void a() {} // partB.cppm export module m:partB; export void b() {} // m.cppm export module m; export import :partA; export import :partB; // onlyUseB; export module onlyUseB; import m; export inline void onluUseB() { b(); } ``` the BMI of `onlyUseB` will change after we change the implementation of `partA.cppm` to `partA.v1.cppm`. Since `partA.v1.cppm` introduces new identifiers and types (the function prototype). So in this patch, we have to write the tests as: ``` // partA.cppm export module m:partA; export int getA() { ... } export int getA2(int) { ... } // partA.v1.cppm export module m:partA; export int getA() { ... } export int getA(int) { ... } export int getA2(int) { ... } // partB.cppm export module m:partB; export void b() {} // m.cppm export module m; export import :partA; export import :partB; // onlyUseB; export module onlyUseB; import m; export inline void onluUseB() { b(); } ``` so that the new introduced declaration `int getA(int)` doesn't introduce new identifiers and types, then the BMI of `onlyUseB` can keep unchanged. While it looks not so great, the patch should be the base of the patch to erase the transitive change for identifiers and types since I don't know how can we introduce new types and identifiers without introducing new declarations. Given how tightly the relationship between declarations, types and identifiers, I think we can only reach the ideal state after we made the series for all of the three entties. #### Design details The design of the patch is similar to https://github.com/llvm/llvm-project/pull/86912, which extends the 32-bit DeclID to 64-bit and use the higher bits to store the module file index and the lower bits to store the Local Decl ID. A slight difference is that we only use 48 bits to store the new DeclID since we try to use the higher 16 bits to store the module ID in the prefix of Decl class. Previously, we use 32 bits to store the module ID and 32 bits to store the DeclID. I don't want to allocate additional space so I tried to make the additional space the same as 64 bits. An potential interesting thing here is about the relationship between the module ID and the module file index. I feel we can get the module file index by the module ID. But I didn't prove it or implement it. Since I want to make the patch itself as small as possible. We can make it in the future if we want. Another change in the patch is the new concept Decl Index, which means the index of the very big array `DeclsLoaded` in ASTReader. Previously, the index of a loaded declaration is simply the Decl ID minus PREDEFINED_DECL_NUMs. So there are some places they got used ambiguously. But this patch tried to split these two concepts. #### Overhead As https://github.com/llvm/llvm-project/pull/86912 did, the change will increase the on-disk PCM file sizes. As the declaration ID may be the most IDs in the PCM file, this can have the biggest impact on the size. In my experiments, this change will bring 6.6% increase of the on-disk PCM size. No compile-time performance regression observed. Given the benefits in the motivation example, I think the cost is worthwhile. --- clang/include/clang/AST/DeclBase.h | 17 +- clang/include/clang/AST/DeclID.h | 18 +- .../include/clang/Serialization/ASTBitCodes.h | 6 + clang/include/clang/Serialization/ASTReader.h | 36 ++-- .../include/clang/Serialization/ModuleFile.h | 18 +- .../clang/Serialization/ModuleManager.h | 2 +- clang/lib/AST/DeclBase.cpp | 40 ++++- clang/lib/Serialization/ASTReader.cpp | 159 ++++++++++-------- clang/lib/Serialization/ASTReaderDecl.cpp | 12 +- clang/lib/Serialization/ASTWriter.cpp | 7 +- clang/lib/Serialization/ModuleFile.cpp | 3 +- .../Modules/no-transitive-decls-change.cppm | 112 ++++++++++++ 12 files changed, 283 insertions(+), 147 deletions(-) create mode 100644 clang/test/Modules/no-transitive-decls-change.cppm diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index e43e812cd945..4bdf27aa9940 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -701,10 +701,7 @@ public: /// Set the owning module ID. This may only be called for /// deserialized Decls. - void setOwningModuleID(unsigned ID) { - assert(isFromASTFile() && "Only works on a deserialized declaration"); - *((unsigned*)this - 2) = ID; - } + void setOwningModuleID(unsigned ID); public: /// Determine the availability of the given declaration. @@ -777,19 +774,11 @@ public: /// Retrieve the global declaration ID associated with this /// declaration, which specifies where this Decl was loaded from. - GlobalDeclID getGlobalID() const { - if (isFromASTFile()) - return (*((const GlobalDeclID *)this - 1)); - return GlobalDeclID(); - } + GlobalDeclID getGlobalID() const; /// Retrieve the global ID of the module that owns this particular /// declaration. - unsigned getOwningModuleID() const { - if (isFromASTFile()) - return *((const unsigned*)this - 2); - return 0; - } + unsigned getOwningModuleID() const; private: Module *getOwningModuleSlow() const; diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h index 614ba06b6386..32d2ed41a374 100644 --- a/clang/include/clang/AST/DeclID.h +++ b/clang/include/clang/AST/DeclID.h @@ -19,6 +19,8 @@ #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/iterator.h" +#include + namespace clang { /// Predefined declaration IDs. @@ -107,12 +109,16 @@ public: /// /// DeclID should only be used directly in serialization. All other users /// should use LocalDeclID or GlobalDeclID. - using DeclID = uint32_t; + using DeclID = uint64_t; protected: DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {} explicit DeclIDBase(DeclID ID) : ID(ID) {} + explicit DeclIDBase(unsigned LocalID, unsigned ModuleFileIndex) { + ID = (DeclID)LocalID | ((DeclID)ModuleFileIndex << 32); + } + public: DeclID get() const { return ID; } @@ -124,6 +130,10 @@ public: bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; } + unsigned getModuleFileIndex() const { return ID >> 32; } + + unsigned getLocalDeclIndex() const; + friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID == RHS.ID; } @@ -156,6 +166,9 @@ public: LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {} explicit LocalDeclID(DeclID ID) : Base(ID) {} + explicit LocalDeclID(unsigned LocalID, unsigned ModuleFileIndex) + : Base(LocalID, ModuleFileIndex) {} + LocalDeclID &operator++() { ++ID; return *this; @@ -175,6 +188,9 @@ public: GlobalDeclID() : Base() {} explicit GlobalDeclID(DeclID ID) : Base(ID) {} + explicit GlobalDeclID(unsigned LocalID, unsigned ModuleFileIndex) + : Base(LocalID, ModuleFileIndex) {} + // For DeclIDIterator to be able to convert a GlobalDeclID // to a LocalDeclID. explicit operator LocalDeclID() const { return LocalDeclID(this->ID); } diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index fe1bd47348be..9e4b21baa7d2 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -255,6 +255,12 @@ public: } }; +// The unaligned decl ID used in the Blobs of bistreams. +using unaligned_decl_id_t = + llvm::support::detail::packed_endian_specific_integral< + serialization::DeclID, llvm::endianness::native, + llvm::support::unaligned>; + /// The number of predefined preprocessed entity IDs. const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1; diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 4ece4593f073..a2e094354d96 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -501,12 +501,6 @@ private: /// = I + 1 has already been loaded. llvm::PagedVector DeclsLoaded; - using GlobalDeclMapType = ContinuousRangeMap; - - /// Mapping from global declaration IDs to the module in which the - /// declaration resides. - GlobalDeclMapType GlobalDeclMap; - using FileOffset = std::pair; using FileOffsetsTy = SmallVector; using DeclUpdateOffsetsMap = llvm::DenseMap; @@ -589,10 +583,11 @@ private: struct FileDeclsInfo { ModuleFile *Mod = nullptr; - ArrayRef Decls; + ArrayRef Decls; FileDeclsInfo() = default; - FileDeclsInfo(ModuleFile *Mod, ArrayRef Decls) + FileDeclsInfo(ModuleFile *Mod, + ArrayRef Decls) : Mod(Mod), Decls(Decls) {} }; @@ -601,11 +596,7 @@ private: /// An array of lexical contents of a declaration context, as a sequence of /// Decl::Kind, DeclID pairs. - using unaligned_decl_id_t = - llvm::support::detail::packed_endian_specific_integral< - serialization::DeclID, llvm::endianness::native, - llvm::support::unaligned>; - using LexicalContents = ArrayRef; + using LexicalContents = ArrayRef; /// Map from a DeclContext to its lexical contents. llvm::DenseMap> @@ -1486,10 +1477,11 @@ private: unsigned ClientLoadCapabilities); public: - class ModuleDeclIterator : public llvm::iterator_adaptor_base< - ModuleDeclIterator, const LocalDeclID *, - std::random_access_iterator_tag, const Decl *, - ptrdiff_t, const Decl *, const Decl *> { + class ModuleDeclIterator + : public llvm::iterator_adaptor_base< + ModuleDeclIterator, const serialization::unaligned_decl_id_t *, + std::random_access_iterator_tag, const Decl *, ptrdiff_t, + const Decl *, const Decl *> { ASTReader *Reader = nullptr; ModuleFile *Mod = nullptr; @@ -1497,11 +1489,11 @@ public: ModuleDeclIterator() : iterator_adaptor_base(nullptr) {} ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod, - const LocalDeclID *Pos) + const serialization::unaligned_decl_id_t *Pos) : iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {} value_type operator*() const { - return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *I)); + return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, (LocalDeclID)*I)); } value_type operator->() const { return **this; } @@ -1541,6 +1533,9 @@ private: StringRef Arg2 = StringRef(), StringRef Arg3 = StringRef()) const; void Error(llvm::Error &&Err) const; + /// Translate a \param GlobalDeclID to the index of DeclsLoaded array. + unsigned translateGlobalDeclIDToIndex(GlobalDeclID ID) const; + public: /// Load the AST file and validate its contents against the given /// Preprocessor. @@ -1912,7 +1907,8 @@ public: /// Retrieve the module file that owns the given declaration, or NULL /// if the declaration is not from a module file. - ModuleFile *getOwningModuleFile(const Decl *D); + ModuleFile *getOwningModuleFile(const Decl *D) const; + ModuleFile *getOwningModuleFile(GlobalDeclID ID) const; /// Returns the source location for the decl \p ID. SourceLocation getSourceLocationForDeclID(GlobalDeclID ID); diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 992d26a8b88c..56193d44dd6f 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -454,23 +454,11 @@ public: /// by the declaration ID (-1). const DeclOffset *DeclOffsets = nullptr; - /// Base declaration ID for declarations local to this module. - serialization::DeclID BaseDeclID = 0; - - /// Remapping table for declaration IDs in this module. - ContinuousRangeMap DeclRemap; - - /// Mapping from the module files that this module file depends on - /// to the base declaration ID for that module as it is understood within this - /// module. - /// - /// This is effectively a reverse global-to-local mapping for declaration - /// IDs, so that we can interpret a true global ID (for this translation unit) - /// as a local ID (for this module file). - llvm::DenseMap GlobalToLocalDeclIDs; + /// Base declaration index in ASTReader for declarations local to this module. + unsigned BaseDeclIndex = 0; /// Array of file-level DeclIDs sorted by file. - const LocalDeclID *FileSortedDecls = nullptr; + const serialization::unaligned_decl_id_t *FileSortedDecls = nullptr; unsigned NumFileSortedDecls = 0; /// Array of category list location information within this diff --git a/clang/include/clang/Serialization/ModuleManager.h b/clang/include/clang/Serialization/ModuleManager.h index d770bc52eaf4..f898dab39f06 100644 --- a/clang/include/clang/Serialization/ModuleManager.h +++ b/clang/include/clang/Serialization/ModuleManager.h @@ -45,7 +45,7 @@ namespace serialization { /// Manages the set of modules loaded by an AST reader. class ModuleManager { /// The chain of AST files, in the order in which we started to load - /// them (this order isn't really useful for anything). + /// them. SmallVector, 2> Chain; /// The chain of non-module PCH files. The first entry is the one named diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index ffb22194bce5..40b58efaaf1b 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -74,18 +74,17 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context, GlobalDeclID ID, std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. - static_assert(sizeof(unsigned) * 2 >= alignof(Decl), - "Decl won't be misaligned"); + static_assert(sizeof(uint64_t) >= alignof(Decl), "Decl won't be misaligned"); void *Start = Context.Allocate(Size + Extra + 8); void *Result = (char*)Start + 8; - unsigned *PrefixPtr = (unsigned *)Result - 2; + uint64_t *PrefixPtr = (uint64_t *)Result - 1; - // Zero out the first 4 bytes; this is used to store the owning module ID. - PrefixPtr[0] = 0; + *PrefixPtr = ID.get(); - // Store the global declaration ID in the second 4 bytes. - PrefixPtr[1] = ID.get(); + // We leave the upper 16 bits to store the module IDs. 48 bits should be + // sufficient to store a declaration ID. + assert(*PrefixPtr < llvm::maskTrailingOnes(48)); return Result; } @@ -111,6 +110,29 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Ctx, return ::operator new(Size + Extra, Ctx); } +GlobalDeclID Decl::getGlobalID() const { + if (!isFromASTFile()) + return GlobalDeclID(); + // See the comments in `Decl::operator new` for details. + uint64_t ID = *((const uint64_t *)this - 1); + return GlobalDeclID(ID & llvm::maskTrailingOnes(48)); +} + +unsigned Decl::getOwningModuleID() const { + if (!isFromASTFile()) + return 0; + + uint64_t ID = *((const uint64_t *)this - 1); + return ID >> 48; +} + +void Decl::setOwningModuleID(unsigned ID) { + assert(isFromASTFile() && "Only works on a deserialized declaration"); + uint64_t *IDAddress = (uint64_t *)this - 1; + assert(!((*IDAddress) >> 48) && "We should only set the module ID once"); + *IDAddress |= (uint64_t)ID << 48; +} + Module *Decl::getOwningModuleSlow() const { assert(isFromASTFile() && "Not from AST file?"); return getASTContext().getExternalSource()->getModule(getOwningModuleID()); @@ -2164,3 +2186,7 @@ DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C, return DD; } + +unsigned DeclIDBase::getLocalDeclIndex() const { + return ID & llvm::maskTrailingOnes(32); +} diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 4a6e1d23161b..7f17e09adc29 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1656,7 +1656,7 @@ bool ASTReader::ReadSLocEntry(int ID) { unsigned NumFileDecls = Record[7]; if (NumFileDecls && ContextObj) { - const LocalDeclID *FirstDecl = F->FileSortedDecls + Record[6]; + const unaligned_decl_id_t *FirstDecl = F->FileSortedDecls + Record[6]; assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?"); FileDeclIDs[FID] = FileDeclsInfo(F, llvm::ArrayRef(FirstDecl, NumFileDecls)); @@ -3375,26 +3375,11 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, "duplicate DECL_OFFSET record in AST file"); F.DeclOffsets = (const DeclOffset *)Blob.data(); F.LocalNumDecls = Record[0]; - unsigned LocalBaseDeclID = Record[1]; - F.BaseDeclID = getTotalNumDecls(); - - if (F.LocalNumDecls > 0) { - // Introduce the global -> local mapping for declarations within this - // module. - GlobalDeclMap.insert(std::make_pair( - GlobalDeclID(getTotalNumDecls() + NUM_PREDEF_DECL_IDS), &F)); - - // Introduce the local -> global mapping for declarations within this - // module. - F.DeclRemap.insertOrReplace( - std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID)); - - // Introduce the global -> local mapping for declarations within this - // module. - F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID; + F.BaseDeclIndex = getTotalNumDecls(); + if (F.LocalNumDecls > 0) DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls); - } + break; } @@ -3629,7 +3614,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; case FILE_SORTED_DECLS: - F.FileSortedDecls = (const LocalDeclID *)Blob.data(); + F.FileSortedDecls = (const unaligned_decl_id_t *)Blob.data(); F.NumFileSortedDecls = Record[0]; break; @@ -4056,7 +4041,6 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap); RemapBuilder SubmoduleRemap(F.SubmoduleRemap); RemapBuilder SelectorRemap(F.SelectorRemap); - RemapBuilder DeclRemap(F.DeclRemap); RemapBuilder TypeRemap(F.TypeRemap); auto &ImportedModuleVector = F.TransitiveImports; @@ -4095,8 +4079,6 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { endian::readNext(Data); uint32_t SelectorIDOffset = endian::readNext(Data); - uint32_t DeclIDOffset = - endian::readNext(Data); uint32_t TypeIndexOffset = endian::readNext(Data); @@ -4114,11 +4096,7 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { PreprocessedEntityRemap); mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap); mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap); - mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap); mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap); - - // Global -> local mappings. - F.GlobalToLocalDeclIDs[OM] = DeclIDOffset; } } @@ -7642,18 +7620,25 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { GlobalDeclID ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const { - DeclID ID = LocalID.get(); - if (ID < NUM_PREDEF_DECL_IDS) - return GlobalDeclID(ID); + if (LocalID.get() < NUM_PREDEF_DECL_IDS) + return GlobalDeclID(LocalID.get()); + + unsigned OwningModuleFileIndex = LocalID.getModuleFileIndex(); + DeclID ID = LocalID.getLocalDeclIndex(); if (!F.ModuleOffsetMap.empty()) ReadModuleOffsetMap(F); - ContinuousRangeMap::iterator I = - F.DeclRemap.find(ID - NUM_PREDEF_DECL_IDS); - assert(I != F.DeclRemap.end() && "Invalid index into decl index remap"); + ModuleFile *OwningModuleFile = + OwningModuleFileIndex == 0 + ? &F + : F.TransitiveImports[OwningModuleFileIndex - 1]; + + if (OwningModuleFileIndex == 0) + ID -= NUM_PREDEF_DECL_IDS; - return GlobalDeclID(ID + I->second); + uint64_t NewModuleFileIndex = OwningModuleFile->Index + 1; + return GlobalDeclID(ID, NewModuleFileIndex); } bool ASTReader::isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const { @@ -7661,31 +7646,33 @@ bool ASTReader::isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const { if (ID.get() < NUM_PREDEF_DECL_IDS) return false; - return ID.get() - NUM_PREDEF_DECL_IDS >= M.BaseDeclID && - ID.get() - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls; + unsigned ModuleFileIndex = ID.getModuleFileIndex(); + return M.Index == ModuleFileIndex - 1; +} + +ModuleFile *ASTReader::getOwningModuleFile(GlobalDeclID ID) const { + // Predefined decls aren't from any module. + if (ID.get() < NUM_PREDEF_DECL_IDS) + return nullptr; + + uint64_t ModuleFileIndex = ID.getModuleFileIndex(); + assert(ModuleFileIndex && "Untranslated Local Decl?"); + + return &getModuleManager()[ModuleFileIndex - 1]; } -ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) { +ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) const { if (!D->isFromASTFile()) return nullptr; - GlobalDeclMapType::const_iterator I = - GlobalDeclMap.find(GlobalDeclID(D->getGlobalID())); - assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); - return I->second; + + return getOwningModuleFile(GlobalDeclID(D->getGlobalID())); } SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) { if (ID.get() < NUM_PREDEF_DECL_IDS) return SourceLocation(); - unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; - - if (Index > DeclsLoaded.size()) { - Error("declaration ID out-of-range for AST file"); - return SourceLocation(); - } - - if (Decl *D = DeclsLoaded[Index]) + if (Decl *D = GetExistingDecl(ID)) return D->getLocation(); SourceLocation Loc; @@ -7752,8 +7739,19 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { llvm_unreachable("PredefinedDeclIDs unknown enum value"); } +unsigned ASTReader::translateGlobalDeclIDToIndex(GlobalDeclID GlobalID) const { + ModuleFile *OwningModuleFile = getOwningModuleFile(GlobalID); + if (!OwningModuleFile) { + assert(GlobalID.get() < NUM_PREDEF_DECL_IDS && "Untransalted Global ID?"); + return GlobalID.get(); + } + + return OwningModuleFile->BaseDeclIndex + GlobalID.getLocalDeclIndex(); +} + Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { assert(ContextObj && "reading decl with no AST context"); + if (ID.get() < NUM_PREDEF_DECL_IDS) { Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID); if (D) { @@ -7766,7 +7764,7 @@ Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { return D; } - unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; + unsigned Index = translateGlobalDeclIDToIndex(ID); if (Index >= DeclsLoaded.size()) { assert(0 && "declaration ID out-of-range for AST file"); @@ -7781,7 +7779,7 @@ Decl *ASTReader::GetDecl(GlobalDeclID ID) { if (ID.get() < NUM_PREDEF_DECL_IDS) return GetExistingDecl(ID); - unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; + unsigned Index = translateGlobalDeclIDToIndex(ID); if (Index >= DeclsLoaded.size()) { assert(0 && "declaration ID out-of-range for AST file"); @@ -7800,20 +7798,31 @@ Decl *ASTReader::GetDecl(GlobalDeclID ID) { LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, GlobalDeclID GlobalID) { - DeclID ID = GlobalID.get(); - if (ID < NUM_PREDEF_DECL_IDS) + if (GlobalID.get() < NUM_PREDEF_DECL_IDS) + return LocalDeclID(GlobalID.get()); + + if (!M.ModuleOffsetMap.empty()) + ReadModuleOffsetMap(M); + + ModuleFile *Owner = getOwningModuleFile(GlobalID); + DeclID ID = GlobalID.getLocalDeclIndex(); + + if (Owner == &M) { + ID += NUM_PREDEF_DECL_IDS; return LocalDeclID(ID); + } - GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID); - assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); - ModuleFile *Owner = I->second; + uint64_t OrignalModuleFileIndex = 0; + for (unsigned I = 0; I < M.TransitiveImports.size(); I++) + if (M.TransitiveImports[I] == Owner) { + OrignalModuleFileIndex = I + 1; + break; + } - llvm::DenseMap::iterator Pos = - M.GlobalToLocalDeclIDs.find(Owner); - if (Pos == M.GlobalToLocalDeclIDs.end()) + if (!OrignalModuleFileIndex) return LocalDeclID(); - return LocalDeclID(ID - Owner->BaseDeclID + Pos->second); + return LocalDeclID(ID, OrignalModuleFileIndex); } GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordData &Record, @@ -7892,32 +7901,34 @@ void ASTReader::FindExternalLexicalDecls( namespace { -class DeclIDComp { +class UnalignedDeclIDComp { ASTReader &Reader; ModuleFile &Mod; public: - DeclIDComp(ASTReader &Reader, ModuleFile &M) : Reader(Reader), Mod(M) {} + UnalignedDeclIDComp(ASTReader &Reader, ModuleFile &M) + : Reader(Reader), Mod(M) {} - bool operator()(LocalDeclID L, LocalDeclID R) const { + bool operator()(unaligned_decl_id_t L, unaligned_decl_id_t R) const { SourceLocation LHS = getLocation(L); SourceLocation RHS = getLocation(R); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - bool operator()(SourceLocation LHS, LocalDeclID R) const { + bool operator()(SourceLocation LHS, unaligned_decl_id_t R) const { SourceLocation RHS = getLocation(R); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - bool operator()(LocalDeclID L, SourceLocation RHS) const { + bool operator()(unaligned_decl_id_t L, SourceLocation RHS) const { SourceLocation LHS = getLocation(L); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - SourceLocation getLocation(LocalDeclID ID) const { + SourceLocation getLocation(unaligned_decl_id_t ID) const { return Reader.getSourceManager().getFileLoc( - Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID))); + Reader.getSourceLocationForDeclID( + Reader.getGlobalDeclID(Mod, (LocalDeclID)ID))); } }; @@ -7940,8 +7951,8 @@ void ASTReader::FindFileRegionDecls(FileID File, BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset); SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length); - DeclIDComp DIDComp(*this, *DInfo.Mod); - ArrayRef::iterator BeginIt = + UnalignedDeclIDComp DIDComp(*this, *DInfo.Mod); + ArrayRef::iterator BeginIt = llvm::lower_bound(DInfo.Decls, BeginLoc, DIDComp); if (BeginIt != DInfo.Decls.begin()) --BeginIt; @@ -7950,17 +7961,18 @@ void ASTReader::FindFileRegionDecls(FileID File, // to backtrack until we find it otherwise we will fail to report that the // region overlaps with an objc container. while (BeginIt != DInfo.Decls.begin() && - GetDecl(getGlobalDeclID(*DInfo.Mod, *BeginIt)) + GetDecl(getGlobalDeclID(*DInfo.Mod, (LocalDeclID)(*BeginIt))) ->isTopLevelDeclInObjCContainer()) --BeginIt; - ArrayRef::iterator EndIt = + ArrayRef::iterator EndIt = llvm::upper_bound(DInfo.Decls, EndLoc, DIDComp); if (EndIt != DInfo.Decls.end()) ++EndIt; - for (ArrayRef::iterator DIt = BeginIt; DIt != EndIt; ++DIt) - Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt))); + for (ArrayRef::iterator DIt = BeginIt; DIt != EndIt; + ++DIt) + Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, (LocalDeclID)(*DIt)))); } bool @@ -8167,7 +8179,6 @@ LLVM_DUMP_METHOD void ASTReader::dump() { dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap); dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap); dumpModuleIDMap("Global type map", GlobalTypeMap); - dumpModuleIDMap("Global declaration map", GlobalDeclMap); dumpModuleIDMap("Global identifier map", GlobalIdentifierMap); dumpModuleIDMap("Global macro map", GlobalMacroMap); dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 61cc99d4df68..519c7d5c20fd 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3244,11 +3244,10 @@ bool ASTReader::isConsumerInterestedIn(Decl *D) { /// Get the correct cursor and offset for loading a declaration. ASTReader::RecordLocation ASTReader::DeclCursorForID(GlobalDeclID ID, SourceLocation &Loc) { - GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID); - assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); - ModuleFile *M = I->second; - const DeclOffset &DOffs = - M->DeclOffsets[ID.get() - M->BaseDeclID - NUM_PREDEF_DECL_IDS]; + ModuleFile *M = getOwningModuleFile(ID); + assert(M); + unsigned LocalDeclIndex = ID.getLocalDeclIndex(); + const DeclOffset &DOffs = M->DeclOffsets[LocalDeclIndex]; Loc = ReadSourceLocation(*M, DOffs.getRawLoc()); return RecordLocation(M, DOffs.getBitOffset(M->DeclsBlockStartOffset)); } @@ -3791,7 +3790,6 @@ void ASTReader::markIncompleteDeclChain(Decl *D) { /// Read the declaration at the given offset from the AST file. Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { - unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; SourceLocation DeclLoc; RecordLocation Loc = DeclCursorForID(ID, DeclLoc); llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor; @@ -4122,7 +4120,7 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { } assert(D && "Unknown declaration reading AST file"); - LoadedDecl(Index, D); + LoadedDecl(translateGlobalDeclIDToIndex(ID), D); // Set the DeclContext before doing any deserialization, to make sure internal // calls to Decl::getASTContext() by Decl's methods will find the // TranslationUnitDecl without crashing. diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index eb41a205bc82..4f1d2c532bc9 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3357,12 +3357,10 @@ void ASTWriter::WriteTypeDeclOffsets() { Abbrev = std::make_shared(); Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base decl ID Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); { - RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(), - FirstDeclID.get() - NUM_PREDEF_DECL_IDS}; + RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size()}; Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets)); } } @@ -5424,7 +5422,6 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, M.NumPreprocessedEntities); writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules); writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors); - writeBaseIDOrNone(M.BaseDeclID, M.LocalNumDecls); writeBaseIDOrNone(M.BaseTypeIndex, M.LocalNumTypes); } } @@ -6617,13 +6614,11 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) { // Note, this will get called multiple times, once one the reader starts up // and again each time it's done reading a PCH or module. - FirstDeclID = LocalDeclID(NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls()); FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes(); FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros(); FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules(); FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors(); - NextDeclID = FirstDeclID; NextTypeID = FirstTypeID; NextIdentID = FirstIdentID; NextMacroID = FirstMacroID; diff --git a/clang/lib/Serialization/ModuleFile.cpp b/clang/lib/Serialization/ModuleFile.cpp index 2c42d33a8f5d..f64a59bd9489 100644 --- a/clang/lib/Serialization/ModuleFile.cpp +++ b/clang/lib/Serialization/ModuleFile.cpp @@ -87,7 +87,6 @@ LLVM_DUMP_METHOD void ModuleFile::dump() { << " Number of types: " << LocalNumTypes << '\n'; dumpLocalRemap("Type index local -> global map", TypeRemap); - llvm::errs() << " Base decl ID: " << BaseDeclID << '\n' + llvm::errs() << " Base decl index: " << BaseDeclIndex << '\n' << " Number of decls: " << LocalNumDecls << '\n'; - dumpLocalRemap("Decl ID local -> global map", DeclRemap); } diff --git a/clang/test/Modules/no-transitive-decls-change.cppm b/clang/test/Modules/no-transitive-decls-change.cppm new file mode 100644 index 000000000000..42ac061bc90b --- /dev/null +++ b/clang/test/Modules/no-transitive-decls-change.cppm @@ -0,0 +1,112 @@ +// Testing that changing a declaration in an unused module file won't change +// the BMI of the current module file. +// +// RUN: rm -rf %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/m-partA.cppm -emit-reduced-module-interface -o %t/m-partA.pcm +// RUN: %clang_cc1 -std=c++20 %t/m-partA.v1.cppm -emit-reduced-module-interface -o \ +// RUN: %t/m-partA.v1.pcm +// RUN: %clang_cc1 -std=c++20 %t/m-partB.cppm -emit-reduced-module-interface -o %t/m-partB.pcm +// RUN: %clang_cc1 -std=c++20 %t/m.cppm -emit-reduced-module-interface -o %t/m.pcm \ +// RUN: -fmodule-file=m:partA=%t/m-partA.pcm -fmodule-file=m:partB=%t/m-partB.pcm +// RUN: %clang_cc1 -std=c++20 %t/m.cppm -emit-reduced-module-interface -o %t/m.v1.pcm \ +// RUN: -fmodule-file=m:partA=%t/m-partA.v1.pcm -fmodule-file=m:partB=%t/m-partB.pcm +// +// RUN: %clang_cc1 -std=c++20 %t/useBOnly.cppm -emit-reduced-module-interface -o %t/useBOnly.pcm \ +// RUN: -fmodule-file=m=%t/m.pcm -fmodule-file=m:partA=%t/m-partA.pcm \ +// RUN: -fmodule-file=m:partB=%t/m-partB.pcm +// RUN: %clang_cc1 -std=c++20 %t/useBOnly.cppm -emit-reduced-module-interface -o %t/useBOnly.v1.pcm \ +// RUN: -fmodule-file=m=%t/m.v1.pcm -fmodule-file=m:partA=%t/m-partA.v1.pcm \ +// RUN: -fmodule-file=m:partB=%t/m-partB.pcm +// Since useBOnly only uses partB from module M, the change in partA shouldn't affect +// useBOnly. +// RUN: diff %t/useBOnly.pcm %t/useBOnly.v1.pcm &> /dev/null + +//--- m-partA.cppm +export module m:partA; + +namespace A_Impl { + inline int getAImpl() { + return 43; + } + + inline int getA2Impl() { + return 43; + } +} + +namespace A { + using A_Impl::getAImpl; +} + +export inline int getA() { + return 43; +} + +export inline int getA2(int) { + return 88; +} + +//--- m-partA.v1.cppm +export module m:partA; + +namespace A_Impl { + inline int getAImpl() { + return 43; + } + + inline int getA2Impl() { + return 43; + } +} + +namespace A { + using A_Impl::getAImpl; + // Adding a new declaration without introducing a new declaration name. + using A_Impl::getA2Impl; +} + +inline int getA() { + return 43; +} + +inline int getA2(int) { + return 88; +} + +// Now we add a new declaration without introducing new identifier and new types. +// The consuming module which didn't use m:partA completely is expected to be +// not changed. +inline int getA(int) { + return 88; +} + +//--- m-partB.cppm +export module m:partB; + +export inline int getB() { + return 430; +} + +//--- m.cppm +export module m; +export import :partA; +export import :partB; + +//--- useBOnly.cppm +export module useBOnly; +import m; + +export inline int get() { + return getB(); +} + +//--- useAOnly.cppm +export module useAOnly; +import m; + +export inline int get() { + A a; + return a.getValue(); +} -- GitLab From b71434f8b33b6538554a092155c7e8477b2899e1 Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Mon, 3 Jun 2024 09:22:21 +0100 Subject: [PATCH 059/678] [AArch64] Avoid NEON ORR when NEON and SVE are unavailable (#93940) For streaming-compatible functions with only +sme, we can't use a NEON ORR (aliased as 'mov') for copies of Q-registers, so we need to use a spill/fill instead. This also fixes the fill, which should use the post-incrementing addressing mode. --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 4 +-- .../CodeGen/AArch64/arm64-reg-copy-noneon.ll | 25 ++++++++++++------- ...streaming-mode-fixed-length-masked-load.ll | 12 ++++++--- .../sve-streaming-mode-test-register-mov.ll | 3 ++- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 96afb10ac3ff..f7da25e15ec5 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4661,7 +4661,7 @@ void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB, .addReg(AArch64::Z0 + (DestReg - AArch64::Q0), RegState::Define) .addReg(AArch64::Z0 + (SrcReg - AArch64::Q0)) .addReg(AArch64::Z0 + (SrcReg - AArch64::Q0)); - else if (Subtarget.hasNEON()) + else if (Subtarget.isNeonAvailable()) BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) .addReg(SrcReg) .addReg(SrcReg, getKillRegState(KillSrc)); @@ -4671,7 +4671,7 @@ void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB, .addReg(SrcReg, getKillRegState(KillSrc)) .addReg(AArch64::SP) .addImm(-16); - BuildMI(MBB, I, DL, get(AArch64::LDRQpre)) + BuildMI(MBB, I, DL, get(AArch64::LDRQpost)) .addReg(AArch64::SP, RegState::Define) .addReg(DestReg, RegState::Define) .addReg(AArch64::SP) diff --git a/llvm/test/CodeGen/AArch64/arm64-reg-copy-noneon.ll b/llvm/test/CodeGen/AArch64/arm64-reg-copy-noneon.ll index 29255ef187c1..69cd295c309d 100644 --- a/llvm/test/CodeGen/AArch64/arm64-reg-copy-noneon.ll +++ b/llvm/test/CodeGen/AArch64/arm64-reg-copy-noneon.ll @@ -1,20 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc -mtriple=arm64-none-linux-gnu -mattr=-neon < %s | FileCheck %s define float @copy_FPR32(float %a, float %b) { -;CHECK-LABEL: copy_FPR32: -;CHECK: fmov s0, s1 +; CHECK-LABEL: copy_FPR32: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov s0, s1 +; CHECK-NEXT: ret ret float %b; } - + define double @copy_FPR64(double %a, double %b) { -;CHECK-LABEL: copy_FPR64: -;CHECK: fmov d0, d1 +; CHECK-LABEL: copy_FPR64: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov d0, d1 +; CHECK-NEXT: ret ret double %b; } - + define fp128 @copy_FPR128(fp128 %a, fp128 %b) { -;CHECK-LABEL: copy_FPR128: -;CHECK: str q1, [sp, #-16]! -;CHECK-NEXT: ldr q0, [sp, #16]! +; CHECK-LABEL: copy_FPR128: +; CHECK: // %bb.0: +; CHECK-NEXT: str q1, [sp, #-16]! +; CHECK-NEXT: ldr q0, [sp], #16 +; CHECK-NEXT: ret ret fp128 %b; } diff --git a/llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-masked-load.ll b/llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-masked-load.ll index be335c697707..a689a539b008 100644 --- a/llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-masked-load.ll +++ b/llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-masked-load.ll @@ -980,7 +980,8 @@ define <32 x i8> @masked_load_v32i8(ptr %src, <32 x i1> %mask) { ; NONEON-NOSVE-NEXT: tbnz w8, #1, .LBB3_3 ; NONEON-NOSVE-NEXT: b .LBB3_4 ; NONEON-NOSVE-NEXT: .LBB3_2: -; NONEON-NOSVE-NEXT: mov v0.16b, v1.16b +; NONEON-NOSVE-NEXT: str q1, [sp, #-16]! +; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 ; NONEON-NOSVE-NEXT: tbz w8, #1, .LBB3_4 ; NONEON-NOSVE-NEXT: .LBB3_3: // %cond.load1 ; NONEON-NOSVE-NEXT: ldrb w10, [x0, #1] @@ -2095,7 +2096,8 @@ define <16 x half> @masked_load_v16f16(ptr %src, <16 x i1> %mask) { ; NONEON-NOSVE-NEXT: tbnz w8, #1, .LBB7_3 ; NONEON-NOSVE-NEXT: b .LBB7_4 ; NONEON-NOSVE-NEXT: .LBB7_2: -; NONEON-NOSVE-NEXT: mov v0.16b, v1.16b +; NONEON-NOSVE-NEXT: str q1, [sp, #-16]! +; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 ; NONEON-NOSVE-NEXT: tbz w8, #1, .LBB7_4 ; NONEON-NOSVE-NEXT: .LBB7_3: // %cond.load1 ; NONEON-NOSVE-NEXT: ldr h2, [x0, #2] @@ -2616,7 +2618,8 @@ define <8 x float> @masked_load_v8f32(ptr %src, <8 x i1> %mask) { ; NONEON-NOSVE-NEXT: tbnz w8, #1, .LBB10_3 ; NONEON-NOSVE-NEXT: b .LBB10_4 ; NONEON-NOSVE-NEXT: .LBB10_2: -; NONEON-NOSVE-NEXT: mov v0.16b, v1.16b +; NONEON-NOSVE-NEXT: str q1, [sp, #-16]! +; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 ; NONEON-NOSVE-NEXT: tbz w8, #1, .LBB10_4 ; NONEON-NOSVE-NEXT: .LBB10_3: // %cond.load1 ; NONEON-NOSVE-NEXT: ldr s2, [x0, #4] @@ -2839,7 +2842,8 @@ define <4 x double> @masked_load_v4f64(ptr %src, <4 x i1> %mask) { ; NONEON-NOSVE-NEXT: tbnz w8, #1, .LBB12_3 ; NONEON-NOSVE-NEXT: b .LBB12_4 ; NONEON-NOSVE-NEXT: .LBB12_2: -; NONEON-NOSVE-NEXT: mov v0.16b, v1.16b +; NONEON-NOSVE-NEXT: str q1, [sp, #-16]! +; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 ; NONEON-NOSVE-NEXT: tbz w8, #1, .LBB12_4 ; NONEON-NOSVE-NEXT: .LBB12_3: // %cond.load1 ; NONEON-NOSVE-NEXT: ldr d2, [x0, #8] diff --git a/llvm/test/CodeGen/AArch64/sve-streaming-mode-test-register-mov.ll b/llvm/test/CodeGen/AArch64/sve-streaming-mode-test-register-mov.ll index 67cdde718e39..23adb1a4bc09 100644 --- a/llvm/test/CodeGen/AArch64/sve-streaming-mode-test-register-mov.ll +++ b/llvm/test/CodeGen/AArch64/sve-streaming-mode-test-register-mov.ll @@ -15,7 +15,8 @@ define fp128 @test_streaming_compatible_register_mov(fp128 %q0, fp128 %q1) { ; ; NONEON-NOSVE-LABEL: test_streaming_compatible_register_mov: ; NONEON-NOSVE: // %bb.0: -; NONEON-NOSVE-NEXT: mov v0.16b, v1.16b +; NONEON-NOSVE-NEXT: str q1, [sp, #-16]! +; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 ; NONEON-NOSVE-NEXT: ret ret fp128 %q1 } -- GitLab From 264b1b24869eb45463a98d70e9b9e991092acc28 Mon Sep 17 00:00:00 2001 From: David Green Date: Mon, 3 Jun 2024 09:31:36 +0100 Subject: [PATCH 060/678] [ARM] Convert vector fdiv+fcvt fixed-point combine to fmul. Instcombine will convert fdiv by a power-2 to fmul, this converts the PerformVDIVCombine that converts fdiv+fcvt to fixed-point fcvt to fmul+fcvt. The fdiv tests will look worse, but won't appear in practice (and should be improved again by #93882). --- llvm/lib/Target/ARM/ARMISelLowering.cpp | 54 ++++++----- llvm/test/CodeGen/ARM/vdiv_combine.ll | 119 ++++++++++++++++-------- 2 files changed, 113 insertions(+), 60 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 5090d8bf6cf2..5212d2c620b7 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -1000,7 +1000,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, } setTargetDAGCombine({ISD::SHL, ISD::SRL, ISD::SRA, ISD::FP_TO_SINT, - ISD::FP_TO_UINT, ISD::FDIV, ISD::LOAD}); + ISD::FP_TO_UINT, ISD::FMUL, ISD::LOAD}); // It is legal to extload from v4i8 to v4i16 or v4i32. for (MVT Ty : {MVT::v8i8, MVT::v4i8, MVT::v2i8, MVT::v4i16, MVT::v2i16, @@ -17011,17 +17011,17 @@ static SDValue PerformFADDCombine(SDNode *N, SelectionDAG &DAG, return SDValue(); } -/// PerformVDIVCombine - VCVT (fixed-point to floating-point, Advanced SIMD) -/// can replace combinations of VCVT (integer to floating-point) and VDIV -/// when the VDIV has a constant operand that is a power of 2. +/// PerformVMulVCTPCombine - VCVT (fixed-point to floating-point, Advanced SIMD) +/// can replace combinations of VCVT (integer to floating-point) and VMUL +/// when the VMUL has a constant operand that is a power of 2. /// -/// Example (assume d17 = ): +/// Example (assume d17 = ): /// vcvt.f32.s32 d16, d16 -/// vdiv.f32 d16, d17, d16 +/// vmul.f32 d16, d16, d17 /// becomes: /// vcvt.f32.s32 d16, d16, #3 -static SDValue PerformVDIVCombine(SDNode *N, SelectionDAG &DAG, - const ARMSubtarget *Subtarget) { +static SDValue PerformVMulVCTPCombine(SDNode *N, SelectionDAG &DAG, + const ARMSubtarget *Subtarget) { if (!Subtarget->hasNEON()) return SDValue(); @@ -17048,26 +17048,34 @@ static SDValue PerformVDIVCombine(SDNode *N, SelectionDAG &DAG, return SDValue(); } - BitVector UndefElements; - BuildVectorSDNode *BV = cast(ConstVec); - int32_t C = BV->getConstantFPSplatPow2ToLog2Int(&UndefElements, 33); + ConstantFPSDNode *CN = isConstOrConstSplatFP(ConstVec, true); + APFloat Recip(0.0f); + if (!CN || !CN->getValueAPF().getExactInverse(&Recip)) + return SDValue(); + + bool IsExact; + APSInt IntVal(33); + if (Recip.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact) != + APFloat::opOK || + !IsExact) + return SDValue(); + + int32_t C = IntVal.exactLogBase2(); if (C == -1 || C == 0 || C > 32) return SDValue(); - SDLoc dl(N); + SDLoc DL(N); bool isSigned = OpOpcode == ISD::SINT_TO_FP; SDValue ConvInput = Op.getOperand(0); if (IntBits < FloatBits) - ConvInput = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, - dl, NumLanes == 2 ? MVT::v2i32 : MVT::v4i32, - ConvInput); + ConvInput = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, DL, + NumLanes == 2 ? MVT::v2i32 : MVT::v4i32, ConvInput); - unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfxs2fp : - Intrinsic::arm_neon_vcvtfxu2fp; - return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, - Op.getValueType(), - DAG.getConstant(IntrinsicOpcode, dl, MVT::i32), - ConvInput, DAG.getConstant(C, dl, MVT::i32)); + unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfxs2fp + : Intrinsic::arm_neon_vcvtfxu2fp; + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(), + DAG.getConstant(IntrinsicOpcode, DL, MVT::i32), ConvInput, + DAG.getConstant(C, DL, MVT::i32)); } static SDValue PerformVECREDUCE_ADDCombine(SDNode *N, SelectionDAG &DAG, @@ -18897,8 +18905,8 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N, return PerformVCVTCombine(N, DCI.DAG, Subtarget); case ISD::FADD: return PerformFADDCombine(N, DCI.DAG, Subtarget); - case ISD::FDIV: - return PerformVDIVCombine(N, DCI.DAG, Subtarget); + case ISD::FMUL: + return PerformVMulVCTPCombine(N, DCI.DAG, Subtarget); case ISD::INTRINSIC_WO_CHAIN: return PerformIntrinsicCombine(N, DCI); case ISD::SHL: diff --git a/llvm/test/CodeGen/ARM/vdiv_combine.ll b/llvm/test/CodeGen/ARM/vdiv_combine.ll index c8721e700a33..988844661085 100644 --- a/llvm/test/CodeGen/ARM/vdiv_combine.ll +++ b/llvm/test/CodeGen/ARM/vdiv_combine.ll @@ -5,7 +5,10 @@ define arm_aapcs_vfpcc <2 x float> @t1(<2 x i32> %vecinit2.i) nounwind { ; CHECK-LABEL: t1: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: vcvt.f32.s32 d0, d0, #3 +; CHECK-NEXT: vmov.f32 s2, #8.000000e+00 +; CHECK-NEXT: vcvt.f32.s32 d2, d0 +; CHECK-NEXT: vdiv.f32 s1, s5, s2 +; CHECK-NEXT: vdiv.f32 s0, s4, s2 ; CHECK-NEXT: bx lr entry: %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> @@ -17,7 +20,10 @@ entry: define arm_aapcs_vfpcc <2 x float> @t2(<2 x i32> %vecinit2.i) nounwind { ; CHECK-LABEL: t2: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: vcvt.f32.u32 d0, d0, #3 +; CHECK-NEXT: vmov.f32 s2, #8.000000e+00 +; CHECK-NEXT: vcvt.f32.u32 d2, d0 +; CHECK-NEXT: vdiv.f32 s1, s5, s2 +; CHECK-NEXT: vdiv.f32 s0, s4, s2 ; CHECK-NEXT: bx lr entry: %vcvt.i = uitofp <2 x i32> %vecinit2.i to <2 x float> @@ -71,8 +77,17 @@ entry: define arm_aapcs_vfpcc <2 x float> @t5(<2 x i32> %vecinit2.i) nounwind { ; CHECK-LABEL: t5: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: vcvt.f32.s32 d0, d0, #32 +; CHECK-NEXT: vcvt.f32.s32 d2, d0 +; CHECK-NEXT: vldr s2, LCPI4_0 +; CHECK-NEXT: vdiv.f32 s1, s5, s2 +; CHECK-NEXT: vdiv.f32 s0, s4, s2 ; CHECK-NEXT: bx lr +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: @ %bb.1: +; CHECK-NEXT: .data_region +; CHECK-NEXT: LCPI4_0: +; CHECK-NEXT: .long 0x4f800000 @ float 4.2949673E+9 +; CHECK-NEXT: .end_data_region entry: %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> %div.i = fdiv <2 x float> %vcvt.i, @@ -83,7 +98,12 @@ entry: define arm_aapcs_vfpcc <4 x float> @t6(<4 x i32> %vecinit6.i) nounwind { ; CHECK-LABEL: t6: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: vcvt.f32.s32 q0, q0, #3 +; CHECK-NEXT: vmov.f32 s4, #8.000000e+00 +; CHECK-NEXT: vcvt.f32.s32 q2, q0 +; CHECK-NEXT: vdiv.f32 s3, s11, s4 +; CHECK-NEXT: vdiv.f32 s2, s10, s4 +; CHECK-NEXT: vdiv.f32 s1, s9, s4 +; CHECK-NEXT: vdiv.f32 s0, s8, s4 ; CHECK-NEXT: bx lr entry: %vcvt.i = sitofp <4 x i32> %vecinit6.i to <4 x float> @@ -95,7 +115,12 @@ define arm_aapcs_vfpcc <4 x float> @fix_unsigned_i16_to_float(<4 x i16> %in) { ; CHECK-LABEL: fix_unsigned_i16_to_float: ; CHECK: @ %bb.0: ; CHECK-NEXT: vmovl.u16 q8, d0 -; CHECK-NEXT: vcvt.f32.u32 q0, q8, #1 +; CHECK-NEXT: vmov.f32 s4, #2.000000e+00 +; CHECK-NEXT: vcvt.f32.u32 q2, q8 +; CHECK-NEXT: vdiv.f32 s3, s11, s4 +; CHECK-NEXT: vdiv.f32 s2, s10, s4 +; CHECK-NEXT: vdiv.f32 s1, s9, s4 +; CHECK-NEXT: vdiv.f32 s0, s8, s4 ; CHECK-NEXT: bx lr %conv = uitofp <4 x i16> %in to <4 x float> %shift = fdiv <4 x float> %conv, @@ -106,7 +131,12 @@ define arm_aapcs_vfpcc <4 x float> @fix_signed_i16_to_float(<4 x i16> %in) { ; CHECK-LABEL: fix_signed_i16_to_float: ; CHECK: @ %bb.0: ; CHECK-NEXT: vmovl.s16 q8, d0 -; CHECK-NEXT: vcvt.f32.s32 q0, q8, #1 +; CHECK-NEXT: vmov.f32 s4, #2.000000e+00 +; CHECK-NEXT: vcvt.f32.s32 q2, q8 +; CHECK-NEXT: vdiv.f32 s3, s11, s4 +; CHECK-NEXT: vdiv.f32 s2, s10, s4 +; CHECK-NEXT: vdiv.f32 s1, s9, s4 +; CHECK-NEXT: vdiv.f32 s0, s8, s4 ; CHECK-NEXT: bx lr %conv = sitofp <4 x i16> %in to <4 x float> %shift = fdiv <4 x float> %conv, @@ -166,8 +196,19 @@ define arm_aapcs_vfpcc <2 x double> @fix_i64_to_double(<2 x i64> %in) { define arm_aapcs_vfpcc <8 x float> @test7(<8 x i32> %in) nounwind { ; CHECK-LABEL: test7: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: vcvt.f32.s32 q0, q0, #3 -; CHECK-NEXT: vcvt.f32.s32 q1, q1, #3 +; CHECK-NEXT: vpush {d8, d9} +; CHECK-NEXT: vmov.f32 s12, #8.000000e+00 +; CHECK-NEXT: vcvt.f32.s32 q4, q0 +; CHECK-NEXT: vcvt.f32.s32 q2, q1 +; CHECK-NEXT: vdiv.f32 s3, s19, s12 +; CHECK-NEXT: vdiv.f32 s7, s11, s12 +; CHECK-NEXT: vdiv.f32 s2, s18, s12 +; CHECK-NEXT: vdiv.f32 s6, s10, s12 +; CHECK-NEXT: vdiv.f32 s1, s17, s12 +; CHECK-NEXT: vdiv.f32 s5, s9, s12 +; CHECK-NEXT: vdiv.f32 s0, s16, s12 +; CHECK-NEXT: vdiv.f32 s4, s8, s12 +; CHECK-NEXT: vpop {d8, d9} ; CHECK-NEXT: bx lr entry: %vcvt.i = sitofp <8 x i32> %in to <8 x float> @@ -179,8 +220,19 @@ entry: define arm_aapcs_vfpcc <4 x float> @test8(<4 x i32> %in) { ; CHECK-LABEL: test8: ; CHECK: @ %bb.0: -; CHECK-NEXT: vcvt.f32.s32 q0, q0, #1 +; CHECK-NEXT: vmov.f32 s4, #2.000000e+00 +; CHECK-NEXT: vcvt.f32.s32 q2, q0 +; CHECK-NEXT: vdiv.f32 s2, s10, s4 +; CHECK-NEXT: vdiv.f32 s1, s9, s4 +; CHECK-NEXT: vdiv.f32 s0, s8, s4 +; CHECK-NEXT: vldr s3, LCPI11_0 ; CHECK-NEXT: bx lr +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: @ %bb.1: +; CHECK-NEXT: .data_region +; CHECK-NEXT: LCPI11_0: +; CHECK-NEXT: .long 0x7fc00000 @ float NaN +; CHECK-NEXT: .end_data_region %vcvt.i = sitofp <4 x i32> %in to <4 x float> %div.i = fdiv <4 x float> %vcvt.i, ret <4 x float> %div.i @@ -189,8 +241,19 @@ define arm_aapcs_vfpcc <4 x float> @test8(<4 x i32> %in) { define arm_aapcs_vfpcc <3 x float> @test_illegal_int_to_fp(<3 x i32> %in) { ; CHECK-LABEL: test_illegal_int_to_fp: ; CHECK: @ %bb.0: -; CHECK-NEXT: vcvt.f32.s32 q0, q0, #2 +; CHECK-NEXT: vmov.f32 s4, #4.000000e+00 +; CHECK-NEXT: vcvt.f32.s32 q2, q0 +; CHECK-NEXT: vdiv.f32 s2, s10, s4 +; CHECK-NEXT: vdiv.f32 s1, s9, s4 +; CHECK-NEXT: vdiv.f32 s0, s8, s4 +; CHECK-NEXT: vldr s3, LCPI12_0 ; CHECK-NEXT: bx lr +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: @ %bb.1: +; CHECK-NEXT: .data_region +; CHECK-NEXT: LCPI12_0: +; CHECK-NEXT: .long 0x7fc00000 @ float NaN +; CHECK-NEXT: .end_data_region %conv = sitofp <3 x i32> %in to <3 x float> %res = fdiv <3 x float> %conv, ret <3 x float> %res @@ -200,9 +263,7 @@ define arm_aapcs_vfpcc <3 x float> @test_illegal_int_to_fp(<3 x i32> %in) { define arm_aapcs_vfpcc <2 x float> @t1_mul(<2 x i32> %vecinit2.i) local_unnamed_addr #0 { ; CHECK-LABEL: t1_mul: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: vcvt.f32.s32 d16, d0 -; CHECK-NEXT: vmov.i32 d17, #0x3e000000 -; CHECK-NEXT: vmul.f32 d0, d16, d17 +; CHECK-NEXT: vcvt.f32.s32 d0, d0, #3 ; CHECK-NEXT: bx lr entry: %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> @@ -213,9 +274,7 @@ entry: define arm_aapcs_vfpcc <2 x float> @t2_mul(<2 x i32> %vecinit2.i) local_unnamed_addr #0 { ; CHECK-LABEL: t2_mul: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: vcvt.f32.u32 d16, d0 -; CHECK-NEXT: vmov.i32 d17, #0x3e000000 -; CHECK-NEXT: vmul.f32 d0, d16, d17 +; CHECK-NEXT: vcvt.f32.u32 d0, d0, #3 ; CHECK-NEXT: bx lr entry: %vcvt.i = uitofp <2 x i32> %vecinit2.i to <2 x float> @@ -239,10 +298,7 @@ entry: define arm_aapcs_vfpcc <2 x float> @t5_mul(<2 x i32> %vecinit2.i) local_unnamed_addr #0 { ; CHECK-LABEL: t5_mul: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: vcvt.f32.s32 d16, d0 -; CHECK-NEXT: mov r0, #796917760 -; CHECK-NEXT: vdup.32 d17, r0 -; CHECK-NEXT: vmul.f32 d0, d16, d17 +; CHECK-NEXT: vcvt.f32.s32 d0, d0, #32 ; CHECK-NEXT: bx lr entry: %vcvt.i = sitofp <2 x i32> %vecinit2.i to <2 x float> @@ -253,9 +309,7 @@ entry: define arm_aapcs_vfpcc <4 x float> @t6_mul(<4 x i32> %vecinit6.i) local_unnamed_addr #0 { ; CHECK-LABEL: t6_mul: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: vcvt.f32.s32 q8, q0 -; CHECK-NEXT: vmov.i32 q9, #0x3e000000 -; CHECK-NEXT: vmul.f32 q0, q8, q9 +; CHECK-NEXT: vcvt.f32.s32 q0, q0, #3 ; CHECK-NEXT: bx lr entry: %vcvt.i = sitofp <4 x i32> %vecinit6.i to <4 x float> @@ -267,9 +321,7 @@ define arm_aapcs_vfpcc <4 x float> @fix_unsigned_i16_to_float_mul(<4 x i16> %in) ; CHECK-LABEL: fix_unsigned_i16_to_float_mul: ; CHECK: @ %bb.0: ; CHECK-NEXT: vmovl.u16 q8, d0 -; CHECK-NEXT: vmov.i32 q9, #0x3f000000 -; CHECK-NEXT: vcvt.f32.u32 q8, q8 -; CHECK-NEXT: vmul.f32 q0, q8, q9 +; CHECK-NEXT: vcvt.f32.u32 q0, q8, #1 ; CHECK-NEXT: bx lr %conv = uitofp <4 x i16> %in to <4 x float> %shift = fmul <4 x float> %conv, @@ -280,9 +332,7 @@ define arm_aapcs_vfpcc <4 x float> @fix_signed_i16_to_float_mul(<4 x i16> %in) l ; CHECK-LABEL: fix_signed_i16_to_float_mul: ; CHECK: @ %bb.0: ; CHECK-NEXT: vmovl.s16 q8, d0 -; CHECK-NEXT: vmov.i32 q9, #0x3f000000 -; CHECK-NEXT: vcvt.f32.s32 q8, q8 -; CHECK-NEXT: vmul.f32 q0, q8, q9 +; CHECK-NEXT: vcvt.f32.s32 q0, q8, #1 ; CHECK-NEXT: bx lr %conv = sitofp <4 x i16> %in to <4 x float> %shift = fmul <4 x float> %conv, @@ -340,11 +390,8 @@ define arm_aapcs_vfpcc <2 x double> @fix_i64_to_double_mul(<2 x i64> %in) local_ define arm_aapcs_vfpcc <8 x float> @test7_mul(<8 x i32> %in) local_unnamed_addr #0 { ; CHECK-LABEL: test7_mul: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: vcvt.f32.s32 q8, q0 -; CHECK-NEXT: vcvt.f32.s32 q9, q1 -; CHECK-NEXT: vmov.i32 q10, #0x3e000000 -; CHECK-NEXT: vmul.f32 q0, q8, q10 -; CHECK-NEXT: vmul.f32 q1, q9, q10 +; CHECK-NEXT: vcvt.f32.s32 q0, q0, #3 +; CHECK-NEXT: vcvt.f32.s32 q1, q1, #3 ; CHECK-NEXT: bx lr entry: %vcvt.i = sitofp <8 x i32> %in to <8 x float> @@ -355,9 +402,7 @@ entry: define arm_aapcs_vfpcc <3 x float> @test_illegal_int_to_fp_mul(<3 x i32> %in) local_unnamed_addr #0 { ; CHECK-LABEL: test_illegal_int_to_fp_mul: ; CHECK: @ %bb.0: -; CHECK-NEXT: vcvt.f32.s32 q8, q0 -; CHECK-NEXT: vmov.f32 q9, #2.500000e-01 -; CHECK-NEXT: vmul.f32 q0, q8, q9 +; CHECK-NEXT: vcvt.f32.s32 q0, q0, #2 ; CHECK-NEXT: bx lr %conv = sitofp <3 x i32> %in to <3 x float> %res = fmul <3 x float> %conv, -- GitLab From ce73e17e3ab5ccfa33a977843e82a9bbfb6b4ce3 Mon Sep 17 00:00:00 2001 From: Vyacheslav Levytskyy Date: Mon, 3 Jun 2024 10:34:05 +0200 Subject: [PATCH 061/678] [SPIR-V] Validate type of the last parameter of OpGroupWaitEvents (#93661) This PR fixes invalid OpGroupWaitEvents emission to ensure that SPIR-V Backend inserts a bitcast before OpGroupWaitEvents if the last argument is a pointer that doesn't point to OpTypeEvent. --- llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp | 99 ++++++++++++++----- .../test/CodeGen/SPIRV/event-wait-ptr-type.ll | 28 ++++++ 2 files changed, 101 insertions(+), 26 deletions(-) create mode 100644 llvm/test/CodeGen/SPIRV/event-wait-ptr-type.ll diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp index 2bd22bbd6316..5ccbaf12ddee 100644 --- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp @@ -104,6 +104,47 @@ SPIRVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, return std::make_pair(0u, RC); } +inline Register getTypeReg(MachineRegisterInfo *MRI, Register OpReg) { + SPIRVType *TypeInst = MRI->getVRegDef(OpReg); + return TypeInst && TypeInst->getOpcode() == SPIRV::OpFunctionParameter + ? TypeInst->getOperand(1).getReg() + : OpReg; +} + +static void doInsertBitcast(const SPIRVSubtarget &STI, MachineRegisterInfo *MRI, + SPIRVGlobalRegistry &GR, MachineInstr &I, + Register OpReg, unsigned OpIdx, + SPIRVType *NewPtrType) { + Register NewReg = MRI->createGenericVirtualRegister(LLT::scalar(32)); + MachineIRBuilder MIB(I); + bool Res = MIB.buildInstr(SPIRV::OpBitcast) + .addDef(NewReg) + .addUse(GR.getSPIRVTypeID(NewPtrType)) + .addUse(OpReg) + .constrainAllUses(*STI.getInstrInfo(), *STI.getRegisterInfo(), + *STI.getRegBankInfo()); + if (!Res) + report_fatal_error("insert validation bitcast: cannot constrain all uses"); + MRI->setRegClass(NewReg, &SPIRV::IDRegClass); + GR.assignSPIRVTypeToVReg(NewPtrType, NewReg, MIB.getMF()); + I.getOperand(OpIdx).setReg(NewReg); +} + +static SPIRVType *createNewPtrType(SPIRVGlobalRegistry &GR, MachineInstr &I, + SPIRVType *OpType, bool ReuseType, + bool EmitIR, SPIRVType *ResType, + const Type *ResTy) { + SPIRV::StorageClass::StorageClass SC = + static_cast( + OpType->getOperand(1).getImm()); + MachineIRBuilder MIB(I); + SPIRVType *NewBaseType = + ReuseType ? ResType + : GR.getOrCreateSPIRVType( + ResTy, MIB, SPIRV::AccessQualifier::ReadWrite, EmitIR); + return GR.getOrCreateSPIRVPointerType(NewBaseType, MIB, SC); +} + // Insert a bitcast before the instruction to keep SPIR-V code valid // when there is a type mismatch between results and operand types. static void validatePtrTypes(const SPIRVSubtarget &STI, @@ -113,11 +154,7 @@ static void validatePtrTypes(const SPIRVSubtarget &STI, // Get operand type MachineFunction *MF = I.getParent()->getParent(); Register OpReg = I.getOperand(OpIdx).getReg(); - SPIRVType *TypeInst = MRI->getVRegDef(OpReg); - Register OpTypeReg = - TypeInst && TypeInst->getOpcode() == SPIRV::OpFunctionParameter - ? TypeInst->getOperand(1).getReg() - : OpReg; + Register OpTypeReg = getTypeReg(MRI, OpReg); SPIRVType *OpType = GR.getSPIRVTypeForVReg(OpTypeReg, MF); if (!ResType || !OpType || OpType->getOpcode() != SPIRV::OpTypePointer) return; @@ -134,30 +171,36 @@ static void validatePtrTypes(const SPIRVSubtarget &STI, return; // There is a type mismatch between results and operand types // and we insert a bitcast before the instruction to keep SPIR-V code valid - SPIRV::StorageClass::StorageClass SC = - static_cast( - OpType->getOperand(1).getImm()); - MachineIRBuilder MIB(I); - SPIRVType *NewBaseType = - IsSameMF ? ResType - : GR.getOrCreateSPIRVType( - ResTy, MIB, SPIRV::AccessQualifier::ReadWrite, false); - SPIRVType *NewPtrType = GR.getOrCreateSPIRVPointerType(NewBaseType, MIB, SC); + SPIRVType *NewPtrType = + createNewPtrType(GR, I, OpType, IsSameMF, false, ResType, ResTy); if (!GR.isBitcastCompatible(NewPtrType, OpType)) report_fatal_error( "insert validation bitcast: incompatible result and operand types"); - Register NewReg = MRI->createGenericVirtualRegister(LLT::scalar(32)); - bool Res = MIB.buildInstr(SPIRV::OpBitcast) - .addDef(NewReg) - .addUse(GR.getSPIRVTypeID(NewPtrType)) - .addUse(OpReg) - .constrainAllUses(*STI.getInstrInfo(), *STI.getRegisterInfo(), - *STI.getRegBankInfo()); - if (!Res) - report_fatal_error("insert validation bitcast: cannot constrain all uses"); - MRI->setRegClass(NewReg, &SPIRV::IDRegClass); - GR.assignSPIRVTypeToVReg(NewPtrType, NewReg, MIB.getMF()); - I.getOperand(OpIdx).setReg(NewReg); + doInsertBitcast(STI, MRI, GR, I, OpReg, OpIdx, NewPtrType); +} + +// Insert a bitcast before OpGroupWaitEvents if the last argument is a pointer +// that doesn't point to OpTypeEvent. +static void validateGroupWaitEventsPtr(const SPIRVSubtarget &STI, + MachineRegisterInfo *MRI, + SPIRVGlobalRegistry &GR, + MachineInstr &I) { + constexpr unsigned OpIdx = 2; + MachineFunction *MF = I.getParent()->getParent(); + Register OpReg = I.getOperand(OpIdx).getReg(); + Register OpTypeReg = getTypeReg(MRI, OpReg); + SPIRVType *OpType = GR.getSPIRVTypeForVReg(OpTypeReg, MF); + if (!OpType || OpType->getOpcode() != SPIRV::OpTypePointer) + return; + SPIRVType *ElemType = GR.getSPIRVTypeForVReg(OpType->getOperand(2).getReg()); + if (!ElemType || ElemType->getOpcode() == SPIRV::OpTypeEvent) + return; + // Insert a bitcast before the instruction to keep SPIR-V code valid. + LLVMContext &Context = MF->getMMI().getModule()->getContext(); + SPIRVType *NewPtrType = + createNewPtrType(GR, I, OpType, false, true, nullptr, + TargetExtType::get(Context, "spirv.Event")); + doInsertBitcast(STI, MRI, GR, I, OpReg, OpIdx, NewPtrType); } // Insert a bitcast before the function call instruction to keep SPIR-V code @@ -336,6 +379,10 @@ void SPIRVTargetLowering::finalizeLowering(MachineFunction &MF) const { SPIRV::OpTypeBool)) MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalNotEqual)); break; + case SPIRV::OpGroupWaitEvents: + // OpGroupWaitEvents ..., ..., + validateGroupWaitEventsPtr(STI, MRI, GR, MI); + break; case SPIRV::OpConstantI: { SPIRVType *Type = GR.getSPIRVTypeForVReg(MI.getOperand(1).getReg()); if (Type->getOpcode() != SPIRV::OpTypeInt && MI.getOperand(2).isImm() && diff --git a/llvm/test/CodeGen/SPIRV/event-wait-ptr-type.ll b/llvm/test/CodeGen/SPIRV/event-wait-ptr-type.ll new file mode 100644 index 000000000000..d6fb70bb59a7 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/event-wait-ptr-type.ll @@ -0,0 +1,28 @@ +; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK: %[[#EventTy:]] = OpTypeEvent +; CHECK: %[[#StructEventTy:]] = OpTypeStruct %[[#EventTy]] +; CHECK: %[[#GenPtrStructEventTy:]] = OpTypePointer Generic %[[#StructEventTy]] +; CHECK: %[[#FunPtrStructEventTy:]] = OpTypePointer Function %[[#StructEventTy]] +; CHECK: %[[#GenPtrEventTy:]] = OpTypePointer Generic %[[#EventTy:]] +; CHECK: OpFunction +; CHECK: %[[#Var:]] = OpVariable %[[#FunPtrStructEventTy]] Function +; CHECK-NEXT: %[[#AddrspacecastVar:]] = OpPtrCastToGeneric %[[#GenPtrStructEventTy]] %[[#Var]] +; CHECK-NEXT: %[[#BitcastVar:]] = OpBitcast %[[#GenPtrEventTy]] %[[#AddrspacecastVar]] +; CHECK-NEXT: OpGroupWaitEvents %[[#]] %[[#]] %[[#BitcastVar]] + +%"class.sycl::_V1::device_event" = type { target("spirv.Event") } + +define weak_odr dso_local spir_kernel void @foo() { +entry: + %var = alloca %"class.sycl::_V1::device_event" + %eventptr = addrspacecast ptr %var to ptr addrspace(4) + call spir_func void @_Z23__spirv_GroupWaitEventsjiP9ocl_event(i32 2, i32 1, ptr addrspace(4) %eventptr) + ret void +} + +declare dso_local spir_func void @_Z23__spirv_GroupWaitEventsjiP9ocl_event(i32, i32, ptr addrspace(4)) -- GitLab From 763b96c86d81d51d0db430791a61fd1e8a406bce Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Mon, 3 Jun 2024 10:34:44 +0200 Subject: [PATCH 062/678] [lldb] Avoid (unlimited) GetNumChildren calls when printing values (#93946) For some data formatters, even getting the number of children can be an expensive operations (e.g., needing to walk a linked list to determine the number of elements). This is then wasted work when we know we will be printing only small number of them. This patch replaces the calls to GetNumChildren (at least those on the "frame var" path) with the calls to the capped version, passing the value of `max-children-count` setting (plus one) --- lldb/source/DataFormatters/FormatManager.cpp | 10 ++++--- .../DataFormatters/ValueObjectPrinter.cpp | 27 ++++++++++--------- .../synthcapping/TestSyntheticCapping.py | 11 ++++++++ .../synthcapping/fooSynthProvider.py | 15 ++++++++++- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index 60765952760a..7e19989a8264 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -9,6 +9,7 @@ #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/LanguageCategory.h" #include "lldb/Interpreter/ScriptInterpreter.h" @@ -448,16 +449,19 @@ lldb::Format FormatManager::GetSingleItemFormat(lldb::Format vector_format) { } bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) { + TargetSP target_sp = valobj.GetTargetSP(); // if settings say no oneline whatsoever - if (valobj.GetTargetSP().get() && - !valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries()) + if (target_sp && !target_sp->GetDebugger().GetAutoOneLineSummaries()) return false; // then don't oneline // if this object has a summary, then ask the summary if (valobj.GetSummaryFormat().get() != nullptr) return valobj.GetSummaryFormat()->IsOneLiner(); - auto num_children = valobj.GetNumChildren(); + const size_t max_num_children = + (target_sp ? *target_sp : Target::GetGlobalProperties()) + .GetMaximumNumberOfChildrenToDisplay(); + auto num_children = valobj.GetNumChildren(max_num_children); if (!num_children) { llvm::consumeError(num_children.takeError()); return true; diff --git a/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/lldb/source/DataFormatters/ValueObjectPrinter.cpp index bbdc2a998157..c2933d857458 100644 --- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp +++ b/lldb/source/DataFormatters/ValueObjectPrinter.cpp @@ -14,6 +14,8 @@ #include "lldb/Target/Language.h" #include "lldb/Target/Target.h" #include "lldb/Utility/Stream.h" +#include "llvm/Support/MathExtras.h" +#include using namespace lldb; using namespace lldb_private; @@ -628,22 +630,21 @@ ValueObjectPrinter::GetMaxNumChildrenToPrint(bool &print_dotdotdot) { if (m_options.m_pointer_as_array) return m_options.m_pointer_as_array.m_element_count; - auto num_children_or_err = synth_valobj.GetNumChildren(); + const uint32_t max_num_children = + m_options.m_ignore_cap ? UINT32_MAX + : GetMostSpecializedValue() + .GetTargetSP() + ->GetMaximumNumberOfChildrenToDisplay(); + // Ask for one more child than the maximum to see if we should print "...". + auto num_children_or_err = synth_valobj.GetNumChildren( + llvm::SaturatingAdd(max_num_children, uint32_t(1))); if (!num_children_or_err) return num_children_or_err; - uint32_t num_children = *num_children_or_err; - print_dotdotdot = false; - if (num_children) { - const size_t max_num_children = GetMostSpecializedValue() - .GetTargetSP() - ->GetMaximumNumberOfChildrenToDisplay(); - - if (num_children > max_num_children && !m_options.m_ignore_cap) { - print_dotdotdot = true; - return max_num_children; - } + if (*num_children_or_err > max_num_children) { + print_dotdotdot = true; + return max_num_children; } - return num_children; + return num_children_or_err; } void ValueObjectPrinter::PrintChildrenPostamble(bool print_dotdotdot) { diff --git a/lldb/test/API/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py b/lldb/test/API/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py index d53dadef836e..9ca232abefa0 100644 --- a/lldb/test/API/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py +++ b/lldb/test/API/functionalities/data-formatter/synthcapping/TestSyntheticCapping.py @@ -68,6 +68,11 @@ class SyntheticCappingTestCase(TestBase): "r = 34", ], ) + # num_children() should be called with at most max_num_children=257 + # (target.max-children-count + 1) + self.expect( + "script fooSynthProvider.reset_max_num_children_max()", substrs=["257"] + ) # check that capping works self.runCmd("settings set target.max-children-count 2", check=False) @@ -80,9 +85,15 @@ class SyntheticCappingTestCase(TestBase): "...", ], ) + self.expect( + "script fooSynthProvider.reset_max_num_children_max()", substrs=["3"] + ) self.expect("frame variable f00_1", matching=False, substrs=["r = 34"]) self.runCmd("settings set target.max-children-count 256", check=False) self.expect("frame variable f00_1", matching=True, substrs=["r = 34"]) + self.expect( + "script fooSynthProvider.reset_max_num_children_max()", substrs=["257"] + ) diff --git a/lldb/test/API/functionalities/data-formatter/synthcapping/fooSynthProvider.py b/lldb/test/API/functionalities/data-formatter/synthcapping/fooSynthProvider.py index 3bfa3130cc01..5ea392ac8829 100644 --- a/lldb/test/API/functionalities/data-formatter/synthcapping/fooSynthProvider.py +++ b/lldb/test/API/functionalities/data-formatter/synthcapping/fooSynthProvider.py @@ -2,11 +2,24 @@ import lldb class fooSynthProvider: + # For testing purposes, we'll keep track of the maximum value of + # max_num_children we've been called with. + MAX_NUM_CHILDREN_MAX = 0 + + @classmethod + def reset_max_num_children_max(cls): + old_value = fooSynthProvider.MAX_NUM_CHILDREN_MAX + fooSynthProvider.MAX_NUM_CHILDREN_MAX = 0 + return old_value + def __init__(self, valobj, dict): self.valobj = valobj self.int_type = valobj.GetType().GetBasicType(lldb.eBasicTypeInt) - def num_children(self): + def num_children(self, max_num_children): + fooSynthProvider.MAX_NUM_CHILDREN_MAX = max( + fooSynthProvider.MAX_NUM_CHILDREN_MAX, max_num_children + ) return 3 def get_child_at_index(self, index): -- GitLab From 09c0607919c958c1a816acd58cc6c6585aec51a6 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Mon, 3 Jun 2024 09:01:04 +0000 Subject: [PATCH 063/678] [lldb][test] Skip D lang mangling test on Windows While the fix is reviewed. --- lldb/test/API/lang/c/non-mangled/TestCNonMangled.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py b/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py index aae2f05263fc..c35d8a9bb916 100644 --- a/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py +++ b/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py @@ -3,6 +3,7 @@ from lldbsuite.test.lldbtest import * class TestCase(TestBase): + @skipIfWindows def test_functions_having_dlang_mangling_prefix(self): """ Ensure C functions with a '_D' prefix alone are not mistakenly treated -- GitLab From 8918d35dbde126c95350b674a2bb102692d90260 Mon Sep 17 00:00:00 2001 From: David Stone Date: Mon, 3 Jun 2024 03:09:13 -0600 Subject: [PATCH 064/678] [clang][Modules] Move `ASTSourceDescriptor` into its own file (#67930) --- .../include/clang/Basic/ASTSourceDescriptor.h | 52 +++++++++++++++++++ clang/include/clang/Basic/Module.h | 26 ---------- clang/lib/AST/ExternalASTSource.cpp | 2 +- clang/lib/Basic/ASTSourceDescriptor.cpp | 33 ++++++++++++ clang/lib/Basic/CMakeLists.txt | 1 + clang/lib/Basic/Module.cpp | 15 ------ clang/lib/CodeGen/CGDebugInfo.h | 3 +- clang/lib/Serialization/ASTReader.cpp | 1 + .../Plugins/ExpressionParser/Clang/ASTUtils.h | 8 ++- .../Clang/ClangExternalASTSourceCallbacks.cpp | 1 + .../Clang/ClangExternalASTSourceCallbacks.h | 8 ++- 11 files changed, 105 insertions(+), 45 deletions(-) create mode 100644 clang/include/clang/Basic/ASTSourceDescriptor.h create mode 100644 clang/lib/Basic/ASTSourceDescriptor.cpp diff --git a/clang/include/clang/Basic/ASTSourceDescriptor.h b/clang/include/clang/Basic/ASTSourceDescriptor.h new file mode 100644 index 000000000000..175e0551db76 --- /dev/null +++ b/clang/include/clang/Basic/ASTSourceDescriptor.h @@ -0,0 +1,52 @@ +//===- ASTSourceDescriptor.h -----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file +/// Defines the clang::ASTSourceDescriptor class, which abstracts clang modules +/// and precompiled header files +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H +#define LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H + +#include "clang/Basic/Module.h" +#include "llvm/ADT/StringRef.h" +#include +#include + +namespace clang { + +/// Abstracts clang modules and precompiled header files and holds +/// everything needed to generate debug info for an imported module +/// or PCH. +class ASTSourceDescriptor { + StringRef PCHModuleName; + StringRef Path; + StringRef ASTFile; + ASTFileSignature Signature; + Module *ClangModule = nullptr; + +public: + ASTSourceDescriptor() = default; + ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, + ASTFileSignature Signature) + : PCHModuleName(std::move(Name)), Path(std::move(Path)), + ASTFile(std::move(ASTFile)), Signature(Signature) {} + ASTSourceDescriptor(Module &M); + + std::string getModuleName() const; + StringRef getPath() const { return Path; } + StringRef getASTFile() const { return ASTFile; } + ASTFileSignature getSignature() const { return Signature; } + Module *getModuleOrNull() const { return ClangModule; } +}; + +} // namespace clang + +#endif // LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index 2d62d05cd919..e86f4303d732 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -868,32 +868,6 @@ private: unsigned Generation = 0; }; -/// Abstracts clang modules and precompiled header files and holds -/// everything needed to generate debug info for an imported module -/// or PCH. -class ASTSourceDescriptor { - StringRef PCHModuleName; - StringRef Path; - StringRef ASTFile; - ASTFileSignature Signature; - Module *ClangModule = nullptr; - -public: - ASTSourceDescriptor() = default; - ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, - ASTFileSignature Signature) - : PCHModuleName(std::move(Name)), Path(std::move(Path)), - ASTFile(std::move(ASTFile)), Signature(Signature) {} - ASTSourceDescriptor(Module &M); - - std::string getModuleName() const; - StringRef getPath() const { return Path; } - StringRef getASTFile() const { return ASTFile; } - ASTFileSignature getSignature() const { return Signature; } - Module *getModuleOrNull() const { return ClangModule; } -}; - - } // namespace clang #endif // LLVM_CLANG_BASIC_MODULE_H diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp index e96a47496851..a5b6f80bde69 100644 --- a/clang/lib/AST/ExternalASTSource.cpp +++ b/clang/lib/AST/ExternalASTSource.cpp @@ -15,10 +15,10 @@ #include "clang/AST/ExternalASTSource.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclarationName.h" +#include "clang/Basic/ASTSourceDescriptor.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/ErrorHandling.h" #include diff --git a/clang/lib/Basic/ASTSourceDescriptor.cpp b/clang/lib/Basic/ASTSourceDescriptor.cpp new file mode 100644 index 000000000000..8072c08a51d3 --- /dev/null +++ b/clang/lib/Basic/ASTSourceDescriptor.cpp @@ -0,0 +1,33 @@ +//===- ASTSourceDescriptor.cpp -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// Defines the clang::ASTSourceDescriptor class, which abstracts clang modules +/// and precompiled header files +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/ASTSourceDescriptor.h" + +namespace clang { + +ASTSourceDescriptor::ASTSourceDescriptor(Module &M) + : Signature(M.Signature), ClangModule(&M) { + if (M.Directory) + Path = M.Directory->getName(); + if (auto File = M.getASTFile()) + ASTFile = File->getName(); +} + +std::string ASTSourceDescriptor::getModuleName() const { + if (ClangModule) + return ClangModule->Name; + else + return std::string(PCHModuleName); +} + +} // namespace clang diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index 824d4a0e2eee..f30680552e0f 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -55,6 +55,7 @@ if(CLANG_VENDOR) endif() add_clang_library(clangBasic + ASTSourceDescriptor.cpp Attributes.cpp Builtins.cpp CLWarnings.cpp diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index 045ef580f9c3..90b7b0d24bb6 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -724,18 +724,3 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, }; VisitModule({M, nullptr}); } - -ASTSourceDescriptor::ASTSourceDescriptor(Module &M) - : Signature(M.Signature), ClangModule(&M) { - if (M.Directory) - Path = M.Directory->getName(); - if (auto File = M.getASTFile()) - ASTFile = File->getName(); -} - -std::string ASTSourceDescriptor::getModuleName() const { - if (ClangModule) - return ClangModule->Name; - else - return std::string(PCHModuleName); -} diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index d6db4d711366..8fe738be2156 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -20,8 +20,8 @@ #include "clang/AST/PrettyPrinter.h" #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" +#include "clang/Basic/ASTSourceDescriptor.h" #include "clang/Basic/CodeGenOptions.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -38,6 +38,7 @@ class MDNode; namespace clang { class ClassTemplateSpecializationDecl; class GlobalDecl; +class Module; class ModuleMap; class ObjCInterfaceDecl; class UsingDecl; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 7f17e09adc29..da99d09de0aa 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -40,6 +40,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeLocVisitor.h" #include "clang/AST/UnresolvedSet.h" +#include "clang/Basic/ASTSourceDescriptor.h" #include "clang/Basic/CommentOptions.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticError.h" diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h index 17f1506036c6..da2b1a15f746 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h @@ -9,13 +9,19 @@ #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H -#include "clang/Basic/Module.h" +#include "clang/Basic/ASTSourceDescriptor.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/MultiplexExternalSemaSource.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaConsumer.h" #include +namespace clang { + +class Module; + +} // namespace clang + namespace lldb_private { /// Wraps an ExternalASTSource into an ExternalSemaSource. Doesn't take diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp index 89d9ac042e57..e746e6afe39b 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp @@ -11,6 +11,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" +#include "clang/Basic/Module.h" #include using namespace lldb_private; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h index 219ed641615e..6bd18186a567 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h @@ -10,9 +10,15 @@ #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "clang/Basic/Module.h" +#include "clang/Basic/ASTSourceDescriptor.h" #include +namespace clang { + +class Module; + +} // namespace clang + namespace lldb_private { class ClangExternalASTSourceCallbacks : public clang::ExternalASTSource { -- GitLab From 6a217307641972e27f9eee1adb80e649e10f229f Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Mon, 3 Jun 2024 10:16:10 +0100 Subject: [PATCH 065/678] [flang][OpenMP][NFC] Reduce FunctionFiltering pass boilerplate (#93951) The pass constructor can be generated automatically. This pass doesn't need to be adapted to support other top level operations because it is specifically supposed to filter functions. We don't need to filter non-function top level operations because without use inside of functions they shouldn't lead to any codegen. --- flang/include/flang/Optimizer/Transforms/Passes.h | 3 +-- flang/include/flang/Optimizer/Transforms/Passes.td | 1 - flang/include/flang/Tools/CLOptions.inc | 2 +- flang/lib/Optimizer/Transforms/OMPFunctionFiltering.cpp | 4 ---- 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index 46c38d107eec..a7ba704fdb39 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -53,6 +53,7 @@ namespace fir { #define GEN_PASS_DECL_ADDALIASTAGS #define GEN_PASS_DECL_OMPMAPINFOFINALIZATIONPASS #define GEN_PASS_DECL_OMPMARKDECLARETARGETPASS +#define GEN_PASS_DECL_OMPFUNCTIONFILTERING #include "flang/Optimizer/Transforms/Passes.h.inc" std::unique_ptr createAffineDemotionPass(); @@ -72,8 +73,6 @@ std::unique_ptr createAlgebraicSimplificationPass(); std::unique_ptr createAlgebraicSimplificationPass(const mlir::GreedyRewriteConfig &config); -std::unique_ptr createOMPFunctionFilteringPass(); - std::unique_ptr createVScaleAttrPass(); std::unique_ptr createVScaleAttrPass(std::pair vscaleAttr); diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index f03412807d40..82638200e5e2 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -343,7 +343,6 @@ def OMPMarkDeclareTargetPass def OMPFunctionFiltering : Pass<"omp-function-filtering"> { let summary = "Filters out functions intended for the host when compiling " "for the target device."; - let constructor = "::fir::createOMPFunctionFilteringPass()"; let dependentDialects = [ "mlir::func::FuncDialect", "fir::FIROpsDialect" diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index e0141a3d76f0..cca3344da02a 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -349,7 +349,7 @@ inline void createOpenMPFIRPassPipeline( pm, fir::createOMPMapInfoFinalizationPass); pm.addPass(fir::createOMPMarkDeclareTargetPass()); if (isTargetDevice) - pm.addPass(fir::createOMPFunctionFilteringPass()); + pm.addPass(fir::createOMPFunctionFiltering()); } #if !defined(FLANG_EXCLUDE_CODEGEN) diff --git a/flang/lib/Optimizer/Transforms/OMPFunctionFiltering.cpp b/flang/lib/Optimizer/Transforms/OMPFunctionFiltering.cpp index 005e84cb8e9f..0c472246c2a4 100644 --- a/flang/lib/Optimizer/Transforms/OMPFunctionFiltering.cpp +++ b/flang/lib/Optimizer/Transforms/OMPFunctionFiltering.cpp @@ -103,7 +103,3 @@ public: } }; } // namespace - -std::unique_ptr fir::createOMPFunctionFilteringPass() { - return std::make_unique(); -} -- GitLab From 770b6c792472e1ff87e8598728d37c516861218e Mon Sep 17 00:00:00 2001 From: David Spickett Date: Mon, 3 Jun 2024 09:16:00 +0000 Subject: [PATCH 066/678] [lldb][test] Add missing import in D lang mangling test --- lldb/test/API/lang/c/non-mangled/TestCNonMangled.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py b/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py index c35d8a9bb916..b10a3d6da30a 100644 --- a/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py +++ b/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py @@ -1,5 +1,6 @@ import lldbsuite.test.lldbutil as lldbutil from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import skipIfWindows class TestCase(TestBase): -- GitLab From 6abf361953e9c5d019a72fd83765498d269eb080 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Mon, 3 Jun 2024 10:18:39 +0100 Subject: [PATCH 067/678] [lldb][test] Fix D lang mangling test on Windows (#94196) On Windows the function does not have a symbol associated with it: Function: id = {0x000001c9}, name = "_Dfunction", range = [0x0000000140001000-0x0000000140001004) LineEntry: <...> Whereas it does on Linux: Function: id = {0x00000023}, name = "_Dfunction", range = [0x0000000000000734-0x0000000000000738) LineEntry: <...> Symbol: id = {0x00000058}, range = [0x0000000000000734-0x0000000000000738), name="_Dfunction" This means that frame.symbol is not valid on Windows. However, frame.function is valid and it also has a "mangled" attribute. So I've updated the test to check the symbol if we've got it, and the function always. In both cases we check that mangled is empty (meaning it has not been treated as mangled) and that the display name matches the original symbol name. --- .../API/lang/c/non-mangled/TestCNonMangled.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py b/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py index b10a3d6da30a..6f7ef247b063 100644 --- a/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py +++ b/lldb/test/API/lang/c/non-mangled/TestCNonMangled.py @@ -1,10 +1,8 @@ import lldbsuite.test.lldbutil as lldbutil from lldbsuite.test.lldbtest import * -from lldbsuite.test.decorators import skipIfWindows class TestCase(TestBase): - @skipIfWindows def test_functions_having_dlang_mangling_prefix(self): """ Ensure C functions with a '_D' prefix alone are not mistakenly treated @@ -13,5 +11,14 @@ class TestCase(TestBase): """ self.build() _, _, thread, _ = lldbutil.run_to_name_breakpoint(self, "_Dfunction") - symbol = thread.frame[0].symbol - self.assertEqual(symbol.GetDisplayName(), "_Dfunction") + frame = thread.frame[0] + + symbol = frame.symbol + # On Windows the function does not have an associated symbol. + if symbol.IsValid(): + self.assertFalse(symbol.mangled) + self.assertEqual(symbol.GetDisplayName(), "_Dfunction") + + function = frame.function + self.assertFalse(function.mangled) + self.assertEqual(function.GetDisplayName(), "_Dfunction") -- GitLab From d00731cb7fcc91047531069e029964a39935a5bb Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Mon, 3 Jun 2024 11:12:54 +0200 Subject: [PATCH 068/678] [lldb] s/assertEquals/assertEqual in TestDAP_variables_children --- .../lldb-dap/variables/children/TestDAP_variables_children.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py b/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py index 54fb318289ae..805e88ddf8f7 100644 --- a/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py +++ b/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py @@ -31,7 +31,7 @@ class TestDAP_variables_children(lldbdap_testcase.DAPTestCaseBase): indexed = next(filter(lambda x: x["name"] == "indexed", local_vars)) not_indexed = next(filter(lambda x: x["name"] == "not_indexed", local_vars)) self.assertIn("indexedVariables", indexed) - self.assertEquals(indexed["indexedVariables"], 1) + self.assertEqual(indexed["indexedVariables"], 1) self.assertNotIn("indexedVariables", not_indexed) self.assertIn( -- GitLab From 6b7444964a8d028989beee554a1f5c61d16a1cac Mon Sep 17 00:00:00 2001 From: AlexGhiti Date: Mon, 3 Jun 2024 11:27:02 +0200 Subject: [PATCH 069/678] [RISCV] Remove experimental from Zabha (#93831) The Zabha extension was ratified in April 2024. Co-authored-by: Alexandre Ghiti --- .../test/Preprocessor/riscv-target-features.c | 18 +++++++++--------- llvm/docs/RISCVUsage.rst | 4 +--- llvm/docs/ReleaseNotes.rst | 1 + llvm/lib/Target/RISCV/RISCVFeatures.td | 4 ++-- .../RISCV/atomic-cmpxchg-branch-on-result.ll | 2 +- llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll | 4 ++-- llvm/test/CodeGen/RISCV/atomic-rmw.ll | 8 ++++---- llvm/test/CodeGen/RISCV/attributes.ll | 4 ++-- llvm/test/MC/RISCV/rvzabha-invalid.s | 4 ++-- llvm/test/MC/RISCV/rvzabha-valid.s | 12 ++++++------ llvm/test/MC/RISCV/rvzabha-zacas-valid.s | 16 ++++++++-------- .../TargetParser/RISCVISAInfoTest.cpp | 2 +- 12 files changed, 39 insertions(+), 40 deletions(-) diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index 0865add7e8fb..09b9ad0a160b 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -80,6 +80,7 @@ // CHECK-NOT: __riscv_za128rs {{.*$}} // CHECK-NOT: __riscv_za64rs {{.*$}} // CHECK-NOT: __riscv_zaamo {{.*$}} +// CHECK-NOT: __riscv_zabha {{.*$}} // CHECK-NOT: __riscv_zacas {{.*$}} // CHECK-NOT: __riscv_zalrsc {{.*$}} // CHECK-NOT: __riscv_zama16b {{.*$}} @@ -176,7 +177,6 @@ // CHECK-NOT: __riscv_sspm{{.*$}} // CHECK-NOT: __riscv_ssqosid{{.*$}} // CHECK-NOT: __riscv_supm{{.*$}} -// CHECK-NOT: __riscv_zabha {{.*$}} // CHECK-NOT: __riscv_zalasr {{.*$}} // CHECK-NOT: __riscv_zfbfmin {{.*$}} // CHECK-NOT: __riscv_zicfilp {{.*$}} @@ -715,6 +715,14 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-ZAAMO-EXT %s // CHECK-ZAAMO-EXT: __riscv_zaamo 1000000{{$}} +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32ia_zabha1p0 -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZABHA-EXT %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64ia_zabha1p0 -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZABHA-EXT %s +// CHECK-ZABHA-EXT: __riscv_zabha 1000000{{$}} + // RUN: %clang --target=riscv32 \ // RUN: -march=rv32ia_zacas1p0 -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s @@ -1570,14 +1578,6 @@ // CHECK-ZVKT-EXT: __riscv_zvkt 1000000{{$}} // Experimental extensions -// RUN: %clang --target=riscv32 -menable-experimental-extensions \ -// RUN: -march=rv32ia_zabha1p0 -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-ZABHA-EXT %s -// RUN: %clang --target=riscv64 -menable-experimental-extensions \ -// RUN: -march=rv64ia_zabha1p0 -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-ZABHA-EXT %s -// CHECK-ZABHA-EXT: __riscv_zabha 1000000{{$}} - // RUN: %clang --target=riscv32 -menable-experimental-extensions \ // RUN: -march=rv32i_zalasr0p1 -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZALASR-EXT %s diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index 5ecee2a480f7..35115e67ecf9 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -120,6 +120,7 @@ on support follow. ``Za128rs`` Supported (`See note <#riscv-profiles-extensions-note>`__) ``Za64rs`` Supported (`See note <#riscv-profiles-extensions-note>`__) ``Zaamo`` Assembly Support + ``Zabha`` Supported ``Zacas`` Supported (`See note <#riscv-zacas-note>`__) ``Zalrsc`` Assembly Support ``Zama16b`` Supported (`See note <#riscv-profiles-extensions-note>`__) @@ -262,9 +263,6 @@ The primary goal of experimental support is to assist in the process of ratifica ``experimental-ssqosid`` LLVM implements assembler support for the `v1.0-rc1 draft specification `_. -``experimental-zabha`` - LLVM implements the `v1.0-rc1 draft specification `__. - ``experimental-zalasr`` LLVM implements the `0.0.5 draft specification `__. diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index c7c2c2825f58..32ec26bf1dcb 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -136,6 +136,7 @@ Changes to the RISC-V Backend * Added smstateen extension to -march. CSR names for smstateen were already supported. * Zaamo and Zalrsc are no longer experimental. * Processors that enable post reg-alloc scheduling (PostMachineScheduler) by default should use the `UsePostRAScheduler` subtarget feature. Setting `PostRAScheduler = 1` in the scheduler model will have no effect on the enabling of the PostMachineScheduler. +* Zabha is no longer experimental. Changes to the WebAssembly Backend ---------------------------------- diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index a78d78946be3..9bf06850483d 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -221,8 +221,8 @@ def HasStdExtAOrZaamo "'Zaamo' (Atomic Memory Operations)">; def FeatureStdExtZabha - : RISCVExperimentalExtension<"zabha", 1, 0, - "'Zabha' (Byte and Halfword Atomic Memory Operations)">; + : RISCVExtension<"zabha", 1, 0, + "'Zabha' (Byte and Halfword Atomic Memory Operations)">; def HasStdExtZabha : Predicate<"Subtarget->hasStdExtZabha()">, AssemblerPredicate<(all_of FeatureStdExtZabha), "'Zabha' (Byte and Halfword Atomic Memory Operations)">; diff --git a/llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll b/llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll index 18b66499b85f..e6462ef93998 100644 --- a/llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll +++ b/llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll @@ -7,7 +7,7 @@ ; RUN: | FileCheck -check-prefixes=NOZACAS,RV64IA %s ; RUN: llc -mtriple=riscv64 -mattr=+a,+zacas -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=ZACAS,RV64IA-ZACAS %s -; RUN: llc -mtriple=riscv64 -mattr=+a,+zacas,+experimental-zabha -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv64 -mattr=+a,+zacas,+zabha -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=ZACAS,RV64IA-ZABHA %s ; Test cmpxchg followed by a branch on the cmpxchg success value to see if the diff --git a/llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll b/llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll index 394dffa346ec..341d4c90e638 100644 --- a/llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll +++ b/llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll @@ -15,13 +15,13 @@ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-WMO %s ; RUN: llc -mtriple=riscv64 -mattr=+a,+zacas -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-ZACAS,RV64IA-WMO-ZACAS %s -; RUN: llc -mtriple=riscv64 -mattr=+a,+zacas,+experimental-zabha -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv64 -mattr=+a,+zacas,+zabha -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-ZABHA,RV64IA-WMO-ZABHA %s ; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-TSO %s ; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso,+zacas -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-ZACAS,RV64IA-TSO-ZACAS %s -; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso,+zacas,+experimental-zabha -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso,+zacas,+zabha -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-ZABHA,RV64IA-TSO-ZABHA %s define void @cmpxchg_i8_monotonic_monotonic(ptr %ptr, i8 %cmp, i8 %val) nounwind { diff --git a/llvm/test/CodeGen/RISCV/atomic-rmw.ll b/llvm/test/CodeGen/RISCV/atomic-rmw.ll index 4871622ec236..e95846b72009 100644 --- a/llvm/test/CodeGen/RISCV/atomic-rmw.ll +++ b/llvm/test/CodeGen/RISCV/atomic-rmw.ll @@ -21,13 +21,13 @@ ; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso,+zacas -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-ZACAS,RV64IA-TSO,RV64IA-TSO-ZACAS %s -; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-zabha -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv64 -mattr=+a,+zabha -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-WMO,RV64IA-WMO-ZABHA,RV64IA-WMO-ZABHA-NOZACAS %s -; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso,+experimental-zabha -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso,+zabha -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-TSO,RV64IA-TSO-ZABHA,RV64IA-TSO-ZABHA-NOZACAS %s -; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-zabha,+zacas -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv64 -mattr=+a,+zabha,+zacas -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-WMO,RV64IA-WMO-ZABHA,RV64IA-WMO-ZABHA-ZACAS %s -; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso,+experimental-zabha,+zacas -verify-machineinstrs < %s \ +; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-ztso,+zabha,+zacas -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefixes=RV64IA,RV64IA-TSO,RV64IA-TSO-ZABHA,RV64IA-TSO-ZABHA-ZACAS %s define i8 @atomicrmw_xchg_i8_monotonic(ptr %a, i8 %b) nounwind { diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index c90bb031e082..1c9356fb1a05 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -118,7 +118,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zalasr %s -o - | FileCheck --check-prefix=RV32ZALASR %s ; RUN: llc -mtriple=riscv32 -mattr=+zama16b %s -o - | FileCheck --check-prefixes=CHECK,RV32ZAMA16B %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV32ZICFILP %s -; RUN: llc -mtriple=riscv32 -mattr=+a,+experimental-zabha %s -o - | FileCheck --check-prefix=RV32ZABHA %s +; RUN: llc -mtriple=riscv32 -mattr=+a,+zabha %s -o - | FileCheck --check-prefix=RV32ZABHA %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-ssnpm %s -o - | FileCheck --check-prefix=RV32SSNPM %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-smnpm %s -o - | FileCheck --check-prefix=RV32SMNPM %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-smmpm %s -o - | FileCheck --check-prefix=RV32SMMPM %s @@ -250,7 +250,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+a,zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zalasr %s -o - | FileCheck --check-prefix=RV64ZALASR %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV64ZICFILP %s -; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-zabha %s -o - | FileCheck --check-prefix=RV64ZABHA %s +; RUN: llc -mtriple=riscv64 -mattr=+a,+zabha %s -o - | FileCheck --check-prefix=RV64ZABHA %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-ssnpm %s -o - | FileCheck --check-prefix=RV64SSNPM %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-smnpm %s -o - | FileCheck --check-prefix=RV64SMNPM %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-smmpm %s -o - | FileCheck --check-prefix=RV64SMMPM %s diff --git a/llvm/test/MC/RISCV/rvzabha-invalid.s b/llvm/test/MC/RISCV/rvzabha-invalid.s index 62cb1d8c8913..dda987c146d4 100644 --- a/llvm/test/MC/RISCV/rvzabha-invalid.s +++ b/llvm/test/MC/RISCV/rvzabha-invalid.s @@ -1,5 +1,5 @@ -# RUN: not llvm-mc -triple riscv32 -mattr=+a,+experimental-zabha < %s 2>&1 | FileCheck %s -# RUN: not llvm-mc -triple riscv64 -mattr=+a,+experimental-zabha < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -triple riscv32 -mattr=+a,+zabha < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -triple riscv64 -mattr=+a,+zabha < %s 2>&1 | FileCheck %s # Final operand must have parentheses amoswap.b a1, a2, a3 # CHECK: :[[@LINE]]:19: error: expected '(' or optional integer offset diff --git a/llvm/test/MC/RISCV/rvzabha-valid.s b/llvm/test/MC/RISCV/rvzabha-valid.s index 333e58d1268e..a3c61dbb570c 100644 --- a/llvm/test/MC/RISCV/rvzabha-valid.s +++ b/llvm/test/MC/RISCV/rvzabha-valid.s @@ -1,12 +1,12 @@ -# RUN: llvm-mc %s -triple=riscv32 -mattr=+a,+experimental-zabha -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+a,+zabha -riscv-no-aliases -show-encoding \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s -# RUN: llvm-mc %s -triple=riscv64 -mattr=+a,+experimental-zabha -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+a,+zabha -riscv-no-aliases -show-encoding \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s -# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+a,+experimental-zabha < %s \ -# RUN: | llvm-objdump --mattr=+a,+experimental-zabha -M no-aliases -d -r - \ +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+a,+zabha < %s \ +# RUN: | llvm-objdump --mattr=+a,+zabha -M no-aliases -d -r - \ # RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s -# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+a,+experimental-zabha < %s \ -# RUN: | llvm-objdump --mattr=+a,+experimental-zabha -M no-aliases -d -r - \ +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+a,+zabha < %s \ +# RUN: | llvm-objdump --mattr=+a,+zabha -M no-aliases -d -r - \ # RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s # CHECK-ASM-AND-OBJ: amoswap.b a4, ra, (s0) diff --git a/llvm/test/MC/RISCV/rvzabha-zacas-valid.s b/llvm/test/MC/RISCV/rvzabha-zacas-valid.s index 994112c6b6e5..97afb9d6563e 100644 --- a/llvm/test/MC/RISCV/rvzabha-zacas-valid.s +++ b/llvm/test/MC/RISCV/rvzabha-zacas-valid.s @@ -1,16 +1,16 @@ -# RUN: llvm-mc %s -triple=riscv32 -mattr=+a,+experimental-zabha,+zacas -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+a,+zabha,+zacas -riscv-no-aliases -show-encoding \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s -# RUN: llvm-mc %s -triple=riscv64 -mattr=+a,+experimental-zabha,+zacas -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+a,+zabha,+zacas -riscv-no-aliases -show-encoding \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s -# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+a,+experimental-zabha,+zacas < %s \ -# RUN: | llvm-objdump --mattr=+a,+experimental-zabha,+zacas -M no-aliases -d -r - \ +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+a,+zabha,+zacas < %s \ +# RUN: | llvm-objdump --mattr=+a,+zabha,+zacas -M no-aliases -d -r - \ # RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s -# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+a,+experimental-zabha,+zacas < %s \ -# RUN: | llvm-objdump --mattr=+a,+experimental-zabha,+zacas -M no-aliases -d -r - \ +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+a,+zabha,+zacas < %s \ +# RUN: | llvm-objdump --mattr=+a,+zabha,+zacas -M no-aliases -d -r - \ # RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s -# RUN: not llvm-mc -triple=riscv32 -mattr=+a,+experimental-zabha -show-encoding %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+a,+zabha -show-encoding %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-ERROR -# RUN: not llvm-mc -triple=riscv64 -mattr=+a,+experimental-zabha -show-encoding %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -mattr=+a,+zabha -show-encoding %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-ERROR # CHECK-ASM-AND-OBJ: amocas.b a1, a3, (a5) diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index df4066980093..22a8a05ef371 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -935,6 +935,7 @@ R"(All available -march extensions for RISC-V za128rs 1.0 za64rs 1.0 zaamo 1.0 + zabha 1.0 zacas 1.0 zalrsc 1.0 zama16b 1.0 @@ -1062,7 +1063,6 @@ R"(All available -march extensions for RISC-V Experimental extensions zicfilp 0.4 This is a long dummy description zicfiss 0.4 - zabha 1.0 zalasr 0.1 zfbfmin 1.0 ztso 0.1 -- GitLab From 5bfc444524d74b714b9efb2dc00c7bc36a3838e2 Mon Sep 17 00:00:00 2001 From: Kareem Ergawy Date: Mon, 3 Jun 2024 11:33:00 +0200 Subject: [PATCH 070/678] [flang] Emit `argNo` debug info only for `func` block args (#93921) Fixes a bug uncovered by [pr43337.f90](https://github.com/llvm/llvm-test-suite/blob/main/Fortran/gfortran/regression/gomp/pr43337.f90) in the test suite. In particular, this emits `argNo` debug info only if the parent op of a block is a `func.func` op. This avoids DI conflicts when a function contains a nested OpenMP region that itself has block arguments with DI attached to them; for example, `omp.parallel` with delayed privatization enabled. --- .../flang/Optimizer/Dialect/FIROpsSupport.h | 1 + flang/lib/Optimizer/Analysis/AliasAnalysis.cpp | 12 +----------- flang/lib/Optimizer/Dialect/FIROps.cpp | 10 ++++++++++ flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 7 ++++--- flang/test/Lower/OpenMP/debug_info_conflict.f90 | 16 ++++++++++++++++ 5 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 flang/test/Lower/OpenMP/debug_info_conflict.f90 diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h index b68a39bf374b..47b80cca5d64 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h +++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h @@ -160,6 +160,7 @@ inline mlir::NamedAttribute getAdaptToByRefAttr(Builder &builder) { builder.getUnitAttr()}; } +bool isDummyArgument(mlir::Value v); } // namespace fir #endif // FORTRAN_OPTIMIZER_DIALECT_FIROPSSUPPORT_H diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp index 9d0d706a85c5..fd40386a6d81 100644 --- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp +++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp @@ -28,16 +28,6 @@ using namespace mlir; // AliasAnalysis: alias //===----------------------------------------------------------------------===// -static bool isDummyArgument(mlir::Value v) { - auto blockArg{mlir::dyn_cast(v)}; - if (!blockArg) - return false; - - auto *owner{blockArg.getOwner()}; - return owner->isEntryBlock() && - mlir::isa(owner->getParentOp()); -} - /// Temporary function to skip through all the no op operations /// TODO: Generalize support of fir.load static mlir::Value getOriginalDef(mlir::Value v) { @@ -85,7 +75,7 @@ bool AliasAnalysis::Source::isTargetOrPointer() const { bool AliasAnalysis::Source::isDummyArgument() const { if (auto v = origin.u.dyn_cast()) { - return ::isDummyArgument(v); + return fir::isDummyArgument(v); } return false; } diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index b541b7cdc7a5..9672cdccc111 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -3908,6 +3908,16 @@ std::optional fir::getIntIfConstant(mlir::Value value) { return {}; } +bool fir::isDummyArgument(mlir::Value v) { + auto blockArg{mlir::dyn_cast(v)}; + if (!blockArg) + return false; + + auto *owner{blockArg.getOwner()}; + return owner->isEntryBlock() && + mlir::isa(owner->getParentOp()); +} + mlir::Type fir::applyPathToType(mlir::Type eleTy, mlir::ValueRange path) { for (auto i = path.begin(), end = path.end(); eleTy && i < end;) { eleTy = llvm::TypeSwitch(eleTy) diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp index fb7c0bf0d1f9..810ebbd3da3e 100644 --- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp +++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp @@ -94,10 +94,11 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp, // DeclareOp is generated. In that case, DeclareOp may point to an // intermediate op and not to BlockArgument. We need to find those cases and // walk the chain to get to the actual argument. - unsigned argNo = 0; - if (auto Arg = llvm::dyn_cast(declOp.getMemref())) - argNo = Arg.getArgNumber() + 1; + if (fir::isDummyArgument(declOp.getMemref())) { + auto arg = llvm::cast(declOp.getMemref()); + argNo = arg.getArgNumber() + 1; + } auto tyAttr = typeGen.convertType(fir::unwrapRefType(declOp.getType()), fileAttr, scopeAttr, declOp.getLoc()); diff --git a/flang/test/Lower/OpenMP/debug_info_conflict.f90 b/flang/test/Lower/OpenMP/debug_info_conflict.f90 new file mode 100644 index 000000000000..5e52db281da2 --- /dev/null +++ b/flang/test/Lower/OpenMP/debug_info_conflict.f90 @@ -0,0 +1,16 @@ +! Tests that there no debug-info conflicts arise because of DI attached to nested +! OMP regions arguments. + +! RUN: %flang -c -fopenmp -g -mmlir --openmp-enable-delayed-privatization=true \ +! RUN: %s -o - 2>&1 | FileCheck %s + +subroutine bar (b) + integer :: a, b +!$omp parallel + do a = 1, 10 + b = a + end do +!$omp end parallel +end subroutine bar + +! CHECK-NOT: conflicting debug info for argument -- GitLab From a5641f106affc3afb899eee42eb40c2ded81f411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Mon, 3 Jun 2024 11:35:55 +0200 Subject: [PATCH 071/678] [SPIR-V] Add pass to merge convergence region exit targets (#92531) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The structurizer required regions to be SESE: single entry, single exit. This new pass transforms multiple-exit regions into single-exit regions. ``` +---+ | A | +---+ / \ +---+ +---+ | B | | C | A, B & C belongs to the same convergence region. +---+ +---+ | | +---+ +---+ | D | | E | C & D belongs to the parent convergence region. +---+ +---+ This means B & C are the exit blocks of the region. \ / And D & E the targets of those exits. \ / | +---+ | F | +---+ ``` This pass would assign one value per exit target: B = 0 C = 1 Then, create one variable per exit block (B, C), and assign it to the correct value: in B, the variable will have the value 0, and in C, the value 1. Then, we'd create a new block H, with a PHI node to gather those 2 variables, and a switch, to route to the correct target. Finally, the branches in B and C are updated to exit to this new block. ``` +---+ | A | +---+ / \ +---+ +---+ | B | | C | +---+ +---+ \ / +---+ | H | +---+ / \ +---+ +---+ | D | | E | +---+ +---+ \ / \ / | +---+ | F | +---+ ``` Note: the variable is set depending on the condition used to branch. If B's terminator was conditional, the variable would be set using a SELECT. All internal edges of a region are left intact, only exiting edges are updated. --------- Signed-off-by: Nathan Gauër --- llvm/lib/Target/SPIRV/CMakeLists.txt | 1 + llvm/lib/Target/SPIRV/SPIRV.h | 1 + llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 19 ++ llvm/lib/Target/SPIRV/SPIRVInstrInfo.td | 2 +- .../SPIRV/SPIRVMergeRegionExitTargets.cpp | 284 ++++++++++++++++++ llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp | 5 + .../SPIRV/structurizer/merge-exit-break.ll | 84 ++++++ .../merge-exit-convergence-in-break.ll | 94 ++++++ .../structurizer/merge-exit-multiple-break.ll | 103 +++++++ .../merge-exit-simple-white-identity.ll | 49 +++ 10 files changed, 641 insertions(+), 1 deletion(-) create mode 100644 llvm/lib/Target/SPIRV/SPIRVMergeRegionExitTargets.cpp create mode 100644 llvm/test/CodeGen/SPIRV/structurizer/merge-exit-break.ll create mode 100644 llvm/test/CodeGen/SPIRV/structurizer/merge-exit-convergence-in-break.ll create mode 100644 llvm/test/CodeGen/SPIRV/structurizer/merge-exit-multiple-break.ll create mode 100644 llvm/test/CodeGen/SPIRV/structurizer/merge-exit-simple-white-identity.ll diff --git a/llvm/lib/Target/SPIRV/CMakeLists.txt b/llvm/lib/Target/SPIRV/CMakeLists.txt index fe09d5903045..14647e92f5d0 100644 --- a/llvm/lib/Target/SPIRV/CMakeLists.txt +++ b/llvm/lib/Target/SPIRV/CMakeLists.txt @@ -25,6 +25,7 @@ add_llvm_target(SPIRVCodeGen SPIRVInstrInfo.cpp SPIRVInstructionSelector.cpp SPIRVStripConvergentIntrinsics.cpp + SPIRVMergeRegionExitTargets.cpp SPIRVISelLowering.cpp SPIRVLegalizerInfo.cpp SPIRVMCInstLower.cpp diff --git a/llvm/lib/Target/SPIRV/SPIRV.h b/llvm/lib/Target/SPIRV/SPIRV.h index fb8580cd47c0..e597a1dc8dc0 100644 --- a/llvm/lib/Target/SPIRV/SPIRV.h +++ b/llvm/lib/Target/SPIRV/SPIRV.h @@ -20,6 +20,7 @@ class InstructionSelector; class RegisterBankInfo; ModulePass *createSPIRVPrepareFunctionsPass(const SPIRVTargetMachine &TM); +FunctionPass *createSPIRVMergeRegionExitTargetsPass(); FunctionPass *createSPIRVStripConvergenceIntrinsicsPass(); FunctionPass *createSPIRVRegularizerPass(); FunctionPass *createSPIRVPreLegalizerPass(); diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp index ffbd1e17bad5..5ef0be1cab72 100644 --- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp @@ -151,6 +151,16 @@ public: ModulePass::getAnalysisUsage(AU); } }; + +bool isConvergenceIntrinsic(const Instruction *I) { + const auto *II = dyn_cast(I); + if (!II) + return false; + + return II->getIntrinsicID() == Intrinsic::experimental_convergence_entry || + II->getIntrinsicID() == Intrinsic::experimental_convergence_loop || + II->getIntrinsicID() == Intrinsic::experimental_convergence_anchor; +} } // namespace char SPIRVEmitIntrinsics::ID = 0; @@ -1353,6 +1363,10 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) { Worklist.push_back(&I); for (auto &I : Worklist) { + // Don't emit intrinsincs for convergence intrinsics. + if (isConvergenceIntrinsic(I)) + continue; + insertAssignPtrTypeIntrs(I, B); insertAssignTypeIntrs(I, B); insertPtrCastOrAssignTypeInstr(I, B); @@ -1371,6 +1385,11 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) { I = visit(*I); if (!I) continue; + + // Don't emit intrinsics for convergence operations. + if (isConvergenceIntrinsic(I)) + continue; + processInstrAfterVisit(I, B); } diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td index 7c9b84a48a2a..dedfd5e6e32d 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td +++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td @@ -617,7 +617,7 @@ def OpFwidthCoarse: UnOp<"OpFwidthCoarse", 215>; def OpPhi: Op<245, (outs ID:$res), (ins TYPE:$type, ID:$var0, ID:$block0, variable_ops), "$res = OpPhi $type $var0 $block0">; def OpLoopMerge: Op<246, (outs), (ins ID:$merge, ID:$continue, LoopControl:$lc, variable_ops), - "OpLoopMerge $merge $merge $continue $lc">; + "OpLoopMerge $merge $continue $lc">; def OpSelectionMerge: Op<247, (outs), (ins ID:$merge, SelectionControl:$sc), "OpSelectionMerge $merge $sc">; def OpLabel: Op<248, (outs ID:$label), (ins), "$label = OpLabel">; diff --git a/llvm/lib/Target/SPIRV/SPIRVMergeRegionExitTargets.cpp b/llvm/lib/Target/SPIRV/SPIRVMergeRegionExitTargets.cpp new file mode 100644 index 000000000000..2cdeb3257903 --- /dev/null +++ b/llvm/lib/Target/SPIRV/SPIRVMergeRegionExitTargets.cpp @@ -0,0 +1,284 @@ +//===-- SPIRVMergeRegionExitTargets.cpp ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Merge the multiple exit targets of a convergence region into a single block. +// Each exit target will be assigned a constant value, and a phi node + switch +// will allow the new exit target to re-route to the correct basic block. +// +//===----------------------------------------------------------------------===// + +#include "Analysis/SPIRVConvergenceRegionAnalysis.h" +#include "SPIRV.h" +#include "SPIRVSubtarget.h" +#include "SPIRVTargetMachine.h" +#include "SPIRVUtils.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/CodeGen/IntrinsicLowering.h" +#include "llvm/IR/CFG.h" +#include "llvm/IR/Dominators.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsSPIRV.h" +#include "llvm/InitializePasses.h" +#include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Transforms/Utils/LoopSimplify.h" +#include "llvm/Transforms/Utils/LowerMemIntrinsics.h" + +using namespace llvm; + +namespace llvm { +void initializeSPIRVMergeRegionExitTargetsPass(PassRegistry &); + +class SPIRVMergeRegionExitTargets : public FunctionPass { +public: + static char ID; + + SPIRVMergeRegionExitTargets() : FunctionPass(ID) { + initializeSPIRVMergeRegionExitTargetsPass(*PassRegistry::getPassRegistry()); + }; + + // Gather all the successors of |BB|. + // This function asserts if the terminator neither a branch, switch or return. + std::unordered_set gatherSuccessors(BasicBlock *BB) { + std::unordered_set output; + auto *T = BB->getTerminator(); + + if (auto *BI = dyn_cast(T)) { + output.insert(BI->getSuccessor(0)); + if (BI->isConditional()) + output.insert(BI->getSuccessor(1)); + return output; + } + + if (auto *SI = dyn_cast(T)) { + output.insert(SI->getDefaultDest()); + for (auto &Case : SI->cases()) + output.insert(Case.getCaseSuccessor()); + return output; + } + + if (auto *RI = dyn_cast(T)) + return output; + + assert(false && "Unhandled terminator type."); + return output; + } + + /// Create a value in BB set to the value associated with the branch the block + /// terminator will take. + llvm::Value *createExitVariable( + BasicBlock *BB, + const std::unordered_map &TargetToValue) { + auto *T = BB->getTerminator(); + if (auto *RI = dyn_cast(T)) + return nullptr; + + IRBuilder<> Builder(BB); + Builder.SetInsertPoint(T); + + if (auto *BI = dyn_cast(T)) { + + BasicBlock *LHSTarget = BI->getSuccessor(0); + BasicBlock *RHSTarget = + BI->isConditional() ? BI->getSuccessor(1) : nullptr; + + Value *LHS = TargetToValue.count(LHSTarget) != 0 + ? TargetToValue.at(LHSTarget) + : nullptr; + Value *RHS = TargetToValue.count(RHSTarget) != 0 + ? TargetToValue.at(RHSTarget) + : nullptr; + + if (LHS == nullptr || RHS == nullptr) + return LHS == nullptr ? RHS : LHS; + return Builder.CreateSelect(BI->getCondition(), LHS, RHS); + } + + // TODO: add support for switch cases. + assert(false && "Unhandled terminator type."); + } + + /// Replaces |BB|'s branch targets present in |ToReplace| with |NewTarget|. + void replaceBranchTargets(BasicBlock *BB, + const std::unordered_set ToReplace, + BasicBlock *NewTarget) { + auto *T = BB->getTerminator(); + if (auto *RI = dyn_cast(T)) + return; + + if (auto *BI = dyn_cast(T)) { + for (size_t i = 0; i < BI->getNumSuccessors(); i++) { + if (ToReplace.count(BI->getSuccessor(i)) != 0) + BI->setSuccessor(i, NewTarget); + } + return; + } + + if (auto *SI = dyn_cast(T)) { + for (size_t i = 0; i < SI->getNumSuccessors(); i++) { + if (ToReplace.count(SI->getSuccessor(i)) != 0) + SI->setSuccessor(i, NewTarget); + } + return; + } + + assert(false && "Unhandled terminator type."); + } + + // Run the pass on the given convergence region, ignoring the sub-regions. + // Returns true if the CFG changed, false otherwise. + bool runOnConvergenceRegionNoRecurse(LoopInfo &LI, + const SPIRV::ConvergenceRegion *CR) { + // Gather all the exit targets for this region. + std::unordered_set ExitTargets; + for (BasicBlock *Exit : CR->Exits) { + for (BasicBlock *Target : gatherSuccessors(Exit)) { + if (CR->Blocks.count(Target) == 0) + ExitTargets.insert(Target); + } + } + + // If we have zero or one exit target, nothing do to. + if (ExitTargets.size() <= 1) + return false; + + // Create the new single exit target. + auto F = CR->Entry->getParent(); + auto NewExitTarget = BasicBlock::Create(F->getContext(), "new.exit", F); + IRBuilder<> Builder(NewExitTarget); + + // CodeGen output needs to be stable. Using the set as-is would order + // the targets differently depending on the allocation pattern. + // Sorting per basic-block ordering in the function. + std::vector SortedExitTargets; + std::vector SortedExits; + for (BasicBlock &BB : *F) { + if (ExitTargets.count(&BB) != 0) + SortedExitTargets.push_back(&BB); + if (CR->Exits.count(&BB) != 0) + SortedExits.push_back(&BB); + } + + // Creating one constant per distinct exit target. This will be route to the + // correct target. + std::unordered_map TargetToValue; + for (BasicBlock *Target : SortedExitTargets) + TargetToValue.emplace(Target, Builder.getInt32(TargetToValue.size())); + + // Creating one variable per exit node, set to the constant matching the + // targeted external block. + std::vector> ExitToVariable; + for (auto Exit : SortedExits) { + llvm::Value *Value = createExitVariable(Exit, TargetToValue); + ExitToVariable.emplace_back(std::make_pair(Exit, Value)); + } + + // Gather the correct value depending on the exit we came from. + llvm::PHINode *node = + Builder.CreatePHI(Builder.getInt32Ty(), ExitToVariable.size()); + for (auto [BB, Value] : ExitToVariable) { + node->addIncoming(Value, BB); + } + + // Creating the switch to jump to the correct exit target. + std::vector> CasesList( + TargetToValue.begin(), TargetToValue.end()); + llvm::SwitchInst *Sw = + Builder.CreateSwitch(node, CasesList[0].first, CasesList.size() - 1); + for (size_t i = 1; i < CasesList.size(); i++) + Sw->addCase(CasesList[i].second, CasesList[i].first); + + // Fix exit branches to redirect to the new exit. + for (auto Exit : CR->Exits) + replaceBranchTargets(Exit, ExitTargets, NewExitTarget); + + return true; + } + + /// Run the pass on the given convergence region and sub-regions (DFS). + /// Returns true if a region/sub-region was modified, false otherwise. + /// This returns as soon as one region/sub-region has been modified. + bool runOnConvergenceRegion(LoopInfo &LI, + const SPIRV::ConvergenceRegion *CR) { + for (auto *Child : CR->Children) + if (runOnConvergenceRegion(LI, Child)) + return true; + + return runOnConvergenceRegionNoRecurse(LI, CR); + } + +#if !NDEBUG + /// Validates each edge exiting the region has the same destination basic + /// block. + void validateRegionExits(const SPIRV::ConvergenceRegion *CR) { + for (auto *Child : CR->Children) + validateRegionExits(Child); + + std::unordered_set ExitTargets; + for (auto *Exit : CR->Exits) { + auto Set = gatherSuccessors(Exit); + for (auto *BB : Set) { + if (CR->Blocks.count(BB) == 0) + ExitTargets.insert(BB); + } + } + + assert(ExitTargets.size() <= 1); + } +#endif + + virtual bool runOnFunction(Function &F) override { + LoopInfo &LI = getAnalysis().getLoopInfo(); + const auto *TopLevelRegion = + getAnalysis() + .getRegionInfo() + .getTopLevelRegion(); + + // FIXME: very inefficient method: each time a region is modified, we bubble + // back up, and recompute the whole convergence region tree. Once the + // algorithm is completed and test coverage good enough, rewrite this pass + // to be efficient instead of simple. + bool modified = false; + while (runOnConvergenceRegion(LI, TopLevelRegion)) { + TopLevelRegion = getAnalysis() + .getRegionInfo() + .getTopLevelRegion(); + modified = true; + } + +#if !defined(NDEBUG) || defined(EXPENSIVE_CHECKS) + validateRegionExits(TopLevelRegion); +#endif + return modified; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + FunctionPass::getAnalysisUsage(AU); + } +}; +} // namespace llvm + +char SPIRVMergeRegionExitTargets::ID = 0; + +INITIALIZE_PASS_BEGIN(SPIRVMergeRegionExitTargets, "split-region-exit-blocks", + "SPIRV split region exit blocks", false, false) +INITIALIZE_PASS_DEPENDENCY(LoopSimplify) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(SPIRVConvergenceRegionAnalysisWrapperPass) + +INITIALIZE_PASS_END(SPIRVMergeRegionExitTargets, "split-region-exit-blocks", + "SPIRV split region exit blocks", false, false) + +FunctionPass *llvm::createSPIRVMergeRegionExitTargetsPass() { + return new SPIRVMergeRegionExitTargets(); +} diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp index ae8baa3f1191..a6823a8ba323 100644 --- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp @@ -164,6 +164,11 @@ void SPIRVPassConfig::addIRPasses() { // - all loop exits are dominated by the loop pre-header. // - loops have a single back-edge. addPass(createLoopSimplifyPass()); + + // 2. Merge the convergence region exit nodes into one. After this step, + // regions are single-entry, single-exit. This will help determine the + // correct merge block. + addPass(createSPIRVMergeRegionExitTargetsPass()); } TargetPassConfig::addIRPasses(); diff --git a/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-break.ll b/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-break.ll new file mode 100644 index 000000000000..b3fcdc978625 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-break.ll @@ -0,0 +1,84 @@ +; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | FileCheck %s --match-full-lines + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1" +target triple = "spirv-unknown-vulkan-compute" + +define internal spir_func void @main() #0 { + +; CHECK: OpDecorate %[[#builtin:]] BuiltIn SubgroupLocalInvocationId +; CHECK-DAG: %[[#int_ty:]] = OpTypeInt 32 0 +; CHECK-DAG: %[[#pint_ty:]] = OpTypePointer Function %[[#int_ty]] +; CHECK-DAG: %[[#bool_ty:]] = OpTypeBool +; CHECK-DAG: %[[#int_0:]] = OpConstant %[[#int_ty]] 0 +; CHECK-DAG: %[[#int_1:]] = OpConstant %[[#int_ty]] 1 +; CHECK-DAG: %[[#int_10:]] = OpConstant %[[#int_ty]] 10 + +; CHECK: %[[#entry:]] = OpLabel +; CHECK: %[[#idx:]] = OpVariable %[[#pint_ty]] Function +; CHECK: OpStore %[[#idx]] %[[#int_0]] Aligned 4 +; CHECK: OpBranch %[[#while_cond:]] +entry: + %0 = call token @llvm.experimental.convergence.entry() + %idx = alloca i32, align 4 + store i32 0, ptr %idx, align 4 + br label %while.cond + +; CHECK: %[[#while_cond]] = OpLabel +; CHECK: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#idx]] Aligned 4 +; CHECK: %[[#cmp:]] = OpINotEqual %[[#bool_ty]] %[[#tmp]] %[[#int_10]] +; CHECK: OpBranchConditional %[[#cmp]] %[[#while_body:]] %[[#new_end:]] +while.cond: + %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] + %2 = load i32, ptr %idx, align 4 + %cmp = icmp ne i32 %2, 10 + br i1 %cmp, label %while.body, label %while.end + +; CHECK: %[[#while_body]] = OpLabel +; CHECK-NEXT: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#builtin]] Aligned 1 +; CHECK-NEXT: OpStore %[[#idx]] %[[#tmp]] Aligned 4 +; CHECK-NEXT: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#idx]] Aligned 4 +; CHECK-NEXT: %[[#cmp1:]] = OpIEqual %[[#bool_ty]] %[[#tmp]] %[[#int_0]] +; CHECK: OpBranchConditional %[[#cmp1]] %[[#new_end]] %[[#if_end:]] +while.body: + %3 = call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %1) ] + store i32 %3, ptr %idx, align 4 + %4 = load i32, ptr %idx, align 4 + %cmp1 = icmp eq i32 %4, 0 + br i1 %cmp1, label %if.then, label %if.end + +; CHECK: %[[#if_then:]] = OpLabel +; CHECK: OpBranch %[[#while_end:]] +if.then: + br label %while.end + +; CHECK: %[[#if_end]] = OpLabel +; CHECK: OpBranch %[[#while_cond]] +if.end: + br label %while.cond + +; CHECK: %[[#while_end_loopexit:]] = OpLabel +; CHECK: OpBranch %[[#while_end]] + +; CHECK: %[[#while_end]] = OpLabel +; CHECK: OpReturn +while.end: + ret void + +; CHECK: %[[#new_end]] = OpLabel +; CHECK: %[[#route:]] = OpPhi %[[#int_ty]] %[[#int_1]] %[[#while_cond]] %[[#int_0]] %[[#while_body]] +; CHECK: OpSwitch %[[#route]] %[[#while_end_loopexit]] 0 %[[#if_then]] +} + +declare token @llvm.experimental.convergence.entry() #2 +declare token @llvm.experimental.convergence.loop() #2 +declare i32 @__hlsl_wave_get_lane_index() #3 + +attributes #0 = { convergent noinline norecurse nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { convergent norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #2 = { convergent nocallback nofree nosync nounwind willreturn memory(none) } +attributes #3 = { convergent } + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 4, !"dx.disable_optimizations", i32 1} diff --git a/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-convergence-in-break.ll b/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-convergence-in-break.ll new file mode 100644 index 000000000000..a67c58fdd574 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-convergence-in-break.ll @@ -0,0 +1,94 @@ +; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | FileCheck %s --match-full-lines + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1" +target triple = "spirv-unknown-vulkan-compute" + +define internal spir_func void @main() #0 { + +; CHECK: OpDecorate %[[#builtin:]] BuiltIn SubgroupLocalInvocationId +; CHECK-DAG: %[[#int_ty:]] = OpTypeInt 32 0 +; CHECK-DAG: %[[#pint_ty:]] = OpTypePointer Function %[[#int_ty]] +; CHECK-DAG: %[[#bool_ty:]] = OpTypeBool +; CHECK-DAG: %[[#int_0:]] = OpConstant %[[#int_ty]] 0 +; CHECK-DAG: %[[#int_1:]] = OpConstant %[[#int_ty]] 1 +; CHECK-DAG: %[[#int_10:]] = OpConstant %[[#int_ty]] 10 + +; CHECK: %[[#entry:]] = OpLabel +; CHECK: %[[#idx:]] = OpVariable %[[#pint_ty]] Function +; CHECK: OpStore %[[#idx]] %[[#int_0]] Aligned 4 +; CHECK: OpBranch %[[#while_cond:]] +entry: + %0 = call token @llvm.experimental.convergence.entry() + %idx = alloca i32, align 4 + store i32 0, ptr %idx, align 4 + br label %while.cond + +; CHECK: %[[#while_cond]] = OpLabel +; CHECK: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#idx]] Aligned 4 +; CHECK: %[[#cmp:]] = OpINotEqual %[[#bool_ty]] %[[#tmp]] %[[#int_10]] +; CHECK: OpBranchConditional %[[#cmp]] %[[#while_body:]] %[[#new_end:]] +while.cond: + %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] + %2 = load i32, ptr %idx, align 4 + %cmp = icmp ne i32 %2, 10 + br i1 %cmp, label %while.body, label %while.end + +; CHECK: %[[#while_body]] = OpLabel +; CHECK-NEXT: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#builtin]] Aligned 1 +; CHECK-NEXT: OpStore %[[#idx]] %[[#tmp]] Aligned 4 +; CHECK-NEXT: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#idx]] Aligned 4 +; CHECK-NEXT: %[[#cmp1:]] = OpIEqual %[[#bool_ty]] %[[#tmp]] %[[#int_0]] +; CHECK: OpBranchConditional %[[#cmp1]] %[[#if_then:]] %[[#if_end:]] +while.body: + %3 = call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %1) ] + store i32 %3, ptr %idx, align 4 + %4 = load i32, ptr %idx, align 4 + %cmp1 = icmp eq i32 %4, 0 + br i1 %cmp1, label %if.then, label %if.end + +; CHECK: %[[#if_then:]] = OpLabel +; CHECK-NEXT: OpBranch %[[#tail:]] +if.then: + br label %tail + +; CHECK: %[[#tail:]] = OpLabel +; CHECK-NEXT: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#builtin]] Aligned 1 +; CHECK-NEXT: OpStore %[[#idx]] %[[#tmp]] Aligned 4 +; CHECK: OpBranch %[[#new_end:]] +tail: + %5 = call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %1) ] + store i32 %5, ptr %idx, align 4 + br label %while.end + +; CHECK: %[[#if_end]] = OpLabel +; CHECK: OpBranch %[[#while_cond]] +if.end: + br label %while.cond + +; CHECK: %[[#while_end_loopexit:]] = OpLabel +; CHECK: OpBranch %[[#while_end:]] + +; CHECK: %[[#while_end]] = OpLabel +; CHECK: OpReturn +while.end: + ret void + +; CHECK: %[[#new_end]] = OpLabel +; CHECK: %[[#route:]] = OpPhi %[[#int_ty]] %[[#int_0]] %[[#while_cond]] %[[#int_1]] %[[#tail]] +; CHECK: OpSwitch %[[#route]] %[[#while_end]] 0 %[[#while_end_loopexit]] +} + +declare token @llvm.experimental.convergence.entry() #2 +declare token @llvm.experimental.convergence.loop() #2 +declare i32 @__hlsl_wave_get_lane_index() #3 + +attributes #0 = { convergent noinline norecurse nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { convergent norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #2 = { convergent nocallback nofree nosync nounwind willreturn memory(none) } +attributes #3 = { convergent } + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 4, !"dx.disable_optimizations", i32 1} + diff --git a/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-multiple-break.ll b/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-multiple-break.ll new file mode 100644 index 000000000000..32a97553df05 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-multiple-break.ll @@ -0,0 +1,103 @@ +; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | FileCheck %s --match-full-lines + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1" +target triple = "spirv-unknown-vulkan-compute" + +define internal spir_func void @main() #0 { + +; CHECK: OpDecorate %[[#builtin:]] BuiltIn SubgroupLocalInvocationId +; CHECK-DAG: %[[#int_ty:]] = OpTypeInt 32 0 +; CHECK-DAG: %[[#pint_ty:]] = OpTypePointer Function %[[#int_ty]] +; CHECK-DAG: %[[#bool_ty:]] = OpTypeBool +; CHECK-DAG: %[[#int_0:]] = OpConstant %[[#int_ty]] 0 +; CHECK-DAG: %[[#int_1:]] = OpConstant %[[#int_ty]] 1 +; CHECK-DAG: %[[#int_2:]] = OpConstant %[[#int_ty]] 2 +; CHECK-DAG: %[[#int_10:]] = OpConstant %[[#int_ty]] 10 + +; CHECK: %[[#entry:]] = OpLabel +; CHECK: %[[#idx:]] = OpVariable %[[#pint_ty]] Function +; CHECK: OpStore %[[#idx]] %[[#int_0]] Aligned 4 +; CHECK: OpBranch %[[#while_cond:]] +entry: + %0 = call token @llvm.experimental.convergence.entry() + %idx = alloca i32, align 4 + store i32 0, ptr %idx, align 4 + br label %while.cond + +; CHECK: %[[#while_cond]] = OpLabel +; CHECK: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#idx]] Aligned 4 +; CHECK: %[[#cmp:]] = OpINotEqual %[[#bool_ty]] %[[#tmp]] %[[#int_10]] +; CHECK: OpBranchConditional %[[#cmp]] %[[#while_body:]] %[[#new_end:]] +while.cond: + %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] + %2 = load i32, ptr %idx, align 4 + %cmp = icmp ne i32 %2, 10 + br i1 %cmp, label %while.body, label %while.end + +; CHECK: %[[#while_body]] = OpLabel +; CHECK-NEXT: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#builtin]] Aligned 1 +; CHECK-NEXT: OpStore %[[#idx]] %[[#tmp]] Aligned 4 +; CHECK-NEXT: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#idx]] Aligned 4 +; CHECK-NEXT: %[[#cmp1:]] = OpIEqual %[[#bool_ty]] %[[#tmp]] %[[#int_0]] +; CHECK: OpBranchConditional %[[#cmp1]] %[[#new_end]] %[[#if_end:]] +while.body: + %3 = call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %1) ] + store i32 %3, ptr %idx, align 4 + %4 = load i32, ptr %idx, align 4 + %cmp1 = icmp eq i32 %4, 0 + br i1 %cmp1, label %if.then, label %if.end + +; CHECK: %[[#if_then:]] = OpLabel +; CHECK: OpBranch %[[#while_end:]] +if.then: + br label %while.end + +; CHECK: %[[#if_end]] = OpLabel +; CHECK-NEXT: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#builtin]] Aligned 1 +; CHECK-NEXT: OpStore %[[#idx]] %[[#tmp]] Aligned 4 +; CHECK-NEXT: %[[#tmp:]] = OpLoad %[[#int_ty]] %[[#idx]] Aligned 4 +; CHECK-NEXT: %[[#cmp2:]] = OpIEqual %[[#bool_ty]] %[[#tmp]] %[[#int_0]] +; CHECK: OpBranchConditional %[[#cmp2]] %[[#new_end]] %[[#if_end2:]] +if.end: + %5 = call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %1) ] + store i32 %5, ptr %idx, align 4 + %6 = load i32, ptr %idx, align 4 + %cmp2 = icmp eq i32 %6, 0 + br i1 %cmp2, label %if.then2, label %if.end2 + +; CHECK: %[[#if_then2:]] = OpLabel +; CHECK: OpBranch %[[#while_end:]] +if.then2: + br label %while.end + +; CHECK: %[[#if_end2]] = OpLabel +; CHECK: OpBranch %[[#while_cond:]] +if.end2: + br label %while.cond + +; CHECK: %[[#while_end_loopexit:]] = OpLabel +; CHECK: OpBranch %[[#while_end]] + +; CHECK: %[[#while_end]] = OpLabel +; CHECK: OpReturn +while.end: + ret void + +; CHECK: %[[#new_end]] = OpLabel +; CHECK: %[[#route:]] = OpPhi %[[#int_ty]] %[[#int_2]] %[[#while_cond]] %[[#int_0]] %[[#while_body]] %[[#int_1]] %[[#if_end]] +; CHECK: OpSwitch %[[#route]] %[[#while_end_loopexit]] 1 %[[#if_then2]] 0 %[[#if_then]] +} + +declare token @llvm.experimental.convergence.entry() #2 +declare token @llvm.experimental.convergence.loop() #2 +declare i32 @__hlsl_wave_get_lane_index() #3 + +attributes #0 = { convergent noinline norecurse nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { convergent norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #2 = { convergent nocallback nofree nosync nounwind willreturn memory(none) } +attributes #3 = { convergent } + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 4, !"dx.disable_optimizations", i32 1} diff --git a/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-simple-white-identity.ll b/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-simple-white-identity.ll new file mode 100644 index 000000000000..a8bf4fb0db98 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/structurizer/merge-exit-simple-white-identity.ll @@ -0,0 +1,49 @@ +; RUN: llc -mtriple=spirv-unknown-vulkan-compute -O0 %s -o - | FileCheck %s + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1" +target triple = "spirv-unknown-vulkan-compute" + +define internal spir_func void @main() #0 { + +; CHECK: %[[#entry:]] = OpLabel +; CHECK: OpBranch %[[#while_cond:]] +entry: + %0 = call token @llvm.experimental.convergence.entry() + %idx = alloca i32, align 4 + store i32 -1, ptr %idx, align 4 + br label %while.cond + +; CHECK: %[[#while_cond]] = OpLabel +; CHECK: OpBranchConditional %[[#cond:]] %[[#while_body:]] %[[#while_end:]] +while.cond: + %1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %0) ] + %2 = load i32, ptr %idx, align 4 + %cmp = icmp ne i32 %2, 0 + br i1 %cmp, label %while.body, label %while.end + +; CHECK: %[[#while_body]] = OpLabel +; CHECK: OpBranch %[[#while_cond]] +while.body: + %3 = call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %1) ] + store i32 %3, ptr %idx, align 4 + br label %while.cond + + ; CHECK: %[[#while_end]] = OpLabel +; CHECK-NEXT: OpReturn +while.end: + ret void +} + +declare token @llvm.experimental.convergence.entry() #2 +declare token @llvm.experimental.convergence.loop() #2 +declare i32 @__hlsl_wave_get_lane_index() #3 + +attributes #0 = { convergent noinline norecurse nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { convergent norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #2 = { convergent nocallback nofree nosync nounwind willreturn memory(none) } +attributes #3 = { convergent } + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 4, !"dx.disable_optimizations", i32 1} -- GitLab From e28b07019b47d3ca820ee9305b4b673f61febfec Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot Date: Mon, 3 Jun 2024 09:37:42 +0000 Subject: [PATCH 072/678] [gn build] Port 8918d35dbde1 --- llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn index 05504ddb79f8..576ab1db5498 100644 --- a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn @@ -61,6 +61,7 @@ static_library("Basic") { ] include_dirs = [ "." ] sources = [ + "ASTSourceDescriptor.cpp", "Attributes.cpp", "Builtins.cpp", "CLWarnings.cpp", -- GitLab From 4f2dba3c0b4e5f11b968a840b5f70070f5288cfe Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Mon, 3 Jun 2024 13:47:28 +0400 Subject: [PATCH 073/678] [clang] Add tests for some CWG issues from 2024-05-31 telecon (#94167) This patch adds tests for some CWG issues that were discussed at 2024-05-31 telecon. While all of them are tentatively ready at the moment, I'm expecting them to be moved to DRs without changes. CWG issues that are expected to have follow-ups are not included in this PR. I also realized that `cwg28xx.cpp` has been testing without `-pedantic-errors`. I fixed that. Fortunately, no existing tests had anything hidden by the lack of this flag. The following CWG issues are covered: [CWG2877](https://cplusplus.github.io/CWG/issues/2877.html) "Type-only lookup for _using-enum-declarator_" [CWG2882](https://cplusplus.github.io/CWG/issues/2882.html) "Unclear treatment of conversion to `void`" [CWG2883](https://cplusplus.github.io/CWG/issues/2883.html) "Definition of "odr-usable" ignores lambda scopes" [CWG2885](https://cplusplus.github.io/CWG/issues/2885.html) "Non-eligible trivial default constructors" [CWG2886](https://cplusplus.github.io/CWG/issues/2886.html) "Temporaries and trivial potentially-throwing special member functions" --- clang/test/CXX/drs/cwg28xx.cpp | 95 +++++++++++++++++++++++++++++++--- clang/www/cxx_dr_status.html | 10 ++-- 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp index 8469a065ccaa..da81eccc8dc2 100644 --- a/clang/test/CXX/drs/cwg28xx.cpp +++ b/clang/test/CXX/drs/cwg28xx.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -std=c++98 -verify=expected %s -// RUN: %clang_cc1 -std=c++11 -verify=expected %s -// RUN: %clang_cc1 -std=c++14 -verify=expected %s -// RUN: %clang_cc1 -std=c++17 -verify=expected %s -// RUN: %clang_cc1 -std=c++20 -verify=expected,since-cxx20 %s -// RUN: %clang_cc1 -std=c++23 -verify=expected,since-cxx20,since-cxx23 %s -// RUN: %clang_cc1 -std=c++2c -verify=expected,since-cxx20,since-cxx23,since-cxx26 %s +// RUN: %clang_cc1 -std=c++98 -pedantic-errors -verify=expected,cxx98 %s +// RUN: %clang_cc1 -std=c++11 -pedantic-errors -verify=expected %s +// RUN: %clang_cc1 -std=c++14 -pedantic-errors -verify=expected %s +// RUN: %clang_cc1 -std=c++17 -pedantic-errors -verify=expected %s +// RUN: %clang_cc1 -std=c++20 -pedantic-errors -verify=expected,since-cxx20 %s +// RUN: %clang_cc1 -std=c++23 -pedantic-errors -verify=expected,since-cxx20,since-cxx23 %s +// RUN: %clang_cc1 -std=c++2c -pedantic-errors -verify=expected,since-cxx20,since-cxx23,since-cxx26 %s namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01 #if __cpp_constexpr >= 202306L @@ -110,6 +110,26 @@ struct A { } // namespace cwg2858 +namespace cwg2877 { // cwg2877: no tentatively ready 2024-05-31 +#if __cplusplus >= 202002L +enum E { x }; +void f() { + int E; + // FIXME: OK, names ::E + using enum E; + // since-cxx20-error@-1 {{unknown type name E}} +} +using F = E; +using enum F; // OK, designates ::E +template using EE = T; +void g() { + // FIXME: OK, designates ::E + using enum EE; + // since-cxx20-error@-1 {{using enum requires an enum or typedef name}} +} +#endif +} // namespace cwg2877 + namespace cwg2881 { // cwg2881: 19 tentatively ready 2024-04-19 #if __cplusplus >= 202302L @@ -180,3 +200,64 @@ void f() { } // namespace cwg2881 +namespace cwg2882 { // cwg2882: 2.7 tentatively ready 2024-05-31 +struct C { + operator void() = delete; + // expected-warning@-1 {{conversion function converting 'cwg2882::C' to 'void' will never be used}} + // cxx98-error@-2 {{deleted function definitions are a C++11 extension}} +}; + +void f(C c) { + (void)c; +} +} // namespace cwg2882 + +namespace cwg2883 { // cwg2883: no tentatively ready 2024-05-31 +#if __cplusplus >= 201103L +void f() { + int x; + (void)[&] { + return x; + }; +} +#endif +#if __cplusplus >= 202002L +struct A { + A() = default; + A(const A &) = delete; // #cwg2883-A-copy-ctor + constexpr operator int() { return 42; } +}; +void g() { + constexpr A a; + // FIXME: OK, not odr-usable from a default template argument, and not odr-used + (void)[=] {}; + // since-cxx20-error@-1 {{call to deleted constructor of 'const A'}} + // since-cxx20-note@#cwg2883-A-copy-ctor {{'A' has been explicitly marked deleted here}} +} +#endif +} // namespace cwg2883 + +namespace cwg2885 { // cwg2885: 16 tentatively ready 2024-05-31 +#if __cplusplus >= 202002L +template +struct A { + A() requires (false) = default; + A() : t(42) {} + T t; +}; + +struct B : A {}; +static_assert(!__is_trivially_constructible(B)); +#endif +} // namespace cwg2885 + +namespace cwg2886 { // cwg2886: 9 tentatively ready 2024-05-31 +#if __cplusplus >= 201103L +struct C { + C() = default; + ~C() noexcept(false) = default; +}; + +static_assert(noexcept(C()), ""); +#endif +} // namespace cwg2886 diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 744d22959db4..4d94ac5a1ac1 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -17071,7 +17071,7 @@ objects 2877 tentatively ready Type-only lookup for using-enum-declarator - Not resolved + Not Resolved* 2878 @@ -17101,13 +17101,13 @@ objects 2882 tentatively ready Unclear treatment of conversion to void - Not resolved + Not Resolved* 2883 tentatively ready Definition of "odr-usable" ignores lambda scopes - Not resolved + Not Resolved* 2884 @@ -17119,13 +17119,13 @@ objects 2885 tentatively ready Non-eligible trivial default constructors - Not resolved + Not Resolved* 2886 tentatively ready Temporaries and trivial potentially-throwing special member functions - Not resolved + Not Resolved* 2887 -- GitLab From bf4eaec44054fa3908d50898f572e15d89119c67 Mon Sep 17 00:00:00 2001 From: Marc Auberer Date: Mon, 3 Jun 2024 11:55:37 +0200 Subject: [PATCH 074/678] [llvm] Replace deprecated aligned_storage with aligned byte array (#94169) `std::aligned_storage` is deprecated with C++23, see [here](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1413r3.pdf). This replaces the usages of `std::aligned_storage` within llvm (only one in ADT and one in Support) with an aligned `std::byte` array. I will provide patches for other subcomponents as well. --- llvm/include/llvm/ADT/FunctionExtras.h | 3 +-- llvm/lib/Support/PrettyStackTrace.cpp | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h index c0bc30c7450f..49e0e8ab0db4 100644 --- a/llvm/include/llvm/ADT/FunctionExtras.h +++ b/llvm/include/llvm/ADT/FunctionExtras.h @@ -161,8 +161,7 @@ protected: // provide three pointers worth of storage here. // This is mutable as an inlined `const unique_function` may // still modify its own mutable members. - mutable std::aligned_storage_t - InlineStorage; + alignas(void *) mutable std::byte InlineStorage[InlineStorageSize]; } StorageUnion; // A compressed pointer to either our dispatching callback or our table of diff --git a/llvm/lib/Support/PrettyStackTrace.cpp b/llvm/lib/Support/PrettyStackTrace.cpp index f9f1b8a419b8..9b09384e95bf 100644 --- a/llvm/lib/Support/PrettyStackTrace.cpp +++ b/llvm/lib/Support/PrettyStackTrace.cpp @@ -143,10 +143,9 @@ static void setCrashLogMessage(const char *msg) { #ifdef __APPLE__ using CrashHandlerString = SmallString<2048>; -using CrashHandlerStringStorage = - std::aligned_storage::type; -static CrashHandlerStringStorage crashHandlerStringStorage; +using CrashHandlerStringStorage = std::byte[sizeof(CrashHandlerString)]; +alignas(CrashHandlerString) static CrashHandlerStringStorage + crashHandlerStringStorage; #endif /// This callback is run if a fatal signal is delivered to the process, it -- GitLab From 910098e40572f9fe6bfde161eafd1b390a356043 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Mon, 3 Jun 2024 11:12:27 +0100 Subject: [PATCH 075/678] [RISCV] Match strided vector bases in RISCVGatherScatterLowering (#93972) Currently we only match GEPs with a scalar base pointer, but a common pattern that's emitted from the loop vectorizer is a strided vector base plus some sort of scalar offset: %base = getelementptr i64, ptr %p, %step %gep = getelementptr i64, %base, i64 %offset This is common for accesses into a struct e.g. f[i].b below: struct F { int a; char b; }; void foo(struct F *f) { for (int i = 0; i < 1024; i += 2) { f[i].a++; f[i].b++; } } This patch handles this case in RISCVGatherScatterLowering by recursing on the base pointer if it's a vector. With this we can convert roughly 80% of the indexed loads and stores emitted to strided loads and stores on SPEC CPU 2017, -O3 -march=rva22u64_v --- .../RISCV/RISCVGatherScatterLowering.cpp | 21 ++++++++++++++++++- .../CodeGen/RISCV/rvv/strided-load-store.ll | 12 ++++------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVGatherScatterLowering.cpp b/llvm/lib/Target/RISCV/RISCVGatherScatterLowering.cpp index f0bd25f167d8..cff46e15251b 100644 --- a/llvm/lib/Target/RISCV/RISCVGatherScatterLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVGatherScatterLowering.cpp @@ -349,8 +349,27 @@ RISCVGatherScatterLowering::determineBaseAndStride(Instruction *Ptr, SmallVector Ops(GEP->operands()); + // If the base pointer is a vector, check if it's strided. + Value *Base = GEP->getPointerOperand(); + if (auto *BaseInst = dyn_cast(Base); + BaseInst && BaseInst->getType()->isVectorTy()) { + // If GEP's offset is scalar then we can add it to the base pointer's base. + auto IsScalar = [](Value *Idx) { return !Idx->getType()->isVectorTy(); }; + if (all_of(GEP->indices(), IsScalar)) { + auto [BaseBase, Stride] = determineBaseAndStride(BaseInst, Builder); + if (BaseBase) { + Builder.SetInsertPoint(GEP); + SmallVector Indices(GEP->indices()); + Value *OffsetBase = + Builder.CreateGEP(GEP->getSourceElementType(), BaseBase, Indices, + GEP->getName() + "offset", GEP->isInBounds()); + return {OffsetBase, Stride}; + } + } + } + // Base pointer needs to be a scalar. - Value *ScalarBase = Ops[0]; + Value *ScalarBase = Base; if (ScalarBase->getType()->isVectorTy()) { ScalarBase = getSplatValue(ScalarBase); if (!ScalarBase) diff --git a/llvm/test/CodeGen/RISCV/rvv/strided-load-store.ll b/llvm/test/CodeGen/RISCV/rvv/strided-load-store.ll index 8733c5dc83d6..70412de1d0e9 100644 --- a/llvm/test/CodeGen/RISCV/rvv/strided-load-store.ll +++ b/llvm/test/CodeGen/RISCV/rvv/strided-load-store.ll @@ -301,10 +301,8 @@ define void @constant_stride( %x, ptr %p, i64 %stride) { define @vector_base_scalar_offset(ptr %p, i64 %offset) { ; CHECK-LABEL: @vector_base_scalar_offset( -; CHECK-NEXT: [[STEP:%.*]] = call @llvm.experimental.stepvector.nxv1i64() -; CHECK-NEXT: [[PTRS1:%.*]] = getelementptr i64, ptr [[P:%.*]], [[STEP]] -; CHECK-NEXT: [[PTRS2:%.*]] = getelementptr i64, [[PTRS1]], i64 [[OFFSET:%.*]] -; CHECK-NEXT: [[X:%.*]] = call @llvm.masked.gather.nxv1i64.nxv1p0( [[PTRS2]], i32 8, shufflevector ( insertelement ( poison, i1 true, i64 0), poison, zeroinitializer), poison) +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i64, ptr [[P:%.*]], i64 [[OFFSET:%.*]] +; CHECK-NEXT: [[X:%.*]] = call @llvm.riscv.masked.strided.load.nxv1i64.p0.i64( poison, ptr [[TMP1]], i64 8, shufflevector ( insertelement ( poison, i1 true, i64 0), poison, zeroinitializer)) ; CHECK-NEXT: ret [[X]] ; %step = call @llvm.experimental.stepvector.nxv1i64() @@ -321,10 +319,8 @@ define @vector_base_scalar_offset(ptr %p, i64 %offset) { define @splat_base_scalar_offset(ptr %p, i64 %offset) { ; CHECK-LABEL: @splat_base_scalar_offset( -; CHECK-NEXT: [[HEAD:%.*]] = insertelement poison, ptr [[P:%.*]], i32 0 -; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector [[HEAD]], poison, zeroinitializer -; CHECK-NEXT: [[PTRS:%.*]] = getelementptr i64, [[SPLAT]], i64 [[OFFSET:%.*]] -; CHECK-NEXT: [[X:%.*]] = call @llvm.masked.gather.nxv1i64.nxv1p0( [[PTRS]], i32 8, shufflevector ( insertelement ( poison, i1 true, i64 0), poison, zeroinitializer), poison) +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i64, ptr [[P:%.*]], i64 [[OFFSET:%.*]] +; CHECK-NEXT: [[X:%.*]] = call @llvm.riscv.masked.strided.load.nxv1i64.p0.i64( poison, ptr [[TMP1]], i64 0, shufflevector ( insertelement ( poison, i1 true, i64 0), poison, zeroinitializer)) ; CHECK-NEXT: ret [[X]] ; %head = insertelement poison, ptr %p, i32 0 -- GitLab From 6b30180b663e1fe4de32046398581a374c8a54f2 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Mon, 3 Jun 2024 18:39:19 +0800 Subject: [PATCH 076/678] Revert "[serialization] no transitive decl change (#92083)" This reverts commit ccb73e882b2d727877cfda42a14a6979cfd31f04. It looks like there are some bots complaining about the patch. See the post commit comment in https://github.com/llvm/llvm-project/pull/92083 to track it. --- clang/include/clang/AST/DeclBase.h | 17 +- clang/include/clang/AST/DeclID.h | 18 +- .../include/clang/Serialization/ASTBitCodes.h | 6 - clang/include/clang/Serialization/ASTReader.h | 36 ++-- .../include/clang/Serialization/ModuleFile.h | 18 +- .../clang/Serialization/ModuleManager.h | 2 +- clang/lib/AST/DeclBase.cpp | 40 +---- clang/lib/Serialization/ASTReader.cpp | 159 ++++++++---------- clang/lib/Serialization/ASTReaderDecl.cpp | 12 +- clang/lib/Serialization/ASTWriter.cpp | 7 +- clang/lib/Serialization/ModuleFile.cpp | 3 +- .../Modules/no-transitive-decls-change.cppm | 112 ------------ 12 files changed, 147 insertions(+), 283 deletions(-) delete mode 100644 clang/test/Modules/no-transitive-decls-change.cppm diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 4bdf27aa9940..e43e812cd945 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -701,7 +701,10 @@ public: /// Set the owning module ID. This may only be called for /// deserialized Decls. - void setOwningModuleID(unsigned ID); + void setOwningModuleID(unsigned ID) { + assert(isFromASTFile() && "Only works on a deserialized declaration"); + *((unsigned*)this - 2) = ID; + } public: /// Determine the availability of the given declaration. @@ -774,11 +777,19 @@ public: /// Retrieve the global declaration ID associated with this /// declaration, which specifies where this Decl was loaded from. - GlobalDeclID getGlobalID() const; + GlobalDeclID getGlobalID() const { + if (isFromASTFile()) + return (*((const GlobalDeclID *)this - 1)); + return GlobalDeclID(); + } /// Retrieve the global ID of the module that owns this particular /// declaration. - unsigned getOwningModuleID() const; + unsigned getOwningModuleID() const { + if (isFromASTFile()) + return *((const unsigned*)this - 2); + return 0; + } private: Module *getOwningModuleSlow() const; diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h index 32d2ed41a374..614ba06b6386 100644 --- a/clang/include/clang/AST/DeclID.h +++ b/clang/include/clang/AST/DeclID.h @@ -19,8 +19,6 @@ #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/iterator.h" -#include - namespace clang { /// Predefined declaration IDs. @@ -109,16 +107,12 @@ public: /// /// DeclID should only be used directly in serialization. All other users /// should use LocalDeclID or GlobalDeclID. - using DeclID = uint64_t; + using DeclID = uint32_t; protected: DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {} explicit DeclIDBase(DeclID ID) : ID(ID) {} - explicit DeclIDBase(unsigned LocalID, unsigned ModuleFileIndex) { - ID = (DeclID)LocalID | ((DeclID)ModuleFileIndex << 32); - } - public: DeclID get() const { return ID; } @@ -130,10 +124,6 @@ public: bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; } - unsigned getModuleFileIndex() const { return ID >> 32; } - - unsigned getLocalDeclIndex() const; - friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID == RHS.ID; } @@ -166,9 +156,6 @@ public: LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {} explicit LocalDeclID(DeclID ID) : Base(ID) {} - explicit LocalDeclID(unsigned LocalID, unsigned ModuleFileIndex) - : Base(LocalID, ModuleFileIndex) {} - LocalDeclID &operator++() { ++ID; return *this; @@ -188,9 +175,6 @@ public: GlobalDeclID() : Base() {} explicit GlobalDeclID(DeclID ID) : Base(ID) {} - explicit GlobalDeclID(unsigned LocalID, unsigned ModuleFileIndex) - : Base(LocalID, ModuleFileIndex) {} - // For DeclIDIterator to be able to convert a GlobalDeclID // to a LocalDeclID. explicit operator LocalDeclID() const { return LocalDeclID(this->ID); } diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 9e4b21baa7d2..fe1bd47348be 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -255,12 +255,6 @@ public: } }; -// The unaligned decl ID used in the Blobs of bistreams. -using unaligned_decl_id_t = - llvm::support::detail::packed_endian_specific_integral< - serialization::DeclID, llvm::endianness::native, - llvm::support::unaligned>; - /// The number of predefined preprocessed entity IDs. const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1; diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index a2e094354d96..4ece4593f073 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -501,6 +501,12 @@ private: /// = I + 1 has already been loaded. llvm::PagedVector DeclsLoaded; + using GlobalDeclMapType = ContinuousRangeMap; + + /// Mapping from global declaration IDs to the module in which the + /// declaration resides. + GlobalDeclMapType GlobalDeclMap; + using FileOffset = std::pair; using FileOffsetsTy = SmallVector; using DeclUpdateOffsetsMap = llvm::DenseMap; @@ -583,11 +589,10 @@ private: struct FileDeclsInfo { ModuleFile *Mod = nullptr; - ArrayRef Decls; + ArrayRef Decls; FileDeclsInfo() = default; - FileDeclsInfo(ModuleFile *Mod, - ArrayRef Decls) + FileDeclsInfo(ModuleFile *Mod, ArrayRef Decls) : Mod(Mod), Decls(Decls) {} }; @@ -596,7 +601,11 @@ private: /// An array of lexical contents of a declaration context, as a sequence of /// Decl::Kind, DeclID pairs. - using LexicalContents = ArrayRef; + using unaligned_decl_id_t = + llvm::support::detail::packed_endian_specific_integral< + serialization::DeclID, llvm::endianness::native, + llvm::support::unaligned>; + using LexicalContents = ArrayRef; /// Map from a DeclContext to its lexical contents. llvm::DenseMap> @@ -1477,11 +1486,10 @@ private: unsigned ClientLoadCapabilities); public: - class ModuleDeclIterator - : public llvm::iterator_adaptor_base< - ModuleDeclIterator, const serialization::unaligned_decl_id_t *, - std::random_access_iterator_tag, const Decl *, ptrdiff_t, - const Decl *, const Decl *> { + class ModuleDeclIterator : public llvm::iterator_adaptor_base< + ModuleDeclIterator, const LocalDeclID *, + std::random_access_iterator_tag, const Decl *, + ptrdiff_t, const Decl *, const Decl *> { ASTReader *Reader = nullptr; ModuleFile *Mod = nullptr; @@ -1489,11 +1497,11 @@ public: ModuleDeclIterator() : iterator_adaptor_base(nullptr) {} ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod, - const serialization::unaligned_decl_id_t *Pos) + const LocalDeclID *Pos) : iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {} value_type operator*() const { - return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, (LocalDeclID)*I)); + return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *I)); } value_type operator->() const { return **this; } @@ -1533,9 +1541,6 @@ private: StringRef Arg2 = StringRef(), StringRef Arg3 = StringRef()) const; void Error(llvm::Error &&Err) const; - /// Translate a \param GlobalDeclID to the index of DeclsLoaded array. - unsigned translateGlobalDeclIDToIndex(GlobalDeclID ID) const; - public: /// Load the AST file and validate its contents against the given /// Preprocessor. @@ -1907,8 +1912,7 @@ public: /// Retrieve the module file that owns the given declaration, or NULL /// if the declaration is not from a module file. - ModuleFile *getOwningModuleFile(const Decl *D) const; - ModuleFile *getOwningModuleFile(GlobalDeclID ID) const; + ModuleFile *getOwningModuleFile(const Decl *D); /// Returns the source location for the decl \p ID. SourceLocation getSourceLocationForDeclID(GlobalDeclID ID); diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 56193d44dd6f..992d26a8b88c 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -454,11 +454,23 @@ public: /// by the declaration ID (-1). const DeclOffset *DeclOffsets = nullptr; - /// Base declaration index in ASTReader for declarations local to this module. - unsigned BaseDeclIndex = 0; + /// Base declaration ID for declarations local to this module. + serialization::DeclID BaseDeclID = 0; + + /// Remapping table for declaration IDs in this module. + ContinuousRangeMap DeclRemap; + + /// Mapping from the module files that this module file depends on + /// to the base declaration ID for that module as it is understood within this + /// module. + /// + /// This is effectively a reverse global-to-local mapping for declaration + /// IDs, so that we can interpret a true global ID (for this translation unit) + /// as a local ID (for this module file). + llvm::DenseMap GlobalToLocalDeclIDs; /// Array of file-level DeclIDs sorted by file. - const serialization::unaligned_decl_id_t *FileSortedDecls = nullptr; + const LocalDeclID *FileSortedDecls = nullptr; unsigned NumFileSortedDecls = 0; /// Array of category list location information within this diff --git a/clang/include/clang/Serialization/ModuleManager.h b/clang/include/clang/Serialization/ModuleManager.h index f898dab39f06..d770bc52eaf4 100644 --- a/clang/include/clang/Serialization/ModuleManager.h +++ b/clang/include/clang/Serialization/ModuleManager.h @@ -45,7 +45,7 @@ namespace serialization { /// Manages the set of modules loaded by an AST reader. class ModuleManager { /// The chain of AST files, in the order in which we started to load - /// them. + /// them (this order isn't really useful for anything). SmallVector, 2> Chain; /// The chain of non-module PCH files. The first entry is the one named diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 40b58efaaf1b..ffb22194bce5 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -74,17 +74,18 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context, GlobalDeclID ID, std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. - static_assert(sizeof(uint64_t) >= alignof(Decl), "Decl won't be misaligned"); + static_assert(sizeof(unsigned) * 2 >= alignof(Decl), + "Decl won't be misaligned"); void *Start = Context.Allocate(Size + Extra + 8); void *Result = (char*)Start + 8; - uint64_t *PrefixPtr = (uint64_t *)Result - 1; + unsigned *PrefixPtr = (unsigned *)Result - 2; - *PrefixPtr = ID.get(); + // Zero out the first 4 bytes; this is used to store the owning module ID. + PrefixPtr[0] = 0; - // We leave the upper 16 bits to store the module IDs. 48 bits should be - // sufficient to store a declaration ID. - assert(*PrefixPtr < llvm::maskTrailingOnes(48)); + // Store the global declaration ID in the second 4 bytes. + PrefixPtr[1] = ID.get(); return Result; } @@ -110,29 +111,6 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Ctx, return ::operator new(Size + Extra, Ctx); } -GlobalDeclID Decl::getGlobalID() const { - if (!isFromASTFile()) - return GlobalDeclID(); - // See the comments in `Decl::operator new` for details. - uint64_t ID = *((const uint64_t *)this - 1); - return GlobalDeclID(ID & llvm::maskTrailingOnes(48)); -} - -unsigned Decl::getOwningModuleID() const { - if (!isFromASTFile()) - return 0; - - uint64_t ID = *((const uint64_t *)this - 1); - return ID >> 48; -} - -void Decl::setOwningModuleID(unsigned ID) { - assert(isFromASTFile() && "Only works on a deserialized declaration"); - uint64_t *IDAddress = (uint64_t *)this - 1; - assert(!((*IDAddress) >> 48) && "We should only set the module ID once"); - *IDAddress |= (uint64_t)ID << 48; -} - Module *Decl::getOwningModuleSlow() const { assert(isFromASTFile() && "Not from AST file?"); return getASTContext().getExternalSource()->getModule(getOwningModuleID()); @@ -2186,7 +2164,3 @@ DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C, return DD; } - -unsigned DeclIDBase::getLocalDeclIndex() const { - return ID & llvm::maskTrailingOnes(32); -} diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index da99d09de0aa..ae72fcdd2611 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1657,7 +1657,7 @@ bool ASTReader::ReadSLocEntry(int ID) { unsigned NumFileDecls = Record[7]; if (NumFileDecls && ContextObj) { - const unaligned_decl_id_t *FirstDecl = F->FileSortedDecls + Record[6]; + const LocalDeclID *FirstDecl = F->FileSortedDecls + Record[6]; assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?"); FileDeclIDs[FID] = FileDeclsInfo(F, llvm::ArrayRef(FirstDecl, NumFileDecls)); @@ -3376,11 +3376,26 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, "duplicate DECL_OFFSET record in AST file"); F.DeclOffsets = (const DeclOffset *)Blob.data(); F.LocalNumDecls = Record[0]; - F.BaseDeclIndex = getTotalNumDecls(); + unsigned LocalBaseDeclID = Record[1]; + F.BaseDeclID = getTotalNumDecls(); - if (F.LocalNumDecls > 0) - DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls); + if (F.LocalNumDecls > 0) { + // Introduce the global -> local mapping for declarations within this + // module. + GlobalDeclMap.insert(std::make_pair( + GlobalDeclID(getTotalNumDecls() + NUM_PREDEF_DECL_IDS), &F)); + + // Introduce the local -> global mapping for declarations within this + // module. + F.DeclRemap.insertOrReplace( + std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID)); + + // Introduce the global -> local mapping for declarations within this + // module. + F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID; + DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls); + } break; } @@ -3615,7 +3630,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; case FILE_SORTED_DECLS: - F.FileSortedDecls = (const unaligned_decl_id_t *)Blob.data(); + F.FileSortedDecls = (const LocalDeclID *)Blob.data(); F.NumFileSortedDecls = Record[0]; break; @@ -4042,6 +4057,7 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap); RemapBuilder SubmoduleRemap(F.SubmoduleRemap); RemapBuilder SelectorRemap(F.SelectorRemap); + RemapBuilder DeclRemap(F.DeclRemap); RemapBuilder TypeRemap(F.TypeRemap); auto &ImportedModuleVector = F.TransitiveImports; @@ -4080,6 +4096,8 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { endian::readNext(Data); uint32_t SelectorIDOffset = endian::readNext(Data); + uint32_t DeclIDOffset = + endian::readNext(Data); uint32_t TypeIndexOffset = endian::readNext(Data); @@ -4097,7 +4115,11 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { PreprocessedEntityRemap); mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap); mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap); + mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap); mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap); + + // Global -> local mappings. + F.GlobalToLocalDeclIDs[OM] = DeclIDOffset; } } @@ -7621,25 +7643,18 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { GlobalDeclID ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const { - if (LocalID.get() < NUM_PREDEF_DECL_IDS) - return GlobalDeclID(LocalID.get()); - - unsigned OwningModuleFileIndex = LocalID.getModuleFileIndex(); - DeclID ID = LocalID.getLocalDeclIndex(); + DeclID ID = LocalID.get(); + if (ID < NUM_PREDEF_DECL_IDS) + return GlobalDeclID(ID); if (!F.ModuleOffsetMap.empty()) ReadModuleOffsetMap(F); - ModuleFile *OwningModuleFile = - OwningModuleFileIndex == 0 - ? &F - : F.TransitiveImports[OwningModuleFileIndex - 1]; - - if (OwningModuleFileIndex == 0) - ID -= NUM_PREDEF_DECL_IDS; + ContinuousRangeMap::iterator I = + F.DeclRemap.find(ID - NUM_PREDEF_DECL_IDS); + assert(I != F.DeclRemap.end() && "Invalid index into decl index remap"); - uint64_t NewModuleFileIndex = OwningModuleFile->Index + 1; - return GlobalDeclID(ID, NewModuleFileIndex); + return GlobalDeclID(ID + I->second); } bool ASTReader::isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const { @@ -7647,33 +7662,31 @@ bool ASTReader::isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const { if (ID.get() < NUM_PREDEF_DECL_IDS) return false; - unsigned ModuleFileIndex = ID.getModuleFileIndex(); - return M.Index == ModuleFileIndex - 1; -} - -ModuleFile *ASTReader::getOwningModuleFile(GlobalDeclID ID) const { - // Predefined decls aren't from any module. - if (ID.get() < NUM_PREDEF_DECL_IDS) - return nullptr; - - uint64_t ModuleFileIndex = ID.getModuleFileIndex(); - assert(ModuleFileIndex && "Untranslated Local Decl?"); - - return &getModuleManager()[ModuleFileIndex - 1]; + return ID.get() - NUM_PREDEF_DECL_IDS >= M.BaseDeclID && + ID.get() - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls; } -ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) const { +ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) { if (!D->isFromASTFile()) return nullptr; - - return getOwningModuleFile(GlobalDeclID(D->getGlobalID())); + GlobalDeclMapType::const_iterator I = + GlobalDeclMap.find(GlobalDeclID(D->getGlobalID())); + assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); + return I->second; } SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) { if (ID.get() < NUM_PREDEF_DECL_IDS) return SourceLocation(); - if (Decl *D = GetExistingDecl(ID)) + unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; + + if (Index > DeclsLoaded.size()) { + Error("declaration ID out-of-range for AST file"); + return SourceLocation(); + } + + if (Decl *D = DeclsLoaded[Index]) return D->getLocation(); SourceLocation Loc; @@ -7740,19 +7753,8 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { llvm_unreachable("PredefinedDeclIDs unknown enum value"); } -unsigned ASTReader::translateGlobalDeclIDToIndex(GlobalDeclID GlobalID) const { - ModuleFile *OwningModuleFile = getOwningModuleFile(GlobalID); - if (!OwningModuleFile) { - assert(GlobalID.get() < NUM_PREDEF_DECL_IDS && "Untransalted Global ID?"); - return GlobalID.get(); - } - - return OwningModuleFile->BaseDeclIndex + GlobalID.getLocalDeclIndex(); -} - Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { assert(ContextObj && "reading decl with no AST context"); - if (ID.get() < NUM_PREDEF_DECL_IDS) { Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID); if (D) { @@ -7765,7 +7767,7 @@ Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { return D; } - unsigned Index = translateGlobalDeclIDToIndex(ID); + unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; if (Index >= DeclsLoaded.size()) { assert(0 && "declaration ID out-of-range for AST file"); @@ -7780,7 +7782,7 @@ Decl *ASTReader::GetDecl(GlobalDeclID ID) { if (ID.get() < NUM_PREDEF_DECL_IDS) return GetExistingDecl(ID); - unsigned Index = translateGlobalDeclIDToIndex(ID); + unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; if (Index >= DeclsLoaded.size()) { assert(0 && "declaration ID out-of-range for AST file"); @@ -7799,31 +7801,20 @@ Decl *ASTReader::GetDecl(GlobalDeclID ID) { LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, GlobalDeclID GlobalID) { - if (GlobalID.get() < NUM_PREDEF_DECL_IDS) - return LocalDeclID(GlobalID.get()); - - if (!M.ModuleOffsetMap.empty()) - ReadModuleOffsetMap(M); - - ModuleFile *Owner = getOwningModuleFile(GlobalID); - DeclID ID = GlobalID.getLocalDeclIndex(); - - if (Owner == &M) { - ID += NUM_PREDEF_DECL_IDS; + DeclID ID = GlobalID.get(); + if (ID < NUM_PREDEF_DECL_IDS) return LocalDeclID(ID); - } - uint64_t OrignalModuleFileIndex = 0; - for (unsigned I = 0; I < M.TransitiveImports.size(); I++) - if (M.TransitiveImports[I] == Owner) { - OrignalModuleFileIndex = I + 1; - break; - } + GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID); + assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); + ModuleFile *Owner = I->second; - if (!OrignalModuleFileIndex) + llvm::DenseMap::iterator Pos = + M.GlobalToLocalDeclIDs.find(Owner); + if (Pos == M.GlobalToLocalDeclIDs.end()) return LocalDeclID(); - return LocalDeclID(ID, OrignalModuleFileIndex); + return LocalDeclID(ID - Owner->BaseDeclID + Pos->second); } GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordData &Record, @@ -7902,34 +7893,32 @@ void ASTReader::FindExternalLexicalDecls( namespace { -class UnalignedDeclIDComp { +class DeclIDComp { ASTReader &Reader; ModuleFile &Mod; public: - UnalignedDeclIDComp(ASTReader &Reader, ModuleFile &M) - : Reader(Reader), Mod(M) {} + DeclIDComp(ASTReader &Reader, ModuleFile &M) : Reader(Reader), Mod(M) {} - bool operator()(unaligned_decl_id_t L, unaligned_decl_id_t R) const { + bool operator()(LocalDeclID L, LocalDeclID R) const { SourceLocation LHS = getLocation(L); SourceLocation RHS = getLocation(R); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - bool operator()(SourceLocation LHS, unaligned_decl_id_t R) const { + bool operator()(SourceLocation LHS, LocalDeclID R) const { SourceLocation RHS = getLocation(R); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - bool operator()(unaligned_decl_id_t L, SourceLocation RHS) const { + bool operator()(LocalDeclID L, SourceLocation RHS) const { SourceLocation LHS = getLocation(L); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - SourceLocation getLocation(unaligned_decl_id_t ID) const { + SourceLocation getLocation(LocalDeclID ID) const { return Reader.getSourceManager().getFileLoc( - Reader.getSourceLocationForDeclID( - Reader.getGlobalDeclID(Mod, (LocalDeclID)ID))); + Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID))); } }; @@ -7952,8 +7941,8 @@ void ASTReader::FindFileRegionDecls(FileID File, BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset); SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length); - UnalignedDeclIDComp DIDComp(*this, *DInfo.Mod); - ArrayRef::iterator BeginIt = + DeclIDComp DIDComp(*this, *DInfo.Mod); + ArrayRef::iterator BeginIt = llvm::lower_bound(DInfo.Decls, BeginLoc, DIDComp); if (BeginIt != DInfo.Decls.begin()) --BeginIt; @@ -7962,18 +7951,17 @@ void ASTReader::FindFileRegionDecls(FileID File, // to backtrack until we find it otherwise we will fail to report that the // region overlaps with an objc container. while (BeginIt != DInfo.Decls.begin() && - GetDecl(getGlobalDeclID(*DInfo.Mod, (LocalDeclID)(*BeginIt))) + GetDecl(getGlobalDeclID(*DInfo.Mod, *BeginIt)) ->isTopLevelDeclInObjCContainer()) --BeginIt; - ArrayRef::iterator EndIt = + ArrayRef::iterator EndIt = llvm::upper_bound(DInfo.Decls, EndLoc, DIDComp); if (EndIt != DInfo.Decls.end()) ++EndIt; - for (ArrayRef::iterator DIt = BeginIt; DIt != EndIt; - ++DIt) - Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, (LocalDeclID)(*DIt)))); + for (ArrayRef::iterator DIt = BeginIt; DIt != EndIt; ++DIt) + Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt))); } bool @@ -8180,6 +8168,7 @@ LLVM_DUMP_METHOD void ASTReader::dump() { dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap); dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap); dumpModuleIDMap("Global type map", GlobalTypeMap); + dumpModuleIDMap("Global declaration map", GlobalDeclMap); dumpModuleIDMap("Global identifier map", GlobalIdentifierMap); dumpModuleIDMap("Global macro map", GlobalMacroMap); dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 519c7d5c20fd..61cc99d4df68 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3244,10 +3244,11 @@ bool ASTReader::isConsumerInterestedIn(Decl *D) { /// Get the correct cursor and offset for loading a declaration. ASTReader::RecordLocation ASTReader::DeclCursorForID(GlobalDeclID ID, SourceLocation &Loc) { - ModuleFile *M = getOwningModuleFile(ID); - assert(M); - unsigned LocalDeclIndex = ID.getLocalDeclIndex(); - const DeclOffset &DOffs = M->DeclOffsets[LocalDeclIndex]; + GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID); + assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); + ModuleFile *M = I->second; + const DeclOffset &DOffs = + M->DeclOffsets[ID.get() - M->BaseDeclID - NUM_PREDEF_DECL_IDS]; Loc = ReadSourceLocation(*M, DOffs.getRawLoc()); return RecordLocation(M, DOffs.getBitOffset(M->DeclsBlockStartOffset)); } @@ -3790,6 +3791,7 @@ void ASTReader::markIncompleteDeclChain(Decl *D) { /// Read the declaration at the given offset from the AST file. Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { + unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; SourceLocation DeclLoc; RecordLocation Loc = DeclCursorForID(ID, DeclLoc); llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor; @@ -4120,7 +4122,7 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { } assert(D && "Unknown declaration reading AST file"); - LoadedDecl(translateGlobalDeclIDToIndex(ID), D); + LoadedDecl(Index, D); // Set the DeclContext before doing any deserialization, to make sure internal // calls to Decl::getASTContext() by Decl's methods will find the // TranslationUnitDecl without crashing. diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 4f1d2c532bc9..eb41a205bc82 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3357,10 +3357,12 @@ void ASTWriter::WriteTypeDeclOffsets() { Abbrev = std::make_shared(); Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base decl ID Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); { - RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size()}; + RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(), + FirstDeclID.get() - NUM_PREDEF_DECL_IDS}; Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets)); } } @@ -5422,6 +5424,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, M.NumPreprocessedEntities); writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules); writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors); + writeBaseIDOrNone(M.BaseDeclID, M.LocalNumDecls); writeBaseIDOrNone(M.BaseTypeIndex, M.LocalNumTypes); } } @@ -6614,11 +6617,13 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) { // Note, this will get called multiple times, once one the reader starts up // and again each time it's done reading a PCH or module. + FirstDeclID = LocalDeclID(NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls()); FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes(); FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros(); FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules(); FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors(); + NextDeclID = FirstDeclID; NextTypeID = FirstTypeID; NextIdentID = FirstIdentID; NextMacroID = FirstMacroID; diff --git a/clang/lib/Serialization/ModuleFile.cpp b/clang/lib/Serialization/ModuleFile.cpp index f64a59bd9489..2c42d33a8f5d 100644 --- a/clang/lib/Serialization/ModuleFile.cpp +++ b/clang/lib/Serialization/ModuleFile.cpp @@ -87,6 +87,7 @@ LLVM_DUMP_METHOD void ModuleFile::dump() { << " Number of types: " << LocalNumTypes << '\n'; dumpLocalRemap("Type index local -> global map", TypeRemap); - llvm::errs() << " Base decl index: " << BaseDeclIndex << '\n' + llvm::errs() << " Base decl ID: " << BaseDeclID << '\n' << " Number of decls: " << LocalNumDecls << '\n'; + dumpLocalRemap("Decl ID local -> global map", DeclRemap); } diff --git a/clang/test/Modules/no-transitive-decls-change.cppm b/clang/test/Modules/no-transitive-decls-change.cppm deleted file mode 100644 index 42ac061bc90b..000000000000 --- a/clang/test/Modules/no-transitive-decls-change.cppm +++ /dev/null @@ -1,112 +0,0 @@ -// Testing that changing a declaration in an unused module file won't change -// the BMI of the current module file. -// -// RUN: rm -rf %t -// RUN: split-file %s %t -// -// RUN: %clang_cc1 -std=c++20 %t/m-partA.cppm -emit-reduced-module-interface -o %t/m-partA.pcm -// RUN: %clang_cc1 -std=c++20 %t/m-partA.v1.cppm -emit-reduced-module-interface -o \ -// RUN: %t/m-partA.v1.pcm -// RUN: %clang_cc1 -std=c++20 %t/m-partB.cppm -emit-reduced-module-interface -o %t/m-partB.pcm -// RUN: %clang_cc1 -std=c++20 %t/m.cppm -emit-reduced-module-interface -o %t/m.pcm \ -// RUN: -fmodule-file=m:partA=%t/m-partA.pcm -fmodule-file=m:partB=%t/m-partB.pcm -// RUN: %clang_cc1 -std=c++20 %t/m.cppm -emit-reduced-module-interface -o %t/m.v1.pcm \ -// RUN: -fmodule-file=m:partA=%t/m-partA.v1.pcm -fmodule-file=m:partB=%t/m-partB.pcm -// -// RUN: %clang_cc1 -std=c++20 %t/useBOnly.cppm -emit-reduced-module-interface -o %t/useBOnly.pcm \ -// RUN: -fmodule-file=m=%t/m.pcm -fmodule-file=m:partA=%t/m-partA.pcm \ -// RUN: -fmodule-file=m:partB=%t/m-partB.pcm -// RUN: %clang_cc1 -std=c++20 %t/useBOnly.cppm -emit-reduced-module-interface -o %t/useBOnly.v1.pcm \ -// RUN: -fmodule-file=m=%t/m.v1.pcm -fmodule-file=m:partA=%t/m-partA.v1.pcm \ -// RUN: -fmodule-file=m:partB=%t/m-partB.pcm -// Since useBOnly only uses partB from module M, the change in partA shouldn't affect -// useBOnly. -// RUN: diff %t/useBOnly.pcm %t/useBOnly.v1.pcm &> /dev/null - -//--- m-partA.cppm -export module m:partA; - -namespace A_Impl { - inline int getAImpl() { - return 43; - } - - inline int getA2Impl() { - return 43; - } -} - -namespace A { - using A_Impl::getAImpl; -} - -export inline int getA() { - return 43; -} - -export inline int getA2(int) { - return 88; -} - -//--- m-partA.v1.cppm -export module m:partA; - -namespace A_Impl { - inline int getAImpl() { - return 43; - } - - inline int getA2Impl() { - return 43; - } -} - -namespace A { - using A_Impl::getAImpl; - // Adding a new declaration without introducing a new declaration name. - using A_Impl::getA2Impl; -} - -inline int getA() { - return 43; -} - -inline int getA2(int) { - return 88; -} - -// Now we add a new declaration without introducing new identifier and new types. -// The consuming module which didn't use m:partA completely is expected to be -// not changed. -inline int getA(int) { - return 88; -} - -//--- m-partB.cppm -export module m:partB; - -export inline int getB() { - return 430; -} - -//--- m.cppm -export module m; -export import :partA; -export import :partB; - -//--- useBOnly.cppm -export module useBOnly; -import m; - -export inline int get() { - return getB(); -} - -//--- useAOnly.cppm -export module useAOnly; -import m; - -export inline int get() { - A a; - return a.getValue(); -} -- GitLab From 22a7f7c3314328dd1ac20042158f4b68a4ac5c1f Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Mon, 3 Jun 2024 18:20:45 +0700 Subject: [PATCH 077/678] [symbolizer] Empty string is not an error (#92660) After commit 1792852f86dc7 ([symbolizer] Change reaction on invalid input) llvm-symbolizer issues an error on malformed command instead of echoing it to the standard output, as in previous versions. It turns out this behavior broke a use case when echoing was used to check if llvm-symbolizer is working (https://github.com/llvm/llvm-project/commit/1792852f86dc75efa1f44d46b1a0daf386d64afa#commitcomment-142161925). With this change an empty line as input is not considered as an error anymore and does not produce any output on stderr. llvm-symbolizer still respond on empty line with line not found, this is consistent with GNU addr2line. --------- Co-authored-by: James Henderson <46713263+jh7370@users.noreply.github.com> --- llvm/test/tools/llvm-symbolizer/get-input-file.test | 6 ++---- llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/llvm/test/tools/llvm-symbolizer/get-input-file.test b/llvm/test/tools/llvm-symbolizer/get-input-file.test index 8c21816591c8..50eb05196871 100644 --- a/llvm/test/tools/llvm-symbolizer/get-input-file.test +++ b/llvm/test/tools/llvm-symbolizer/get-input-file.test @@ -1,9 +1,9 @@ # If binary input file is not specified, llvm-symbolizer assumes it is the first # item in the command. -# No input items at all, complain about missing input file. +# No input items at all. Report an unknown line, but do not produce any output on stderr. RUN: echo | llvm-symbolizer 2>%t.1.err | FileCheck %s --check-prefix=NOSOURCE -RUN: FileCheck --input-file=%t.1.err --check-prefix=NOFILE %s +RUN: FileCheck --input-file=%t.1.err --implicit-check-not={{.}} --allow-empty %s # Only one input item, complain about missing addresses. RUN: llvm-symbolizer "foo" 2>%t.2.err | FileCheck %s --check-prefix=NOSOURCE @@ -32,8 +32,6 @@ RUN: FileCheck --input-file=%t.7.err --check-prefix=BAD-QUOTE %s NOSOURCE: ?? NOSOURCE-NEXT: ??:0:0 -NOFILE: error: no input filename has been specified - NOADDR: error: 'foo': no module offset has been specified NOTFOUND: error: 'foo': [[MSG]] diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp index b98bdbc388fa..6d7953f3109a 100644 --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -337,6 +337,14 @@ static void symbolizeInput(const opt::InputArgList &Args, object::BuildID BuildID(IncomingBuildID.begin(), IncomingBuildID.end()); uint64_t Offset = 0; StringRef Symbol; + + // An empty input string may be used to check if the process is alive and + // responding to input. Do not emit a message on stderr in this case but + // respond on stdout. + if (InputString.empty()) { + printUnknownLineInfo(ModuleName, Printer); + return; + } if (Error E = parseCommand(Args.getLastArgValue(OPT_obj_EQ), IsAddr2Line, StringRef(InputString), Cmd, ModuleName, BuildID, Symbol, Offset)) { -- GitLab From 12fcca0afeb08fbe41d79c5387cfacb249992bb4 Mon Sep 17 00:00:00 2001 From: Corentin Ferry Date: Mon, 3 Jun 2024 13:22:52 +0200 Subject: [PATCH 078/678] [mlir][emitc] Lower arith.andi, arith.ori, arith.xori to EmitC This commit lowers bitwise arith ops to EmitC and also brings in `adaptValueType` and `adaptIntegralTypeSignedness` that other ArithToEmitC functions can benefit from. --- .../Conversion/ArithToEmitC/ArithToEmitC.cpp | 62 +++++++++++++++++++ .../ArithToEmitC/arith-to-emitc.mlir | 39 ++++++++++++ 2 files changed, 101 insertions(+) diff --git a/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp b/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp index 388794ec122d..9b1e47147861 100644 --- a/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp +++ b/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp @@ -40,6 +40,25 @@ public: } }; +/// Get the signed or unsigned type corresponding to \p ty. +Type adaptIntegralTypeSignedness(Type ty, bool needsUnsigned) { + if (isa(ty)) { + if (ty.isUnsignedInteger() != needsUnsigned) { + auto signedness = needsUnsigned + ? IntegerType::SignednessSemantics::Unsigned + : IntegerType::SignednessSemantics::Signed; + return IntegerType::get(ty.getContext(), ty.getIntOrFloatBitWidth(), + signedness); + } + } + return ty; +} + +/// Insert a cast operation to type \p ty if \p val does not have this type. +Value adaptValueType(Value val, ConversionPatternRewriter &rewriter, Type ty) { + return rewriter.createOrFold(val.getLoc(), ty, val); +} + class CmpIOpConversion : public OpConversionPattern { public: using OpConversionPattern::OpConversionPattern; @@ -265,6 +284,46 @@ public: } }; +template +class BitwiseOpConversion : public OpConversionPattern { +public: + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(ArithOp op, typename ArithOp::Adaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + + Type type = this->getTypeConverter()->convertType(op.getType()); + if (!isa_and_nonnull(type)) { + return rewriter.notifyMatchFailure( + op, + "expected integer type, vector/tensor support not yet implemented"); + } + + // Bitwise ops can be performed directly on booleans + if (type.isInteger(1)) { + rewriter.replaceOpWithNewOp(op, type, adaptor.getLhs(), + adaptor.getRhs()); + return success(); + } + + // Bitwise ops are defined by the C standard on unsigned operands. + Type arithmeticType = + adaptIntegralTypeSignedness(type, /*needsUnsigned=*/true); + + Value lhs = adaptValueType(adaptor.getLhs(), rewriter, arithmeticType); + Value rhs = adaptValueType(adaptor.getRhs(), rewriter, arithmeticType); + + Value arithmeticResult = rewriter.template create( + op.getLoc(), arithmeticType, lhs, rhs); + + Value result = adaptValueType(arithmeticResult, rewriter, type); + + rewriter.replaceOp(op, result); + return success(); + } +}; + class SelectOpConversion : public OpConversionPattern { public: using OpConversionPattern::OpConversionPattern; @@ -401,6 +460,9 @@ void mlir::populateArithToEmitCPatterns(TypeConverter &typeConverter, IntegerOpConversion, IntegerOpConversion, IntegerOpConversion, + BitwiseOpConversion, + BitwiseOpConversion, + BitwiseOpConversion, CmpIOpConversion, SelectOpConversion, // Truncation is guaranteed for unsigned types. diff --git a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir index dac3fd99b607..5b1a1860b0f9 100644 --- a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir +++ b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir @@ -88,6 +88,45 @@ func.func @arith_index(%arg0: index, %arg1: index) { // ----- +// CHECK-LABEL: arith_bitwise +// CHECK-SAME: %[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32 +func.func @arith_bitwise(%arg0: i32, %arg1: i32) { + // CHECK: %[[C1:[^ ]*]] = emitc.cast %[[ARG0]] : i32 to ui32 + // CHECK: %[[C2:[^ ]*]] = emitc.cast %[[ARG1]] : i32 to ui32 + // CHECK: %[[AND:[^ ]*]] = emitc.bitwise_and %[[C1]], %[[C2]] : (ui32, ui32) -> ui32 + // CHECK: %[[C3:[^ ]*]] = emitc.cast %[[AND]] : ui32 to i32 + %0 = arith.andi %arg0, %arg1 : i32 + // CHECK: %[[C1:[^ ]*]] = emitc.cast %[[ARG0]] : i32 to ui32 + // CHECK: %[[C2:[^ ]*]] = emitc.cast %[[ARG1]] : i32 to ui32 + // CHECK: %[[OR:[^ ]*]] = emitc.bitwise_or %[[C1]], %[[C2]] : (ui32, ui32) -> ui32 + // CHECK: %[[C3:[^ ]*]] = emitc.cast %[[OR]] : ui32 to i32 + %1 = arith.ori %arg0, %arg1 : i32 + // CHECK: %[[C1:[^ ]*]] = emitc.cast %[[ARG0]] : i32 to ui32 + // CHECK: %[[C2:[^ ]*]] = emitc.cast %[[ARG1]] : i32 to ui32 + // CHECK: %[[XOR:[^ ]*]] = emitc.bitwise_xor %[[C1]], %[[C2]] : (ui32, ui32) -> ui32 + // CHECK: %[[C3:[^ ]*]] = emitc.cast %[[XOR]] : ui32 to i32 + %2 = arith.xori %arg0, %arg1 : i32 + + return +} + +// ----- + +// CHECK-LABEL: arith_bitwise_bool +// CHECK-SAME: %[[ARG0:.*]]: i1, %[[ARG1:.*]]: i1 +func.func @arith_bitwise_bool(%arg0: i1, %arg1: i1) { + // CHECK: %[[AND:[^ ]*]] = emitc.bitwise_and %[[ARG0]], %[[ARG1]] : (i1, i1) -> i1 + %0 = arith.andi %arg0, %arg1 : i1 + // CHECK: %[[OR:[^ ]*]] = emitc.bitwise_or %[[ARG0]], %[[ARG1]] : (i1, i1) -> i1 + %1 = arith.ori %arg0, %arg1 : i1 + // CHECK: %[[xor:[^ ]*]] = emitc.bitwise_xor %[[ARG0]], %[[ARG1]] : (i1, i1) -> i1 + %2 = arith.xori %arg0, %arg1 : i1 + + return +} + +// ----- + // CHECK-LABEL: arith_signed_integer_div_rem func.func @arith_signed_integer_div_rem(%arg0: i32, %arg1: i32) { // CHECK: emitc.div %arg0, %arg1 : (i32, i32) -> i32 -- GitLab From 9a7bd8a60f03595be5d42315790df6d409f81091 Mon Sep 17 00:00:00 2001 From: Takuto Ikuta Date: Mon, 3 Jun 2024 20:30:14 +0900 Subject: [PATCH 079/678] remove goma support from clang (#93942) goma is deprecated and not maintained anymore. https://chromium.googlesource.com/infra/goma/client/ --- clang/lib/Tooling/JSONCompilationDatabase.cpp | 5 ++--- clang/unittests/Tooling/CompilationDatabaseTest.cpp | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp b/clang/lib/Tooling/JSONCompilationDatabase.cpp index a77686996879..5ecba5dfece3 100644 --- a/clang/lib/Tooling/JSONCompilationDatabase.cpp +++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -260,7 +260,7 @@ static llvm::StringRef stripExecutableExtension(llvm::StringRef Name) { return Name; } -// There are compiler-wrappers (ccache, distcc, gomacc) that take the "real" +// There are compiler-wrappers (ccache, distcc) that take the "real" // compiler as an argument, e.g. distcc gcc -O3 foo.c. // These end up in compile_commands.json when people set CC="distcc gcc". // Clang's driver doesn't understand this, so we need to unwrap. @@ -269,8 +269,7 @@ static bool unwrapCommand(std::vector &Args) { return false; StringRef Wrapper = stripExecutableExtension(llvm::sys::path::filename(Args.front())); - if (Wrapper == "distcc" || Wrapper == "gomacc" || Wrapper == "ccache" || - Wrapper == "sccache") { + if (Wrapper == "distcc" || Wrapper == "ccache" || Wrapper == "sccache") { // Most of these wrappers support being invoked 3 ways: // `distcc g++ file.c` This is the mode we're trying to match. // We need to drop `distcc`. diff --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp b/clang/unittests/Tooling/CompilationDatabaseTest.cpp index 45062cf7c16f..2032b13726c4 100644 --- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp @@ -402,7 +402,6 @@ TEST(findCompileArgsInJsonDatabase, FindsEntry) { TEST(findCompileArgsInJsonDatabase, ParsesCompilerWrappers) { std::vector> Cases = { {"distcc gcc foo.c", "gcc foo.c"}, - {"gomacc clang++ foo.c", "clang++ foo.c"}, {"sccache clang++ foo.c", "clang++ foo.c"}, {"ccache gcc foo.c", "gcc foo.c"}, {"ccache.exe gcc foo.c", "gcc foo.c"}, -- GitLab From 72c901f5e59477e568b1b04dae9de753b9d1f6f3 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Mon, 3 Jun 2024 12:50:34 +0100 Subject: [PATCH 080/678] [TableGen] CodeGenIntrinsic - pass DefaultProperties as ArrayRef instead of std::vector by value. Avoid std::vector copies as setDefaultProperties just iterates across the Records Fixes #89207 --- llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp | 4 ++-- llvm/utils/TableGen/Basic/CodeGenIntrinsics.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp index 7cb86ad95266..9153645e3d9a 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp @@ -55,7 +55,7 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) { } CodeGenIntrinsic::CodeGenIntrinsic(Record *R, - std::vector DefaultProperties) { + ArrayRef DefaultProperties) { TheDef = R; std::string DefName = std::string(R->getName()); ArrayRef DefLoc = R->getLoc(); @@ -148,7 +148,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R, } void CodeGenIntrinsic::setDefaultProperties( - Record *R, std::vector DefaultProperties) { + Record *R, ArrayRef DefaultProperties) { // opt-out of using default attributes. if (R->getValueAsBit("DisableDefaultAttributes")) return; diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h index da9e386d64d1..403706407fdb 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h @@ -14,6 +14,7 @@ #define LLVM_UTILS_TABLEGEN_CODEGENINTRINSICS_H #include "SDNodeProperties.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ModRef.h" #include @@ -140,7 +141,7 @@ struct CodeGenIntrinsic { /// Goes through all IntrProperties that have IsDefault /// value set and sets the property. - void setDefaultProperties(Record *R, std::vector DefaultProperties); + void setDefaultProperties(Record *R, ArrayRef DefaultProperties); /// Helper function to set property \p Name to true; void setProperty(Record *R); @@ -154,7 +155,7 @@ struct CodeGenIntrinsic { bool isParamImmArg(unsigned ParamIdx) const; - CodeGenIntrinsic(Record *R, std::vector DefaultProperties); + CodeGenIntrinsic(Record *R, ArrayRef DefaultProperties); }; class CodeGenIntrinsicTable { -- GitLab From 6ef785c9517e8e44ddda8263e5f319b44f56cff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= Date: Mon, 3 Jun 2024 14:23:58 +0200 Subject: [PATCH 081/678] [clang][analyzer] Move unix.BlockInCriticalSection out of alpha (#93815) After recent improvements (#80029) and testing on open-source projects, the checker is ready to move out of the alpha package. --- clang/docs/analyzer/checkers.rst | 87 ++++++++++--------- .../clang/StaticAnalyzer/Checkers/Checkers.td | 8 +- .../test/Analysis/analyzer-enabled-checkers.c | 1 + .../test/Analysis/block-in-critical-section.c | 2 +- .../Analysis/block-in-critical-section.cpp | 2 +- .../test/Analysis/block-in-critical-section.m | 2 +- ...c-library-functions-arg-enabled-checkers.c | 1 + clang/www/analyzer/alpha_checks.html | 33 ------- 8 files changed, 53 insertions(+), 83 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index bbc31832b9c3..1e75c3997a47 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -1235,6 +1235,50 @@ Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, mallo .. literalinclude:: checkers/unix_api_example.c :language: c +.. _unix-BlockInCriticalSection: + +unix.BlockInCriticalSection (C, C++) +"""""""""""""""""""""""""""""""""""" +Check for calls to blocking functions inside a critical section. +Blocking functions detected by this checker: ``sleep, getc, fgets, read, recv``. +Critical section handling functions modeled by this checker: +``lock, unlock, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``. + +.. code-block:: c + + void pthread_lock_example(pthread_mutex_t *m) { + pthread_mutex_lock(m); // note: entering critical section here + sleep(10); // warn: Call to blocking function 'sleep' inside of critical section + pthread_mutex_unlock(m); + } + +.. code-block:: cpp + + void overlapping_critical_sections(mtx_t *m1, std::mutex &m2) { + std::lock_guard lg{m2}; // note: entering critical section here + mtx_lock(m1); // note: entering critical section here + sleep(10); // warn: Call to blocking function 'sleep' inside of critical section + mtx_unlock(m1); + sleep(10); // warn: Call to blocking function 'sleep' inside of critical section + // still inside of the critical section of the std::lock_guard + } + +**Limitations** + +* The ``trylock`` and ``timedlock`` versions of acquiring locks are currently assumed to always succeed. + This can lead to false positives. + +.. code-block:: c + + void trylock_example(pthread_mutex_t *m) { + if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds + sleep(10); // warn: Call to blocking function 'sleep' inside of critical section + pthread_mutex_unlock(m); + } else { + sleep(10); // false positive: Incorrect warning about blocking function inside critical section. + } + } + .. _unix-Errno: unix.Errno (C) @@ -3130,49 +3174,6 @@ For a more detailed description of configuration options, please see the alpha.unix ^^^^^^^^^^ -.. _alpha-unix-BlockInCriticalSection: - -alpha.unix.BlockInCriticalSection (C) -""""""""""""""""""""""""""""""""""""" -Check for calls to blocking functions inside a critical section. -Blocking functions detected by this checker: ``sleep, getc, fgets, read, recv``. -Critical section handling functions modelled by this checker: ``lock, unlock, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``. - -.. code-block:: c - - void pthread_lock_example(pthread_mutex_t *m) { - pthread_mutex_lock(m); // note: entering critical section here - sleep(10); // warn: Call to blocking function 'sleep' inside of critical section - pthread_mutex_unlock(m); - } - -.. code-block:: cpp - - void overlapping_critical_sections(mtx_t *m1, std::mutex &m2) { - std::lock_guard lg{m2}; // note: entering critical section here - mtx_lock(m1); // note: entering critical section here - sleep(10); // warn: Call to blocking function 'sleep' inside of critical section - mtx_unlock(m1); - sleep(10); // warn: Call to blocking function 'sleep' inside of critical section - // still inside of the critical section of the std::lock_guard - } - -**Limitations** - -* The ``trylock`` and ``timedlock`` versions of acquiring locks are currently assumed to always succeed. - This can lead to false positives. - -.. code-block:: c - - void trylock_example(pthread_mutex_t *m) { - if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds - sleep(10); // warn: Call to blocking function 'sleep' inside of critical section - pthread_mutex_unlock(m); - } else { - sleep(10); // false positive: Incorrect warning about blocking function inside critical section. - } - } - .. _alpha-unix-Chroot: alpha.unix.Chroot (C) diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 40f443047bd4..668e9f6cf071 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -509,6 +509,10 @@ def UnixAPIMisuseChecker : Checker<"API">, HelpText<"Check calls to various UNIX/Posix functions">, Documentation; +def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">, + HelpText<"Check for calls to blocking functions inside a critical section">, + Documentation; + def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">, HelpText<"The base of several malloc() related checkers. On it's own it " "emits no reports, but adds valuable information to the analysis " @@ -619,10 +623,6 @@ def SimpleStreamChecker : Checker<"SimpleStream">, HelpText<"Check for misuses of stream APIs">, Documentation; -def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">, - HelpText<"Check for calls to blocking functions inside a critical section">, - Documentation; - } // end "alpha.unix" //===----------------------------------------------------------------------===// diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c index 9543ba8ec02f..e605c62a66ad 100644 --- a/clang/test/Analysis/analyzer-enabled-checkers.c +++ b/clang/test/Analysis/analyzer-enabled-checkers.c @@ -42,6 +42,7 @@ // CHECK-NEXT: security.insecureAPI.mktemp // CHECK-NEXT: security.insecureAPI.vfork // CHECK-NEXT: unix.API +// CHECK-NEXT: unix.BlockInCriticalSection // CHECK-NEXT: unix.cstring.CStringModeling // CHECK-NEXT: unix.DynamicMemoryModeling // CHECK-NEXT: unix.Errno diff --git a/clang/test/Analysis/block-in-critical-section.c b/clang/test/Analysis/block-in-critical-section.c index 1e174af541b1..36ecf9ac55f7 100644 --- a/clang/test/Analysis/block-in-critical-section.c +++ b/clang/test/Analysis/block-in-critical-section.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.BlockInCriticalSection -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.BlockInCriticalSection -verify %s // expected-no-diagnostics // This should not crash diff --git a/clang/test/Analysis/block-in-critical-section.cpp b/clang/test/Analysis/block-in-critical-section.cpp index 403b7a16726a..ee9a708f231a 100644 --- a/clang/test/Analysis/block-in-critical-section.cpp +++ b/clang/test/Analysis/block-in-critical-section.cpp @@ -1,5 +1,5 @@ // RUN: %clang_analyze_cc1 \ -// RUN: -analyzer-checker=alpha.unix.BlockInCriticalSection \ +// RUN: -analyzer-checker=unix.BlockInCriticalSection \ // RUN: -std=c++11 \ // RUN: -analyzer-output text \ // RUN: -verify %s diff --git a/clang/test/Analysis/block-in-critical-section.m b/clang/test/Analysis/block-in-critical-section.m index 73d58479f4bf..2b5ec31568ba 100644 --- a/clang/test/Analysis/block-in-critical-section.m +++ b/clang/test/Analysis/block-in-critical-section.m @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.BlockInCriticalSection -verify -Wno-objc-root-class %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.BlockInCriticalSection -verify -Wno-objc-root-class %s // expected-no-diagnostics @interface SomeClass diff --git a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c index 14aca5a948bf..345a4e8f44ef 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c +++ b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c @@ -50,6 +50,7 @@ // CHECK-NEXT: security.insecureAPI.mktemp // CHECK-NEXT: security.insecureAPI.vfork // CHECK-NEXT: unix.API +// CHECK-NEXT: unix.BlockInCriticalSection // CHECK-NEXT: unix.cstring.CStringModeling // CHECK-NEXT: unix.DynamicMemoryModeling // CHECK-NEXT: unix.Errno diff --git a/clang/www/analyzer/alpha_checks.html b/clang/www/analyzer/alpha_checks.html index 2c8eece41fb2..411baae695b9 100644 --- a/clang/www/analyzer/alpha_checks.html +++ b/clang/www/analyzer/alpha_checks.html @@ -780,39 +780,6 @@ void test() { - - - -