// Copyright 2024 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/base/vector.h" #include "src/objects/objects-inl.h" #include "test/cctest/cctest.h" #include "test/cctest/compiler/turboshaft-codegen-tester.h" #include "test/common/value-helper.h" namespace v8::internal::compiler::turboshaft { namespace { constexpr TurboshaftBinop kLogicOpcodes[] = …; constexpr std::array kInt32CmpOpcodes = { TurboshaftComparison::kWord32Equal, TurboshaftComparison::kInt32LessThan, TurboshaftComparison::kInt32LessThanOrEqual, TurboshaftComparison::kUint32LessThan, TurboshaftComparison::kUint32LessThanOrEqual}; #if V8_TARGET_ARCH_64_BIT constexpr std::array kInt64CmpOpcodes = { TurboshaftComparison::kWord64Equal, TurboshaftComparison::kInt64LessThan, TurboshaftComparison::kInt64LessThanOrEqual, TurboshaftComparison::kUint64LessThan, TurboshaftComparison::kUint64LessThanOrEqual}; #endif enum GraphShape { … }; enum InvertPattern { … }; enum BranchPattern { … }; constexpr GraphShape kGraphShapes[] = …; constexpr InvertPattern kInvertPatterns[] = …; constexpr BranchPattern kBranchPatterns[] = …; // These are shorter versions of ValueHelper::uint32_vector() and // ValueHelper::uint64_vector() (which are used by FOR_UINT32_INPUTS and // FOR_UINT64_INPUTS). static constexpr uint32_t uint32_test_array[] = …; static constexpr auto uint32_test_vector = …; #ifdef V8_TARGET_ARCH_64_BIT static constexpr uint64_t uint64_test_array[] = …; static constexpr auto uint64_test_vector = …; #endif // Given kGraphShapes and kInvertPatterns, defined above, the graphs produced by // the test framework, with four compares, are illustrated below. In the cases // where we insert a branch, this takes the final logic node as the input. // kBalanced - kNoInvert // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // --> logic <-- --> logic <-- // | | // ---------> logic <-------- // // kBalanced - kInvertCompare // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // not | not | // | | | | // --> logic <-- --> logic <-- // | | // | | // ---------> logic <-------- // kBalanced - kInvertCompareDouble // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // not | not | // | | | | // not | not | // | | | | // --> logic <-- --> logic <-- // | | // | | // ---------> logic <-------- // kBalanced - kInvertLogic // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // --> logic <-- --> logic <-- // | | // not | // ---------> logic <-------- // kBalanced - kInvertLogicDouble // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // --> logic <-- --> logic <-- // | | // not | // | | // not | // ---------> logic <-------- // kBalanced - kInvertCompareAndLogic // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // not | not | // | | | | // --> logic <-- --> logic <-- // | | // not | // ---------> logic <-------- // kUnbalanced - kNoInvert // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // --> logic <-- | | // | | | // --------> logic <-- | // | | // -----> logic <----- // kUnbalanced - kInvertCompare // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // not | not | // | | | | // --> logic <-- | | // | | | // --------> logic <-- | // | | // -----> logic <----- // kUnbalanced - kInvertCompareDouble // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // not | not | // | | | | // not | not | // | | | | // --> logic <-- | | // | | | // --------> logic <-- | // | | // -----> logic <----- // kUnbalanced - kInvertLogic // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // --> logic <-- | | // | | | // not | | // --------> logic <-- | // | | // not | // | | // -----> logic <----- // kUnbalanced - kInvertLogicDouble // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // --> logic <-- | | // | | | // not | | // | | | // not | | // --------> logic <-- | // | | // not | // | | // not | // | | // -----> logic <----- // kUnbalanced - kInvertCompareAndLogic // a b c d a b c d // | | | | | | | | // | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | // not | not | // | | | | // --> logic <-- | | // | | | // not | | // --------> logic <-- | // | | // not | // | | // -----> logic <----- template <uint32_t NumLogic, typename CompareType> class CombineCompares { … }; template <uint32_t NumLogic> class CombineCompareWord32 : public CombineCompares<NumLogic, uint32_t> { … }; template <uint32_t NumLogic> class CombineCompareWord64 : public CombineCompares<NumLogic, uint64_t> { … }; template <typename Combiner, typename InputType> void CombineCompareLogic1( const std::array<TurboshaftComparison, 5>& cmp_opcodes, MachineType (*input_type)(void), const base::Vector<const InputType>& input_vector) { … } TEST(CombineCompareWord32Logic1) { … } #if V8_TARGET_ARCH_64_BIT TEST(CombineCompareWord64Logic1) { … } #endif template <typename Combiner, typename InputType> void CombineCompareLogic2( const std::array<TurboshaftComparison, 5>& cmp_opcodes, MachineType (*input_type)(void), const base::Vector<const InputType>& input_vector) { … } TEST(CombineCompareWord32Logic2) { … } #if V8_TARGET_ARCH_64_BIT TEST(CombineCompareWord64Logic2) { … } #endif template <typename Combiner, typename InputType> void CombineCompareLogic3Zero( const std::array<TurboshaftComparison, 5>& cmp_opcodes, MachineType (*input_type)(void), const base::Vector<const InputType>& input_vector) { … } TEST(CombineCompareWord32Logic3Zero) { … } #if V8_TARGET_ARCH_64_BIT TEST(CombineCompareWord64Logic3Zero) { … } #endif template <typename Combiner, typename InputType> void CombineCompareLogic3One( const std::array<TurboshaftComparison, 5>& cmp_opcodes, MachineType (*input_type)(void), const base::Vector<const InputType>& input_vector) { … } TEST(CombineCompareWord32Logic3One) { … } #if V8_TARGET_ARCH_64_BIT TEST(CombineCompareWord64Logic3One) { … } #endif template <typename Combiner, typename InputType> void CombineCompareLogic3ThirtyTwo( const std::array<TurboshaftComparison, 5>& cmp_opcodes, MachineType (*input_type)(void), const base::Vector<const InputType>& input_vector) { … } TEST(CombineCompareWord32Logic3ThirtyTwo) { … } #if V8_TARGET_ARCH_64_BIT TEST(CombineCompareWord64Logic3ThirtyTwo) { … } #endif constexpr uint32_t kMaxDepth = …; // a b b a a b b a a b // | | | | | | | | | | // | | | | | | | | | | // -> cmp <- -> cmp <- -> cmp <- -> cmp <- -> cmp <- // | | | | | // ---> and <--- | | | // | | | | // ---------> or <---- | | // | | | // ------> and <------ | // | | // --------> or <-------- TEST(CombineCompareMaxDepth) { … } TEST(CombineCompareBranchesMaxDepth) { … } TEST(CombineCompareMaxDepthPlusOne) { … } TEST(CombineCompareTwoLogicInputs) { … } } // end namespace } // namespace v8::internal::compiler::turboshaft