14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci#include "ecmascript/compiler/bytecodes.h"
164514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit.h"
174514f5e3Sopenharmony_ci#include "ecmascript/compiler/gate_accessor.h"
184514f5e3Sopenharmony_ci#include "ecmascript/compiler/lcr_gate_meta_data.h"
194514f5e3Sopenharmony_ci#include "ecmascript/compiler/pass.h"
204514f5e3Sopenharmony_ci#include "ecmascript/compiler/share_gate_meta_data.h"
214514f5e3Sopenharmony_ci#include "ecmascript/compiler/share_opcodes.h"
224514f5e3Sopenharmony_ci#include "ecmascript/compiler/instruction_combine.h"
234514f5e3Sopenharmony_ci#include "ecmascript/compiler/verifier.h"
244514f5e3Sopenharmony_ci#include "ecmascript/compiler/gate_matchers.h"
254514f5e3Sopenharmony_ci#include "ecmascript/elements.h"
264514f5e3Sopenharmony_ci#include "ecmascript/mem/concurrent_marker.h"
274514f5e3Sopenharmony_ci#include "ecmascript/mem/machine_code.h"
284514f5e3Sopenharmony_ci#include "ecmascript/mem/native_area_allocator.h"
294514f5e3Sopenharmony_ci#include "ecmascript/tests/test_helper.h"
304514f5e3Sopenharmony_ci#include "gtest/gtest.h"
314514f5e3Sopenharmony_ci#include <cmath>
324514f5e3Sopenharmony_ci#include <cstddef>
334514f5e3Sopenharmony_ci#include <cstdint>
344514f5e3Sopenharmony_ci#include <vector>
354514f5e3Sopenharmony_ci
364514f5e3Sopenharmony_cinamespace panda::test {
374514f5e3Sopenharmony_ciclass InstructionCombineTests : public testing::Test {};
384514f5e3Sopenharmony_ciusing ecmascript::kungfu::Circuit;
394514f5e3Sopenharmony_ciusing ecmascript::kungfu::CircuitBuilder;
404514f5e3Sopenharmony_ciusing ecmascript::kungfu::CombinedPassVisitor;
414514f5e3Sopenharmony_ciusing ecmascript::kungfu::EcmaOpcode;
424514f5e3Sopenharmony_ciusing ecmascript::kungfu::Environment;
434514f5e3Sopenharmony_ciusing ecmascript::kungfu::Float64BinopMatcher;
444514f5e3Sopenharmony_ciusing ecmascript::kungfu::Float64Matcher;
454514f5e3Sopenharmony_ciusing ecmascript::kungfu::GateAccessor;
464514f5e3Sopenharmony_ciusing ecmascript::kungfu::GateRef;
474514f5e3Sopenharmony_ciusing ecmascript::kungfu::InstructionCombine;
484514f5e3Sopenharmony_ciusing ecmascript::kungfu::Int32BinopMatcher;
494514f5e3Sopenharmony_ciusing ecmascript::kungfu::Int64BinopMatcher;
504514f5e3Sopenharmony_ciusing ecmascript::kungfu::OpCode;
514514f5e3Sopenharmony_ciusing ecmascript::kungfu::PGOSampleType;
524514f5e3Sopenharmony_ciusing ecmascript::kungfu::Verifier;
534514f5e3Sopenharmony_ci// std::numeric_limits<T>::quiet_NaN().
544514f5e3Sopenharmony_citemplate <class T> T SilenceNaN(T x)
554514f5e3Sopenharmony_ci{
564514f5e3Sopenharmony_ci    assert(std::isnan(x));
574514f5e3Sopenharmony_ci    // Do some calculation to make a signalling NaN quiet.
584514f5e3Sopenharmony_ci    return x - x;
594514f5e3Sopenharmony_ci}
604514f5e3Sopenharmony_ci
614514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64AddTest)
624514f5e3Sopenharmony_ci{
634514f5e3Sopenharmony_ci    // construct a circuit
644514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
654514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
664514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
674514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
684514f5e3Sopenharmony_ci    CircuitBuilder builder(&circuit);
694514f5e3Sopenharmony_ci    Environment env(0, &builder);
704514f5e3Sopenharmony_ci    builder.SetEnvironment(&env);
714514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
724514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
734514f5e3Sopenharmony_ci
744514f5e3Sopenharmony_ci    // test  x + 0 => x
754514f5e3Sopenharmony_ci    {
764514f5e3Sopenharmony_ci        auto x = builder.Arguments(1);
774514f5e3Sopenharmony_ci        auto const_i64_0 = builder.Int64(0);
784514f5e3Sopenharmony_ci        auto test_x_add_0 = builder.Int64Add(x, const_i64_0);
794514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(test_x_add_0), x);
804514f5e3Sopenharmony_ci    }
814514f5e3Sopenharmony_ci    // test  1 + 2 => 3
824514f5e3Sopenharmony_ci    {
834514f5e3Sopenharmony_ci        auto const_i64_1 = builder.Int64(1);
844514f5e3Sopenharmony_ci        auto const_i64_2 = builder.Int64(2);
854514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int64Add(const_i64_1, const_i64_2));
864514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, 3), true);
874514f5e3Sopenharmony_ci    }
884514f5e3Sopenharmony_ci    // Test for 64-bit integer wraparound: 9223372036854775807 + 1 => -9223372036854775808
894514f5e3Sopenharmony_ci    {
904514f5e3Sopenharmony_ci        auto const_i64_max = builder.Int64(9223372036854775807);
914514f5e3Sopenharmony_ci        auto const_i64_1 = builder.Int64(1);
924514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int64Add(const_i64_max, const_i64_1));
934514f5e3Sopenharmony_ci
944514f5e3Sopenharmony_ci        // Cast -9223372036854775808 to uint64_t for comparison
954514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, static_cast<uint64_t>(9223372036854775808ULL)), true);
964514f5e3Sopenharmony_ci    }
974514f5e3Sopenharmony_ci
984514f5e3Sopenharmony_ci    // test ((y+max)+1)
994514f5e3Sopenharmony_ci    {
1004514f5e3Sopenharmony_ci        auto y = builder.Arguments(2);
1014514f5e3Sopenharmony_ci        auto const_i64_max = builder.Int64(9223372036854775807);
1024514f5e3Sopenharmony_ci        auto const_i64_1 = builder.Int64(1);
1034514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int64Add(builder.Int64Add(y, const_i64_max), const_i64_1));
1044514f5e3Sopenharmony_ci        Int64BinopMatcher result_m(result, &circuit);
1054514f5e3Sopenharmony_ci        EXPECT_EQ(result_m.Left().Gate(), y);
1064514f5e3Sopenharmony_ci        EXPECT_EQ(result_m.Right().ResolvedValue(), static_cast<uint64_t>(9223372036854775808ULL));
1074514f5e3Sopenharmony_ci    }
1084514f5e3Sopenharmony_ci    // test ((z+1)+2) => (z+3)  [z+1] not Owns
1094514f5e3Sopenharmony_ci    {
1104514f5e3Sopenharmony_ci        auto z = builder.Arguments(3);
1114514f5e3Sopenharmony_ci        auto const_i64_1 = builder.Int64(1);
1124514f5e3Sopenharmony_ci        auto const_i64_2 = builder.Int64(2);
1134514f5e3Sopenharmony_ci        auto z_add_1 = builder.Int64Add(z, const_i64_1);
1144514f5e3Sopenharmony_ci        auto intfer = builder.Int64Add(z_add_1, z_add_1);
1154514f5e3Sopenharmony_ci        (void)intfer;
1164514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int64Add(z_add_1, const_i64_2));
1174514f5e3Sopenharmony_ci        EXPECT_EQ(result, Circuit::NullGate());
1184514f5e3Sopenharmony_ci    }
1194514f5e3Sopenharmony_ci}
1204514f5e3Sopenharmony_ci
1214514f5e3Sopenharmony_ci
1224514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int32AddTest)
1234514f5e3Sopenharmony_ci{
1244514f5e3Sopenharmony_ci    // construct a circuit
1254514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
1264514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
1274514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
1284514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
1294514f5e3Sopenharmony_ci    CircuitBuilder builder(&circuit);
1304514f5e3Sopenharmony_ci    Environment env(0, &builder);
1314514f5e3Sopenharmony_ci    builder.SetEnvironment(&env);
1324514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
1334514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
1344514f5e3Sopenharmony_ci    // test  x + 0 => x
1354514f5e3Sopenharmony_ci    {
1364514f5e3Sopenharmony_ci        auto x = builder.Arguments(1);
1374514f5e3Sopenharmony_ci        auto const_i32_0 = builder.Int32(0);
1384514f5e3Sopenharmony_ci        auto test_x_add_0 = builder.Int32Add(x, const_i32_0);
1394514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(test_x_add_0), x);
1404514f5e3Sopenharmony_ci    }
1414514f5e3Sopenharmony_ci
1424514f5e3Sopenharmony_ci    // test  1 + 2 => 3
1434514f5e3Sopenharmony_ci    {
1444514f5e3Sopenharmony_ci        auto const_i32_1 = builder.Int32(1);
1454514f5e3Sopenharmony_ci        auto const_i32_2 = builder.Int32(2);
1464514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Add(const_i32_1, const_i32_2));
1474514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, 3), true);
1484514f5e3Sopenharmony_ci    }
1494514f5e3Sopenharmony_ci
1504514f5e3Sopenharmony_ci    // Test for 32-bit integer wraparound: 2147483647 + 1 => -2147483648
1514514f5e3Sopenharmony_ci    {
1524514f5e3Sopenharmony_ci        auto const_i32_max = builder.Int32(2147483647);
1534514f5e3Sopenharmony_ci        auto const_i32_1 = builder.Int32(1);
1544514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Add(const_i32_max, const_i32_1));
1554514f5e3Sopenharmony_ci
1564514f5e3Sopenharmony_ci        // Check if the result is -2147483648, demonstrating wraparound behavior
1574514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, static_cast<uint64_t>(-2147483648)), true);
1584514f5e3Sopenharmony_ci    }
1594514f5e3Sopenharmony_ci
1604514f5e3Sopenharmony_ci
1614514f5e3Sopenharmony_ci    // test (0 - x) + y => y - x
1624514f5e3Sopenharmony_ci    {
1634514f5e3Sopenharmony_ci        auto x = builder.Arguments(2);
1644514f5e3Sopenharmony_ci        auto y = builder.Arguments(3);
1654514f5e3Sopenharmony_ci        auto zero = builder.Int32(0);
1664514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Add(builder.Int32Sub(zero, x), y));
1674514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
1684514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), y);
1694514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), x);
1704514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::SUB);
1714514f5e3Sopenharmony_ci    }
1724514f5e3Sopenharmony_ci    // test  y + (0 - x) => y - x
1734514f5e3Sopenharmony_ci    {
1744514f5e3Sopenharmony_ci        auto x = builder.Arguments(4);
1754514f5e3Sopenharmony_ci        auto y = builder.Arguments(5);
1764514f5e3Sopenharmony_ci        auto zero = builder.Int32(0);
1774514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Add(y, builder.Int32Sub(zero, x)));
1784514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
1794514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), y);
1804514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), x);
1814514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::SUB);
1824514f5e3Sopenharmony_ci    }
1834514f5e3Sopenharmony_ci
1844514f5e3Sopenharmony_ci    // test ((y+1)+2) => (y+3)  [y+1] Owns
1854514f5e3Sopenharmony_ci    {
1864514f5e3Sopenharmony_ci        auto y = builder.Arguments(6);
1874514f5e3Sopenharmony_ci        auto const_1 = builder.Int32(1);
1884514f5e3Sopenharmony_ci        auto const_2 = builder.Int32(2);
1894514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Add(builder.Int32Add(y, const_1), const_2));
1904514f5e3Sopenharmony_ci        Int32BinopMatcher result_m(result, &circuit);
1914514f5e3Sopenharmony_ci        EXPECT_EQ(result_m.Left().Gate(), y);
1924514f5e3Sopenharmony_ci        EXPECT_EQ(result_m.Right().ResolvedValue(), 3);
1934514f5e3Sopenharmony_ci    }
1944514f5e3Sopenharmony_ci
1954514f5e3Sopenharmony_ci    // test ((y+max)+1)
1964514f5e3Sopenharmony_ci    {
1974514f5e3Sopenharmony_ci        auto y = builder.Arguments(6);
1984514f5e3Sopenharmony_ci        auto const_1 = builder.Int32(2147483647);
1994514f5e3Sopenharmony_ci        auto const_2 = builder.Int32(1);
2004514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Add(builder.Int32Add(y, const_1), const_2));
2014514f5e3Sopenharmony_ci        Int32BinopMatcher result_m(result, &circuit);
2024514f5e3Sopenharmony_ci        EXPECT_EQ(result_m.Left().Gate(), y);
2034514f5e3Sopenharmony_ci        EXPECT_EQ(result_m.Right().ResolvedValue(), static_cast<uint64_t>(-2147483648));
2044514f5e3Sopenharmony_ci    }
2054514f5e3Sopenharmony_ci}
2064514f5e3Sopenharmony_ci
2074514f5e3Sopenharmony_ci
2084514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64SubTest)
2094514f5e3Sopenharmony_ci{
2104514f5e3Sopenharmony_ci    // construct a circuit
2114514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
2124514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
2134514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
2144514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
2154514f5e3Sopenharmony_ci    CircuitBuilder builder(&circuit);
2164514f5e3Sopenharmony_ci    Environment env(0, &builder);
2174514f5e3Sopenharmony_ci    builder.SetEnvironment(&env);
2184514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
2194514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
2204514f5e3Sopenharmony_ci
2214514f5e3Sopenharmony_ci    // test  x - 0 => x
2224514f5e3Sopenharmony_ci    {
2234514f5e3Sopenharmony_ci        auto x = builder.Arguments(1);
2244514f5e3Sopenharmony_ci        auto const_i64_0 = builder.Int64(0);
2254514f5e3Sopenharmony_ci        auto test_x_add_0 = builder.Int64Sub(x, const_i64_0);
2264514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(test_x_add_0), x);
2274514f5e3Sopenharmony_ci    }
2284514f5e3Sopenharmony_ci    // test  1 - 2 => -1
2294514f5e3Sopenharmony_ci    {
2304514f5e3Sopenharmony_ci        auto const_i64_1 = builder.Int64(1);
2314514f5e3Sopenharmony_ci        auto const_i64_2 = builder.Int64(2);
2324514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int64Sub(const_i64_1, const_i64_2));
2334514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, (int64_t)-1), true);
2344514f5e3Sopenharmony_ci    }
2354514f5e3Sopenharmony_ci
2364514f5e3Sopenharmony_ci    // Test for 64-bit integer wraparound subtraction: -9223372036854775808 - 1 => 9223372036854775807
2374514f5e3Sopenharmony_ci    {
2384514f5e3Sopenharmony_ci        auto const_i64_min = builder.Int64(-9223372036854775807 - 1); // -9223372036854775808
2394514f5e3Sopenharmony_ci        auto const_i64_1 = builder.Int64(1);
2404514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int64Sub(const_i64_min, const_i64_1));
2414514f5e3Sopenharmony_ci
2424514f5e3Sopenharmony_ci        // Expect the result to wrap around to 9223372036854775807
2434514f5e3Sopenharmony_ci        // Casting to uint64_t for the comparison
2444514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, static_cast<uint64_t>(9223372036854775807)), true);
2454514f5e3Sopenharmony_ci    }
2464514f5e3Sopenharmony_ci
2474514f5e3Sopenharmony_ci
2484514f5e3Sopenharmony_ci    // test x -x => 0
2494514f5e3Sopenharmony_ci    {
2504514f5e3Sopenharmony_ci        auto x = builder.Arguments(2);
2514514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int64Sub(x, x));
2524514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, 0), true);
2534514f5e3Sopenharmony_ci    }
2544514f5e3Sopenharmony_ci
2554514f5e3Sopenharmony_ci    // test x - k = x + (-k)
2564514f5e3Sopenharmony_ci    {
2574514f5e3Sopenharmony_ci        auto x = builder.Arguments(3);
2584514f5e3Sopenharmony_ci        auto const_1 = builder.Int64(-1);
2594514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int64Sub(x, const_1));
2604514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
2614514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
2624514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().ResolvedValue(), 1);
2634514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::ADD);
2644514f5e3Sopenharmony_ci    }
2654514f5e3Sopenharmony_ci    // Test for x - k = x + (-k) when k is the minimum int64_t value
2664514f5e3Sopenharmony_ci    {
2674514f5e3Sopenharmony_ci        auto x = builder.Arguments(3);
2684514f5e3Sopenharmony_ci        auto const_min = builder.Int64(INT64_MIN); // Minimum int64_t value
2694514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int64Sub(x, const_min));
2704514f5e3Sopenharmony_ci
2714514f5e3Sopenharmony_ci        // Due to overflow, -k should wrap around to INT64_MIN.
2724514f5e3Sopenharmony_ci        // The opcode should be ADD if the subtraction is reinterpreted as addition with -k.
2734514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
2744514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
2754514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().ResolvedValue(), INT64_MIN); // Here, we expect that -k has wrapped around to INT64_MIN
2764514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::ADD);
2774514f5e3Sopenharmony_ci    }
2784514f5e3Sopenharmony_ci}
2794514f5e3Sopenharmony_ci
2804514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int32SubTest)
2814514f5e3Sopenharmony_ci{
2824514f5e3Sopenharmony_ci    // construct a circuit
2834514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
2844514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
2854514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
2864514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
2874514f5e3Sopenharmony_ci    CircuitBuilder builder(&circuit);
2884514f5e3Sopenharmony_ci    Environment env(0, &builder);
2894514f5e3Sopenharmony_ci    builder.SetEnvironment(&env);
2904514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
2914514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
2924514f5e3Sopenharmony_ci
2934514f5e3Sopenharmony_ci    // test  x - 0 => x
2944514f5e3Sopenharmony_ci    {
2954514f5e3Sopenharmony_ci        auto x = builder.Arguments(1);
2964514f5e3Sopenharmony_ci        auto const_i32_0 = builder.Int32(0);
2974514f5e3Sopenharmony_ci        auto test_x_add_0 = builder.Int32Sub(x, const_i32_0);
2984514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(test_x_add_0), x);
2994514f5e3Sopenharmony_ci    }
3004514f5e3Sopenharmony_ci    // test  1 - 2 => -1
3014514f5e3Sopenharmony_ci    {
3024514f5e3Sopenharmony_ci        auto const_i32_1 = builder.Int32(1);
3034514f5e3Sopenharmony_ci        auto const_i32_2 = builder.Int32(2);
3044514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Sub(const_i32_1, const_i32_2));
3054514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, (int32_t)-1), true);
3064514f5e3Sopenharmony_ci    }
3074514f5e3Sopenharmony_ci
3084514f5e3Sopenharmony_ci    // Test for 32-bit integer wraparound subtraction: -2147483648 - 1 => 2147483647
3094514f5e3Sopenharmony_ci    {
3104514f5e3Sopenharmony_ci        auto const_i32_min = builder.Int32(-2147483647 - 1); // -2147483648
3114514f5e3Sopenharmony_ci        auto const_i32_1 = builder.Int32(1);
3124514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Sub(const_i32_min, const_i32_1));
3134514f5e3Sopenharmony_ci
3144514f5e3Sopenharmony_ci        // Expect the result to wrap around to 2147483647
3154514f5e3Sopenharmony_ci        // Casting to uint64_t for the comparison, assuming IsConstantValue accepts uint64_t
3164514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, static_cast<uint64_t>(2147483647)), true);
3174514f5e3Sopenharmony_ci    }
3184514f5e3Sopenharmony_ci
3194514f5e3Sopenharmony_ci    // test x -x => 0
3204514f5e3Sopenharmony_ci    {
3214514f5e3Sopenharmony_ci        auto x = builder.Arguments(2);
3224514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Sub(x, x));
3234514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, 0), true);
3244514f5e3Sopenharmony_ci    }
3254514f5e3Sopenharmony_ci
3264514f5e3Sopenharmony_ci    // test x - k = x + (-k)
3274514f5e3Sopenharmony_ci    {
3284514f5e3Sopenharmony_ci        auto x = builder.Arguments(3);
3294514f5e3Sopenharmony_ci        auto const_1 = builder.Int32(-1);
3304514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Sub(x, const_1));
3314514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
3324514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
3334514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().ResolvedValue(), 1);
3344514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::ADD);
3354514f5e3Sopenharmony_ci    }
3364514f5e3Sopenharmony_ci
3374514f5e3Sopenharmony_ci    // Test for x - k = x + (-k) when k is the minimum int32_t value
3384514f5e3Sopenharmony_ci    {
3394514f5e3Sopenharmony_ci        auto x = builder.Arguments(3);
3404514f5e3Sopenharmony_ci        auto const_min = builder.Int32(INT32_MIN); // Minimum int32_t value
3414514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(builder.Int32Sub(x, const_min));
3424514f5e3Sopenharmony_ci
3434514f5e3Sopenharmony_ci        // Due to overflow, -k should wrap around to INT32_MIN.
3444514f5e3Sopenharmony_ci        // The opcode should be ADD if the subtraction is reinterpreted as addition with -k.
3454514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
3464514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
3474514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().ResolvedValue(), INT32_MIN); // Here, we expect that -k has wrapped around to INT32_MIN
3484514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::ADD);
3494514f5e3Sopenharmony_ci    }
3504514f5e3Sopenharmony_ci}
3514514f5e3Sopenharmony_ci
3524514f5e3Sopenharmony_ci
3534514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64MulTest)
3544514f5e3Sopenharmony_ci{
3554514f5e3Sopenharmony_ci    // construct a circuit
3564514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
3574514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
3584514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
3594514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
3604514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
3614514f5e3Sopenharmony_ci    Environment env(0, &b);
3624514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
3634514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
3644514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
3654514f5e3Sopenharmony_ci
3664514f5e3Sopenharmony_ci    // test  x * 0 => 0
3674514f5e3Sopenharmony_ci    {
3684514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
3694514f5e3Sopenharmony_ci        auto const_0 = b.Int64(0);
3704514f5e3Sopenharmony_ci        auto result = b.Int64Mul(x, const_0);
3714514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(result), const_0);
3724514f5e3Sopenharmony_ci    }
3734514f5e3Sopenharmony_ci    // test  x * 1 => x
3744514f5e3Sopenharmony_ci    {
3754514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
3764514f5e3Sopenharmony_ci        auto const_1 = b.Int64(1);
3774514f5e3Sopenharmony_ci        auto result = b.Int64Mul(x, const_1);
3784514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(result), x);
3794514f5e3Sopenharmony_ci    }
3804514f5e3Sopenharmony_ci
3814514f5e3Sopenharmony_ci    // test  1 * 2 => 2
3824514f5e3Sopenharmony_ci    {
3834514f5e3Sopenharmony_ci        auto const_1 = b.Int64(1);
3844514f5e3Sopenharmony_ci        auto const_2 = b.Int64(2);
3854514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int64Mul(const_1, const_2));
3864514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, (int64_t)2), true);
3874514f5e3Sopenharmony_ci    }
3884514f5e3Sopenharmony_ci    // Test for 64-bit integer wraparound multiplication: 9223372036854775807 * 2 => -2
3894514f5e3Sopenharmony_ci    {
3904514f5e3Sopenharmony_ci        auto const_i64_max = b.Int64(9223372036854775807); // Max int64_t value
3914514f5e3Sopenharmony_ci        auto const_i64_2 = b.Int64(2);
3924514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int64Mul(const_i64_max, const_i64_2));
3934514f5e3Sopenharmony_ci
3944514f5e3Sopenharmony_ci        // Expect the result to wrap around to -2
3954514f5e3Sopenharmony_ci        // Casting to uint64_t for the comparison
3964514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, static_cast<uint64_t>(-2)), true);
3974514f5e3Sopenharmony_ci    }
3984514f5e3Sopenharmony_ci
3994514f5e3Sopenharmony_ci    // test x * -1 => 0 - X
4004514f5e3Sopenharmony_ci    {
4014514f5e3Sopenharmony_ci        auto x = b.Arguments(2);
4024514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int64Mul(x, b.Int64(-1)));
4034514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
4044514f5e3Sopenharmony_ci
4054514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().ResolvedValue(), 0);
4064514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), x);
4074514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::SUB);
4084514f5e3Sopenharmony_ci    }
4094514f5e3Sopenharmony_ci
4104514f5e3Sopenharmony_ci    // test x * 2^n => x << n
4114514f5e3Sopenharmony_ci    {
4124514f5e3Sopenharmony_ci        auto x = b.Arguments(3);
4134514f5e3Sopenharmony_ci        auto const_4 = b.Int64(4);
4144514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int64Mul(x, const_4));
4154514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
4164514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
4174514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().ResolvedValue(), 2);
4184514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::LSL);
4194514f5e3Sopenharmony_ci    }
4204514f5e3Sopenharmony_ci
4214514f5e3Sopenharmony_ci    // (x * Int64Constant(a)) * Int64Constant(b)) => x * Int64Constant(a * b)
4224514f5e3Sopenharmony_ci    {
4234514f5e3Sopenharmony_ci        auto x = b.Arguments(4);
4244514f5e3Sopenharmony_ci        auto const_4 = b.Int64(4);
4254514f5e3Sopenharmony_ci        auto const_5 = b.Int64(5);
4264514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int64Mul(b.Int64Mul(x, const_4), const_5));
4274514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
4284514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
4294514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().ResolvedValue(), 20);
4304514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::MUL);
4314514f5e3Sopenharmony_ci    }
4324514f5e3Sopenharmony_ci    // Test for (x * Int64Constant(a)) * Int64Constant(b)) => x * Int64Constant(a * b) with overflow
4334514f5e3Sopenharmony_ci    {
4344514f5e3Sopenharmony_ci        auto x = b.Arguments(4);
4354514f5e3Sopenharmony_ci        auto const_almost_max = b.Int64(INT64_MAX - 1); // INT64_MAX - 1
4364514f5e3Sopenharmony_ci        auto const_3 = b.Int64(3);
4374514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int64Mul(b.Int64Mul(x, const_almost_max), const_3));
4384514f5e3Sopenharmony_ci
4394514f5e3Sopenharmony_ci        // Due to overflow, a * b should wrap around.
4404514f5e3Sopenharmony_ci        // The opcode should still be MUL.
4414514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
4424514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
4434514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().ResolvedValue(), 9223372036854775802);
4444514f5e3Sopenharmony_ci
4454514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::MUL);
4464514f5e3Sopenharmony_ci    }
4474514f5e3Sopenharmony_ci}
4484514f5e3Sopenharmony_ci
4494514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int32MulTest)
4504514f5e3Sopenharmony_ci{
4514514f5e3Sopenharmony_ci    // construct a circuit
4524514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
4534514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
4544514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
4554514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
4564514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
4574514f5e3Sopenharmony_ci    Environment env(0, &b);
4584514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
4594514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
4604514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
4614514f5e3Sopenharmony_ci
4624514f5e3Sopenharmony_ci    // test  x * 0 => 0
4634514f5e3Sopenharmony_ci    {
4644514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
4654514f5e3Sopenharmony_ci        auto const_0 = b.Int32(0);
4664514f5e3Sopenharmony_ci        auto result = b.Int32Mul(x, const_0);
4674514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(result), const_0);
4684514f5e3Sopenharmony_ci    }
4694514f5e3Sopenharmony_ci    // test  x * 1 => x
4704514f5e3Sopenharmony_ci    {
4714514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
4724514f5e3Sopenharmony_ci        auto const_1 = b.Int32(1);
4734514f5e3Sopenharmony_ci        auto result = b.Int32Mul(x, const_1);
4744514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(result), x);
4754514f5e3Sopenharmony_ci    }
4764514f5e3Sopenharmony_ci
4774514f5e3Sopenharmony_ci
4784514f5e3Sopenharmony_ci    // test  1 * 2 => 2
4794514f5e3Sopenharmony_ci    {
4804514f5e3Sopenharmony_ci        auto const_1 = b.Int32(1);
4814514f5e3Sopenharmony_ci        auto const_2 = b.Int32(2);
4824514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32Mul(const_1, const_2));
4834514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
4844514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, (int32_t)2), true);
4854514f5e3Sopenharmony_ci    }
4864514f5e3Sopenharmony_ci
4874514f5e3Sopenharmony_ci    // Test for 32-bit integer wraparound multiplication: 2147483647 * 2 => -2
4884514f5e3Sopenharmony_ci    {
4894514f5e3Sopenharmony_ci        auto const_i32_max = b.Int32(2147483647); // Max int32_t value
4904514f5e3Sopenharmony_ci        auto const_i32_2 = b.Int32(2);
4914514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32Mul(const_i32_max, const_i32_2));
4924514f5e3Sopenharmony_ci
4934514f5e3Sopenharmony_ci        // Expect the result to wrap around to -2
4944514f5e3Sopenharmony_ci        // Casting to uint32_t for the comparison
4954514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
4964514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetInt32FromConstant(result), -2);
4974514f5e3Sopenharmony_ci    }
4984514f5e3Sopenharmony_ci
4994514f5e3Sopenharmony_ci
5004514f5e3Sopenharmony_ci    // test x * -1 => 0 - X
5014514f5e3Sopenharmony_ci    {
5024514f5e3Sopenharmony_ci        auto x = b.Arguments(2);
5034514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32Mul(x, b.Int32(-1)));
5044514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
5054514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
5064514f5e3Sopenharmony_ci
5074514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().ResolvedValue(), 0);
5084514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), x);
5094514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::SUB);
5104514f5e3Sopenharmony_ci    }
5114514f5e3Sopenharmony_ci
5124514f5e3Sopenharmony_ci    // test x * 2^n => x << n
5134514f5e3Sopenharmony_ci    {
5144514f5e3Sopenharmony_ci        auto x = b.Arguments(3);
5154514f5e3Sopenharmony_ci        auto const_4 = b.Int32(4);
5164514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32Mul(x, const_4));
5174514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
5184514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
5194514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
5204514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().ResolvedValue(), 2);
5214514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::LSL);
5224514f5e3Sopenharmony_ci    }
5234514f5e3Sopenharmony_ci
5244514f5e3Sopenharmony_ci    // (x * Int32Constant(a)) * Int32Constant(b)) => x * Int32Constant(a * b)
5254514f5e3Sopenharmony_ci    {
5264514f5e3Sopenharmony_ci        auto x = b.Arguments(4);
5274514f5e3Sopenharmony_ci        auto const_4 = b.Int32(4);
5284514f5e3Sopenharmony_ci        auto const_5 = b.Int32(5);
5294514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32Mul(b.Int32Mul(x, const_4), const_5));
5304514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
5314514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
5324514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
5334514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().ResolvedValue(), 20);
5344514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::MUL);
5354514f5e3Sopenharmony_ci    }
5364514f5e3Sopenharmony_ci    // Test for (x * Int32Constant(a)) * Int32Constant(b)) => x * Int32Constant(a * b) with overflow
5374514f5e3Sopenharmony_ci    {
5384514f5e3Sopenharmony_ci        auto x = b.Arguments(4);
5394514f5e3Sopenharmony_ci        auto const_almost_max = b.Int32(INT32_MAX - 1); // INT32_MAX - 1
5404514f5e3Sopenharmony_ci        auto const_3 = b.Int32(3);
5414514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32Mul(b.Int32Mul(x, const_almost_max), const_3));
5424514f5e3Sopenharmony_ci
5434514f5e3Sopenharmony_ci        // Due to overflow, a * b should wrap around.
5444514f5e3Sopenharmony_ci        // The opcode should still be MUL.
5454514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
5464514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
5474514f5e3Sopenharmony_ci
5484514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().ResolvedValue(), static_cast<uint32_t>(2147483642));
5494514f5e3Sopenharmony_ci
5504514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::MUL);
5514514f5e3Sopenharmony_ci    }
5524514f5e3Sopenharmony_ci}
5534514f5e3Sopenharmony_ci
5544514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64DivTest)
5554514f5e3Sopenharmony_ci{
5564514f5e3Sopenharmony_ci    // construct a circuit
5574514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
5584514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
5594514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
5604514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
5614514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
5624514f5e3Sopenharmony_ci    Environment env(0, &b);
5634514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
5644514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
5654514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
5664514f5e3Sopenharmony_ci
5674514f5e3Sopenharmony_ci    // test  0/x => 0
5684514f5e3Sopenharmony_ci    {
5694514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
5704514f5e3Sopenharmony_ci        auto const_0 = b.Int64(0);
5714514f5e3Sopenharmony_ci        auto result = b.Int64Div(const_0, x);
5724514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(result), const_0);
5734514f5e3Sopenharmony_ci    }
5744514f5e3Sopenharmony_ci
5754514f5e3Sopenharmony_ci
5764514f5e3Sopenharmony_ci    // test  x/0 => 0
5774514f5e3Sopenharmony_ci    {
5784514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
5794514f5e3Sopenharmony_ci        auto const_0 = b.Int64(0);
5804514f5e3Sopenharmony_ci        auto result = b.Int64Div(x, const_0);
5814514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(result), const_0);
5824514f5e3Sopenharmony_ci    }
5834514f5e3Sopenharmony_ci
5844514f5e3Sopenharmony_ci    // test  x / 1 => x
5854514f5e3Sopenharmony_ci    {
5864514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
5874514f5e3Sopenharmony_ci        auto const_1 = b.Int64(1);
5884514f5e3Sopenharmony_ci        auto result = b.Int64Div(x, const_1);
5894514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(result), x);
5904514f5e3Sopenharmony_ci    }
5914514f5e3Sopenharmony_ci
5924514f5e3Sopenharmony_ci    // test  4 / 2 => 4
5934514f5e3Sopenharmony_ci    {
5944514f5e3Sopenharmony_ci        auto const_4 = b.Int64(4);
5954514f5e3Sopenharmony_ci        auto const_2 = b.Int64(2);
5964514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int64Div(const_4, const_2));
5974514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
5984514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, (int64_t)2), true);
5994514f5e3Sopenharmony_ci    }
6004514f5e3Sopenharmony_ci
6014514f5e3Sopenharmony_ci    // test x / -1 => 0 - X
6024514f5e3Sopenharmony_ci    {
6034514f5e3Sopenharmony_ci        auto x = b.Arguments(2);
6044514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int64Div(x, b.Int64(-1)));
6054514f5e3Sopenharmony_ci
6064514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
6074514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
6084514f5e3Sopenharmony_ci
6094514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().ResolvedValue(), 0);
6104514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), x);
6114514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::SUB);
6124514f5e3Sopenharmony_ci    }
6134514f5e3Sopenharmony_ci
6144514f5e3Sopenharmony_ci    // test x / -5 => 0 - x / 5
6154514f5e3Sopenharmony_ci    {
6164514f5e3Sopenharmony_ci        auto x = b.Arguments(2);
6174514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int64Div(x, b.Int64(-5)));
6184514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
6194514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
6204514f5e3Sopenharmony_ci
6214514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().ResolvedValue(), 0);
6224514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::SUB);
6234514f5e3Sopenharmony_ci        Int64BinopMatcher m_right(m.Right().Gate(), &circuit);
6244514f5e3Sopenharmony_ci
6254514f5e3Sopenharmony_ci        EXPECT_EQ(m_right.Left().Gate(), x);
6264514f5e3Sopenharmony_ci        EXPECT_EQ(m_right.Opcode(), OpCode::SDIV);
6274514f5e3Sopenharmony_ci        EXPECT_EQ(m_right.Right().ResolvedValue(), 5);
6284514f5e3Sopenharmony_ci    }
6294514f5e3Sopenharmony_ci}
6304514f5e3Sopenharmony_ci
6314514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int32DivTest)
6324514f5e3Sopenharmony_ci{
6334514f5e3Sopenharmony_ci    // construct a circuit
6344514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
6354514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
6364514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
6374514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
6384514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
6394514f5e3Sopenharmony_ci    Environment env(0, &b);
6404514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
6414514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
6424514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
6434514f5e3Sopenharmony_ci
6444514f5e3Sopenharmony_ci    // test  0/x => 0
6454514f5e3Sopenharmony_ci    {
6464514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
6474514f5e3Sopenharmony_ci        auto const_0 = b.Int32(0);
6484514f5e3Sopenharmony_ci        auto result = b.Int32Div(const_0, x);
6494514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(result), const_0);
6504514f5e3Sopenharmony_ci    }
6514514f5e3Sopenharmony_ci
6524514f5e3Sopenharmony_ci
6534514f5e3Sopenharmony_ci    // test  x/0 => 0
6544514f5e3Sopenharmony_ci    {
6554514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
6564514f5e3Sopenharmony_ci        auto const_0 = b.Int32(0);
6574514f5e3Sopenharmony_ci        auto result = b.Int32Div(x, const_0);
6584514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(result), const_0);
6594514f5e3Sopenharmony_ci    }
6604514f5e3Sopenharmony_ci
6614514f5e3Sopenharmony_ci    // test  x / 1 => x
6624514f5e3Sopenharmony_ci    {
6634514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
6644514f5e3Sopenharmony_ci        auto const_1 = b.Int32(1);
6654514f5e3Sopenharmony_ci        auto result = b.Int32Div(x, const_1);
6664514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(result), x);
6674514f5e3Sopenharmony_ci    }
6684514f5e3Sopenharmony_ci
6694514f5e3Sopenharmony_ci    // test  4 / 2 => 4
6704514f5e3Sopenharmony_ci    {
6714514f5e3Sopenharmony_ci        auto const_4 = b.Int32(4);
6724514f5e3Sopenharmony_ci        auto const_2 = b.Int32(2);
6734514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32Div(const_4, const_2));
6744514f5e3Sopenharmony_ci
6754514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
6764514f5e3Sopenharmony_ci        EXPECT_EQ(acc.IsConstantValue(result, (int32_t)2), true);
6774514f5e3Sopenharmony_ci    }
6784514f5e3Sopenharmony_ci
6794514f5e3Sopenharmony_ci    // test x / -1 => 0 - X
6804514f5e3Sopenharmony_ci    {
6814514f5e3Sopenharmony_ci        auto x = b.Arguments(2);
6824514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32Div(x, b.Int32(-1)));
6834514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
6844514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
6854514f5e3Sopenharmony_ci
6864514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().ResolvedValue(), 0);
6874514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), x);
6884514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::SUB);
6894514f5e3Sopenharmony_ci    }
6904514f5e3Sopenharmony_ci
6914514f5e3Sopenharmony_ci    // test x / -5 => 0 - x / 5
6924514f5e3Sopenharmony_ci    {
6934514f5e3Sopenharmony_ci        auto x = b.Arguments(2);
6944514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32Div(x, b.Int32(-5)));
6954514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
6964514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
6974514f5e3Sopenharmony_ci
6984514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().ResolvedValue(), 0);
6994514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::SUB);
7004514f5e3Sopenharmony_ci        Int32BinopMatcher m_right(m.Right().Gate(), &circuit);
7014514f5e3Sopenharmony_ci
7024514f5e3Sopenharmony_ci        EXPECT_EQ(m_right.Left().Gate(), x);
7034514f5e3Sopenharmony_ci        EXPECT_EQ(m_right.Opcode(), OpCode::SDIV);
7044514f5e3Sopenharmony_ci        EXPECT_EQ(m_right.Right().ResolvedValue(), 5);
7054514f5e3Sopenharmony_ci    }
7064514f5e3Sopenharmony_ci}
7074514f5e3Sopenharmony_ci
7084514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, DoubleBinOptest)
7094514f5e3Sopenharmony_ci{
7104514f5e3Sopenharmony_ci    // construct a circuit
7114514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
7124514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
7134514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
7144514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
7154514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
7164514f5e3Sopenharmony_ci    Environment env(0, &b);
7174514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
7184514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
7194514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
7204514f5e3Sopenharmony_ci
7214514f5e3Sopenharmony_ci    // test  x op NaN => NaN
7224514f5e3Sopenharmony_ci    {
7234514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
7244514f5e3Sopenharmony_ci        auto nan = b.NanValue();
7254514f5e3Sopenharmony_ci        auto zero = b.Double(0);
7264514f5e3Sopenharmony_ci        Float64Matcher nan_m(nan, &circuit);
7274514f5e3Sopenharmony_ci        EXPECT_EQ(nan_m.HasResolvedValue(), true);
7284514f5e3Sopenharmony_ci
7294514f5e3Sopenharmony_ci
7304514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.DoubleAdd(x, nan)), nan);
7314514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.DoubleSub(x, nan)), nan);
7324514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.DoubleMul(x, nan)), nan);
7334514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.DoubleDiv(x, nan)), nan);
7344514f5e3Sopenharmony_ci        // x % 0 => NaN
7354514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.DoubleMod(x, zero)), nan);
7364514f5e3Sopenharmony_ci    }
7374514f5e3Sopenharmony_ci    // test  NaN op op => NaN
7384514f5e3Sopenharmony_ci    {
7394514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
7404514f5e3Sopenharmony_ci        auto nan = b.NanValue();
7414514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.DoubleAdd(nan, x)), nan);
7424514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.DoubleSub(nan, x)), nan);
7434514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.DoubleDiv(nan, x)), nan);
7444514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.DoubleMod(nan, x)), nan);
7454514f5e3Sopenharmony_ci    }
7464514f5e3Sopenharmony_ci
7474514f5e3Sopenharmony_ci    // test 10.4 op 5.2 => ?
7484514f5e3Sopenharmony_ci    {
7494514f5e3Sopenharmony_ci        auto value1 = b.Double(10.1);
7504514f5e3Sopenharmony_ci        auto value2 = b.Double(5.2);
7514514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.DoubleAdd(value1, value2));
7524514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
7534514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetOpCode(result), OpCode::CONSTANT);
7544514f5e3Sopenharmony_ci
7554514f5e3Sopenharmony_ci        result = instcombie.VisitGate(b.DoubleAdd(value1, value2));
7564514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
7574514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetOpCode(result), OpCode::CONSTANT);
7584514f5e3Sopenharmony_ci
7594514f5e3Sopenharmony_ci        result = instcombie.VisitGate(b.DoubleSub(value1, value2));
7604514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
7614514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetOpCode(result), OpCode::CONSTANT);
7624514f5e3Sopenharmony_ci
7634514f5e3Sopenharmony_ci        result = instcombie.VisitGate(b.DoubleDiv(value1, value2));
7644514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
7654514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetOpCode(result), OpCode::CONSTANT);
7664514f5e3Sopenharmony_ci    }
7674514f5e3Sopenharmony_ci
7684514f5e3Sopenharmony_ci    // test x * -1.0 => -0.0 - x
7694514f5e3Sopenharmony_ci    {
7704514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
7714514f5e3Sopenharmony_ci        auto neg_one = b.Double(-1);
7724514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.DoubleMul(x, neg_one));
7734514f5e3Sopenharmony_ci
7744514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
7754514f5e3Sopenharmony_ci        Float64BinopMatcher m(result, &circuit);
7764514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::SUB);
7774514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().ResolvedValue(), -0.0);
7784514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), x);
7794514f5e3Sopenharmony_ci    }
7804514f5e3Sopenharmony_ci
7814514f5e3Sopenharmony_ci    // test x * -1.0 => -0.0 - x
7824514f5e3Sopenharmony_ci    {
7834514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
7844514f5e3Sopenharmony_ci        auto two = b.Double(2.0);
7854514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.DoubleMul(x, two));
7864514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
7874514f5e3Sopenharmony_ci        Float64BinopMatcher m(result, &circuit);
7884514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::ADD);
7894514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
7904514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), x);
7914514f5e3Sopenharmony_ci    }
7924514f5e3Sopenharmony_ci}
7934514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int32Modtest)
7944514f5e3Sopenharmony_ci{
7954514f5e3Sopenharmony_ci    // construct a circuit
7964514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
7974514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
7984514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
7994514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
8004514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
8014514f5e3Sopenharmony_ci    Environment env(0, &b);
8024514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
8034514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
8044514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
8054514f5e3Sopenharmony_ci    {
8064514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
8074514f5e3Sopenharmony_ci        auto zero = b.Int32(0);
8084514f5e3Sopenharmony_ci        auto one = b.Int32(1);
8094514f5e3Sopenharmony_ci        auto neg_one = b.Int32(-1);
8104514f5e3Sopenharmony_ci        auto four = b.Int32(4);
8114514f5e3Sopenharmony_ci        auto two = b.Int32(2);
8124514f5e3Sopenharmony_ci
8134514f5e3Sopenharmony_ci        // 0 % x  => 0
8144514f5e3Sopenharmony_ci        // x % 0  => 0
8154514f5e3Sopenharmony_ci        // x % 1  => 0
8164514f5e3Sopenharmony_ci        // x % -1 => 0
8174514f5e3Sopenharmony_ci        // x % x  => 0
8184514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Mod(x, zero)), zero);
8194514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Mod(zero, x)), zero);
8204514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Mod(x, one)), zero);
8214514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Mod(x, neg_one)), zero);
8224514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Mod(x, x)), zero);
8234514f5e3Sopenharmony_ci        // 2%4 =>2
8244514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Mod(two, four)), two);
8254514f5e3Sopenharmony_ci    }
8264514f5e3Sopenharmony_ci}
8274514f5e3Sopenharmony_ci
8284514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int32AddOverFlowtest)
8294514f5e3Sopenharmony_ci{
8304514f5e3Sopenharmony_ci    // construct a circuit
8314514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
8324514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
8334514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
8344514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
8354514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
8364514f5e3Sopenharmony_ci    Environment env(0, &b);
8374514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
8384514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
8394514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
8404514f5e3Sopenharmony_ci
8414514f5e3Sopenharmony_ci    // IsFoldable overflow
8424514f5e3Sopenharmony_ci    // 2147483647 + 1 =-2147483648
8434514f5e3Sopenharmony_ci    {
8444514f5e3Sopenharmony_ci        auto add_overflow = b.AddWithOverflow(b.Int32(2147483647), b.Int32(1));
8454514f5e3Sopenharmony_ci        auto add_result = b.ExtractValue(ecmascript::kungfu::MachineType::I32, add_overflow, b.Int32(0));
8464514f5e3Sopenharmony_ci        auto is_over = b.ExtractValue(ecmascript::kungfu::MachineType::I1, add_overflow, b.Int32(1));
8474514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetInt32FromConstant(instcombie.VisitGate(add_result)), -2147483648);
8484514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(is_over), b.Boolean(true));
8494514f5e3Sopenharmony_ci    }
8504514f5e3Sopenharmony_ci
8514514f5e3Sopenharmony_ci    // IsFoldable no overflow
8524514f5e3Sopenharmony_ci    {
8534514f5e3Sopenharmony_ci        auto add_overflow = b.AddWithOverflow(b.Int32(2147483646), b.Int32(1));
8544514f5e3Sopenharmony_ci        auto add_result = b.ExtractValue(ecmascript::kungfu::MachineType::I32, add_overflow, b.Int32(0));
8554514f5e3Sopenharmony_ci        auto is_over = b.ExtractValue(ecmascript::kungfu::MachineType::I1, add_overflow, b.Int32(1));
8564514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetInt32FromConstant(instcombie.VisitGate(add_result)), 2147483647);
8574514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(is_over), b.Boolean(false));
8584514f5e3Sopenharmony_ci    }
8594514f5e3Sopenharmony_ci
8604514f5e3Sopenharmony_ci
8614514f5e3Sopenharmony_ci    // x add 0 => 0
8624514f5e3Sopenharmony_ci    // IsFoldable no overflow
8634514f5e3Sopenharmony_ci    {
8644514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
8654514f5e3Sopenharmony_ci        auto add_overflow = b.AddWithOverflow(x, b.Int32(0));
8664514f5e3Sopenharmony_ci        auto add_result = b.ExtractValue(ecmascript::kungfu::MachineType::I32, add_overflow, b.Int32(0));
8674514f5e3Sopenharmony_ci        auto is_over = b.ExtractValue(ecmascript::kungfu::MachineType::I1, add_overflow, b.Int32(1));
8684514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(add_result), x);
8694514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(is_over), b.Boolean(false));
8704514f5e3Sopenharmony_ci    }
8714514f5e3Sopenharmony_ci}
8724514f5e3Sopenharmony_ci
8734514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int32SubOverFlowTest)
8744514f5e3Sopenharmony_ci{
8754514f5e3Sopenharmony_ci    // construct a circuit
8764514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
8774514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
8784514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
8794514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
8804514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
8814514f5e3Sopenharmony_ci    Environment env(0, &b);
8824514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
8834514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
8844514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
8854514f5e3Sopenharmony_ci
8864514f5e3Sopenharmony_ci    // IsFoldable overflow
8874514f5e3Sopenharmony_ci    // -2147483648 - 1 = 2147483647
8884514f5e3Sopenharmony_ci    {
8894514f5e3Sopenharmony_ci        auto sub_overflow = b.SubWithOverflow(b.Int32(-2147483648), b.Int32(1));
8904514f5e3Sopenharmony_ci        auto sub_result = b.ExtractValue(ecmascript::kungfu::MachineType::I32, sub_overflow, b.Int32(0));
8914514f5e3Sopenharmony_ci        auto is_over = b.ExtractValue(ecmascript::kungfu::MachineType::I1, sub_overflow, b.Int32(1));
8924514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetInt32FromConstant(instcombie.VisitGate(sub_result)), 2147483647);
8934514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(is_over), b.Boolean(true));
8944514f5e3Sopenharmony_ci    }
8954514f5e3Sopenharmony_ci
8964514f5e3Sopenharmony_ci    // IsFoldable no overflow
8974514f5e3Sopenharmony_ci    {
8984514f5e3Sopenharmony_ci        auto sub_overflow = b.SubWithOverflow(b.Int32(2147483647), b.Int32(1));
8994514f5e3Sopenharmony_ci        auto sub_result = b.ExtractValue(ecmascript::kungfu::MachineType::I32, sub_overflow, b.Int32(0));
9004514f5e3Sopenharmony_ci        auto is_over = b.ExtractValue(ecmascript::kungfu::MachineType::I1, sub_overflow, b.Int32(1));
9014514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetInt32FromConstant(instcombie.VisitGate(sub_result)), 2147483646);
9024514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(is_over), b.Boolean(false));
9034514f5e3Sopenharmony_ci    }
9044514f5e3Sopenharmony_ci
9054514f5e3Sopenharmony_ci    // x sub 0 => x
9064514f5e3Sopenharmony_ci    // IsFoldable no overflow
9074514f5e3Sopenharmony_ci    {
9084514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
9094514f5e3Sopenharmony_ci        auto sub_overflow = b.SubWithOverflow(x, b.Int32(0));
9104514f5e3Sopenharmony_ci        auto sub_result = b.ExtractValue(ecmascript::kungfu::MachineType::I32, sub_overflow, b.Int32(0));
9114514f5e3Sopenharmony_ci        auto is_over = b.ExtractValue(ecmascript::kungfu::MachineType::I1, sub_overflow, b.Int32(1));
9124514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(sub_result), x);
9134514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(is_over), b.Boolean(false));
9144514f5e3Sopenharmony_ci    }
9154514f5e3Sopenharmony_ci}
9164514f5e3Sopenharmony_ci
9174514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int32MulOverFlowTest)
9184514f5e3Sopenharmony_ci{
9194514f5e3Sopenharmony_ci    // construct a circuit
9204514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
9214514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
9224514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
9234514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
9244514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
9254514f5e3Sopenharmony_ci    Environment env(0, &b);
9264514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
9274514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
9284514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
9294514f5e3Sopenharmony_ci
9304514f5e3Sopenharmony_ci    // IsFoldable overflow
9314514f5e3Sopenharmony_ci    // 2147483647 * 2 = -2
9324514f5e3Sopenharmony_ci    {
9334514f5e3Sopenharmony_ci        auto mul_overflow = b.MulWithOverflow(b.Int32(2147483647), b.Int32(2));
9344514f5e3Sopenharmony_ci        auto mul_result = b.ExtractValue(ecmascript::kungfu::MachineType::I32, mul_overflow, b.Int32(0));
9354514f5e3Sopenharmony_ci        auto is_over = b.ExtractValue(ecmascript::kungfu::MachineType::I1, mul_overflow, b.Int32(1));
9364514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetInt32FromConstant(instcombie.VisitGate(mul_result)), -2);
9374514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(is_over), b.Boolean(true));
9384514f5e3Sopenharmony_ci    }
9394514f5e3Sopenharmony_ci
9404514f5e3Sopenharmony_ci    // IsFoldable no overflow
9414514f5e3Sopenharmony_ci    // 1000 * 2 = 2000
9424514f5e3Sopenharmony_ci    {
9434514f5e3Sopenharmony_ci        auto mul_overflow = b.MulWithOverflow(b.Int32(1000), b.Int32(2));
9444514f5e3Sopenharmony_ci        auto mul_result = b.ExtractValue(ecmascript::kungfu::MachineType::I32, mul_overflow, b.Int32(0));
9454514f5e3Sopenharmony_ci        auto is_over = b.ExtractValue(ecmascript::kungfu::MachineType::I1, mul_overflow, b.Int32(1));
9464514f5e3Sopenharmony_ci        EXPECT_EQ(acc.GetInt32FromConstant(instcombie.VisitGate(mul_result)), 2000);
9474514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(is_over), b.Boolean(false));
9484514f5e3Sopenharmony_ci    }
9494514f5e3Sopenharmony_ci
9504514f5e3Sopenharmony_ci    // x * 1 => x
9514514f5e3Sopenharmony_ci    // IsFoldable no overflow
9524514f5e3Sopenharmony_ci    {
9534514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
9544514f5e3Sopenharmony_ci        auto mul_overflow = b.MulWithOverflow(x, b.Int32(1));
9554514f5e3Sopenharmony_ci        auto mul_result = b.ExtractValue(ecmascript::kungfu::MachineType::I32, mul_overflow, b.Int32(0));
9564514f5e3Sopenharmony_ci        auto is_over = b.ExtractValue(ecmascript::kungfu::MachineType::I1, mul_overflow, b.Int32(1));
9574514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(mul_result), x);
9584514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(is_over), b.Boolean(false));
9594514f5e3Sopenharmony_ci    }
9604514f5e3Sopenharmony_ci
9614514f5e3Sopenharmony_ci    // x * 0 => 0
9624514f5e3Sopenharmony_ci    // IsFoldable no overflow
9634514f5e3Sopenharmony_ci    {
9644514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
9654514f5e3Sopenharmony_ci        auto mul_overflow = b.MulWithOverflow(x, b.Int32(0));
9664514f5e3Sopenharmony_ci        auto mul_result = b.ExtractValue(ecmascript::kungfu::MachineType::I32, mul_overflow, b.Int32(0));
9674514f5e3Sopenharmony_ci        auto is_over = b.ExtractValue(ecmascript::kungfu::MachineType::I1, mul_overflow, b.Int32(1));
9684514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(mul_result), b.Int32(0));
9694514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(is_over), b.Boolean(false));
9704514f5e3Sopenharmony_ci    }
9714514f5e3Sopenharmony_ci}
9724514f5e3Sopenharmony_ci
9734514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64_32AndTest)
9744514f5e3Sopenharmony_ci{
9754514f5e3Sopenharmony_ci    // construct a circuit
9764514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
9774514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
9784514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
9794514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
9804514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
9814514f5e3Sopenharmony_ci    Environment env(0, &b);
9824514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
9834514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
9844514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
9854514f5e3Sopenharmony_ci    {
9864514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
9874514f5e3Sopenharmony_ci        auto zero = b.Int64(0);
9884514f5e3Sopenharmony_ci        auto neg_one = b.Int64(-1);
9894514f5e3Sopenharmony_ci        auto Icmp = b.Equal(x, zero);
9904514f5e3Sopenharmony_ci        auto one = b.Int64(1);
9914514f5e3Sopenharmony_ci        auto two = b.Int64(2);
9924514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64And(x, zero)), zero);   // x & 0  => 0
9934514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64And(x, neg_one)), x);   // x & -1 => x
9944514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64And(Icmp, one)), Icmp); // CMP & 1 => CMP
9954514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64And(two, one)), zero);  // K & K  => K
9964514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64And(x, x)), x);         // x & x => x
9974514f5e3Sopenharmony_ci        // (x & 1) & 2 => x & 0
9984514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int64And(b.Int64And(x, one), two));
9994514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
10004514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
10014514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
10024514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::AND);
10034514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), zero);
10044514f5e3Sopenharmony_ci    }
10054514f5e3Sopenharmony_ci
10064514f5e3Sopenharmony_ci    {
10074514f5e3Sopenharmony_ci        auto x = b.Arguments(2);
10084514f5e3Sopenharmony_ci        auto zero = b.Int32(0);
10094514f5e3Sopenharmony_ci        auto neg_one = b.Int32(-1);
10104514f5e3Sopenharmony_ci        auto Icmp = b.Equal(x, zero);
10114514f5e3Sopenharmony_ci        auto one = b.Int32(1);
10124514f5e3Sopenharmony_ci        auto two = b.Int32(2);
10134514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32And(x, zero)), zero);   // x & 0  => 0
10144514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32And(x, neg_one)), x);   // x & -1 => x
10154514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32And(Icmp, one)), Icmp); // CMP & 1 => CMP
10164514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32And(two, one)), zero);  // K & K  => K
10174514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32And(x, x)), x);         // x & x => x
10184514f5e3Sopenharmony_ci        // (x & 1) & 2 => x & 0
10194514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32And(b.Int32And(x, one), two));
10204514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
10214514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
10224514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
10234514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::AND);
10244514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), zero);
10254514f5e3Sopenharmony_ci    }
10264514f5e3Sopenharmony_ci}
10274514f5e3Sopenharmony_ci
10284514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64_32OrTest)
10294514f5e3Sopenharmony_ci{
10304514f5e3Sopenharmony_ci    // construct a circuit
10314514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
10324514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
10334514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
10344514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
10354514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
10364514f5e3Sopenharmony_ci    Environment env(0, &b);
10374514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
10384514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
10394514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
10404514f5e3Sopenharmony_ci    {
10414514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
10424514f5e3Sopenharmony_ci        auto zero = b.Int64(0);
10434514f5e3Sopenharmony_ci        auto neg_one = b.Int64(-1);
10444514f5e3Sopenharmony_ci        auto one = b.Int64(1);
10454514f5e3Sopenharmony_ci        auto two = b.Int64(2);
10464514f5e3Sopenharmony_ci        auto three = b.Int64(3);
10474514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64Or(x, zero)), x);          // x | 0  => x
10484514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64Or(x, neg_one)), neg_one); // x | -1 => -1
10494514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64Or(two, one)), three);     // 2 | 1  => 3
10504514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64Or(x, x)), x);             // x | x => x
10514514f5e3Sopenharmony_ci        // (x & K1) | K2 => x | K2 if K2 has ones for every zero bit in K1.
10524514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(
10534514f5e3Sopenharmony_ci            b.Int64Or(b.Int64And(x, b.Int64(-6148914691236517205L)), b.Int64(6148914691236517205L)));
10544514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
10554514f5e3Sopenharmony_ci        Int64BinopMatcher m(result, &circuit);
10564514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
10574514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::OR);
10584514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), b.Int64(6148914691236517205L));
10594514f5e3Sopenharmony_ci    }
10604514f5e3Sopenharmony_ci
10614514f5e3Sopenharmony_ci    {
10624514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
10634514f5e3Sopenharmony_ci        auto zero = b.Int32(0);
10644514f5e3Sopenharmony_ci        auto neg_one = b.Int32(-1);
10654514f5e3Sopenharmony_ci        auto one = b.Int32(1);
10664514f5e3Sopenharmony_ci        auto two = b.Int32(2);
10674514f5e3Sopenharmony_ci        auto three = b.Int32(3);
10684514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Or(x, zero)), x);          // x | 0  => x
10694514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Or(x, neg_one)), neg_one); // x | -1 => -1
10704514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Or(two, one)), three);     // 2 | 1  => 3
10714514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Or(x, x)), x);             // x | x => x
10724514f5e3Sopenharmony_ci        // (x & K1) | K2 => x | K2 if K2 has ones for every zero bit in K1.
10734514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Int32Or(b.Int32And(x, b.Int32(-1431655765)), b.Int32(1431655765)));
10744514f5e3Sopenharmony_ci        EXPECT_NE(result, Circuit::NullGate());
10754514f5e3Sopenharmony_ci        Int32BinopMatcher m(result, &circuit);
10764514f5e3Sopenharmony_ci        EXPECT_EQ(m.Left().Gate(), x);
10774514f5e3Sopenharmony_ci        EXPECT_EQ(m.Opcode(), OpCode::OR);
10784514f5e3Sopenharmony_ci        EXPECT_EQ(m.Right().Gate(), b.Int32(1431655765));
10794514f5e3Sopenharmony_ci    }
10804514f5e3Sopenharmony_ci}
10814514f5e3Sopenharmony_ci
10824514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64_32XOrTest)
10834514f5e3Sopenharmony_ci{
10844514f5e3Sopenharmony_ci    // construct a circuit
10854514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
10864514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
10874514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
10884514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
10894514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
10904514f5e3Sopenharmony_ci    Environment env(0, &b);
10914514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
10924514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
10934514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
10944514f5e3Sopenharmony_ci    {
10954514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
10964514f5e3Sopenharmony_ci        auto zero = b.Int64(0);
10974514f5e3Sopenharmony_ci        auto neg_one = b.Int64(-1);
10984514f5e3Sopenharmony_ci        auto one = b.Int64(1);
10994514f5e3Sopenharmony_ci        auto two = b.Int64(2);
11004514f5e3Sopenharmony_ci        auto three = b.Int64(3);
11014514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64Xor(x, zero)), x);      // x ^ 0 => x
11024514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64Xor(two, one)), three); // 2 | 1  => 3
11034514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64Xor(x, x)), zero);      // x ^ x => 0
11044514f5e3Sopenharmony_ci        // (x ^ -1) ^ -1 => x
11054514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64Xor(b.Int64Xor(x, neg_one), neg_one)), x);
11064514f5e3Sopenharmony_ci    }
11074514f5e3Sopenharmony_ci
11084514f5e3Sopenharmony_ci    {
11094514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
11104514f5e3Sopenharmony_ci        auto zero = b.Int32(0);
11114514f5e3Sopenharmony_ci        auto neg_one = b.Int32(-1);
11124514f5e3Sopenharmony_ci        auto one = b.Int32(1);
11134514f5e3Sopenharmony_ci        auto two = b.Int32(2);
11144514f5e3Sopenharmony_ci        auto three = b.Int32(3);
11154514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Xor(x, zero)), x);      // x ^ 0 => x
11164514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Xor(two, one)), three); // 2 | 1  => 3
11174514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Xor(x, x)), zero);      // x ^ x => 0
11184514f5e3Sopenharmony_ci        // (x ^ -1) ^ -1 => x
11194514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32Xor(b.Int32Xor(x, neg_one), neg_one)), x);
11204514f5e3Sopenharmony_ci    }
11214514f5e3Sopenharmony_ci}
11224514f5e3Sopenharmony_ci
11234514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64_32LsrTest)
11244514f5e3Sopenharmony_ci{
11254514f5e3Sopenharmony_ci    // construct a circuit
11264514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
11274514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
11284514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
11294514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
11304514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
11314514f5e3Sopenharmony_ci    Environment env(0, &b);
11324514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
11334514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
11344514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
11354514f5e3Sopenharmony_ci
11364514f5e3Sopenharmony_ci    {
11374514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
11384514f5e3Sopenharmony_ci        auto zero = b.Int64(0);
11394514f5e3Sopenharmony_ci        auto two = b.Int64(2);
11404514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64LSR(x, zero)), x); // x >>> 0 => x
11414514f5e3Sopenharmony_ci        // (u)-8 >> 2  => 4611686018427387902u
11424514f5e3Sopenharmony_ci        // 8 >> 2  => 2
11434514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64LSR(b.Int64(-8), two)), b.Int64(4611686018427387902u));
11444514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64LSR(b.Int64(8), two)), b.Int64(2));
11454514f5e3Sopenharmony_ci    }
11464514f5e3Sopenharmony_ci
11474514f5e3Sopenharmony_ci    {
11484514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
11494514f5e3Sopenharmony_ci        auto zero = b.Int32(0);
11504514f5e3Sopenharmony_ci        auto two = b.Int32(2);
11514514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32LSR(x, zero)), x); // x >>> 0 => x
11524514f5e3Sopenharmony_ci        // (u)-8 >> 2  => 1073741822u
11534514f5e3Sopenharmony_ci        // 8 >> 2  => 2
11544514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32LSR(b.Int32(-8), two)), b.Int32(1073741822u));
11554514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32LSR(b.Int32(8), two)), b.Int32(2));
11564514f5e3Sopenharmony_ci        // (x & 1023) >>> 10  => 0
11574514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32LSR(b.Int32And(x, b.Int32(1023)), b.Int32(10))), zero);
11584514f5e3Sopenharmony_ci    }
11594514f5e3Sopenharmony_ci}
11604514f5e3Sopenharmony_ci
11614514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64_32AsrTest)
11624514f5e3Sopenharmony_ci{
11634514f5e3Sopenharmony_ci    // construct a circuit
11644514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
11654514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
11664514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
11674514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
11684514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
11694514f5e3Sopenharmony_ci    Environment env(0, &b);
11704514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
11714514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
11724514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
11734514f5e3Sopenharmony_ci    {
11744514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
11754514f5e3Sopenharmony_ci        auto zero = b.Int64(0);
11764514f5e3Sopenharmony_ci        auto two = b.Int64(2);
11774514f5e3Sopenharmony_ci        // x >> 0 => x
11784514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64ASR(x, zero)), x);
11794514f5e3Sopenharmony_ci        // -8 >> 2  => -2
11804514f5e3Sopenharmony_ci        // 8 >> 2  => 2
11814514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64ASR(b.Int64(-8), two)), b.Int64(-2));
11824514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64ASR(b.Int64(8), two)), b.Int64(2));
11834514f5e3Sopenharmony_ci    }
11844514f5e3Sopenharmony_ci    {
11854514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
11864514f5e3Sopenharmony_ci        auto zero = b.Int32(0);
11874514f5e3Sopenharmony_ci        auto two = b.Int32(2);
11884514f5e3Sopenharmony_ci        // x >> 0 => x
11894514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32ASR(x, zero)), x);
11904514f5e3Sopenharmony_ci        // -8 >> 2  => -2
11914514f5e3Sopenharmony_ci        // 8 >> 2  => 2
11924514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32ASR(b.Int32(-8), two)), b.Int32(-2));
11934514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32ASR(b.Int32(8), two)), b.Int32(2));
11944514f5e3Sopenharmony_ci    }
11954514f5e3Sopenharmony_ci}
11964514f5e3Sopenharmony_ci
11974514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64_32LslTest)
11984514f5e3Sopenharmony_ci{
11994514f5e3Sopenharmony_ci    // construct a circuit
12004514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
12014514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
12024514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
12034514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
12044514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
12054514f5e3Sopenharmony_ci    Environment env(0, &b);
12064514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
12074514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
12084514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
12094514f5e3Sopenharmony_ci    {
12104514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
12114514f5e3Sopenharmony_ci        auto zero = b.Int64(0);
12124514f5e3Sopenharmony_ci        auto two = b.Int64(2);
12134514f5e3Sopenharmony_ci        // x << 0 => x
12144514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64LSL(x, zero)), x);
12154514f5e3Sopenharmony_ci        // 1 << 2  => 4
12164514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int64LSL(b.Int64(1), two)), b.Int64(4));
12174514f5e3Sopenharmony_ci    }
12184514f5e3Sopenharmony_ci    {
12194514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
12204514f5e3Sopenharmony_ci        auto zero = b.Int32(0);
12214514f5e3Sopenharmony_ci        auto two = b.Int32(2);
12224514f5e3Sopenharmony_ci        // x << 0 => x
12234514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32LSL(x, zero)), x);
12244514f5e3Sopenharmony_ci        // 1 << 2  => 4
12254514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.Int32LSL(b.Int32(1), two)), b.Int32(4));
12264514f5e3Sopenharmony_ci    }
12274514f5e3Sopenharmony_ci}
12284514f5e3Sopenharmony_ci
12294514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, Int64EqualTest)
12304514f5e3Sopenharmony_ci{
12314514f5e3Sopenharmony_ci    // construct a circuit
12324514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
12334514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
12344514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
12354514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
12364514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
12374514f5e3Sopenharmony_ci    Environment env(0, &b);
12384514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
12394514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
12404514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
12414514f5e3Sopenharmony_ci
12424514f5e3Sopenharmony_ci    //  Match {EQ ((x or constant1) , constant2)} {((constant1 || constant2) != constant2)} => false
12434514f5e3Sopenharmony_ci    {
12444514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
12454514f5e3Sopenharmony_ci        auto constant1 = b.Int64(5);
12464514f5e3Sopenharmony_ci        auto constant2 = b.Int64(10);
12474514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Equal(b.Int64Or(x, constant1), constant2));
12484514f5e3Sopenharmony_ci        EXPECT_EQ(result, b.False());
12494514f5e3Sopenharmony_ci    }
12504514f5e3Sopenharmony_ci
12514514f5e3Sopenharmony_ci    // Taggedalue
12524514f5e3Sopenharmony_ci    {
12534514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
12544514f5e3Sopenharmony_ci        auto constant1 = b.Int64(5);
12554514f5e3Sopenharmony_ci        auto constant2 = b.Int64(10);
12564514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Equal(b.Int64ToTaggedPtr(b.Int64Or(x, constant1)), constant2));
12574514f5e3Sopenharmony_ci        EXPECT_EQ(result, b.False());
12584514f5e3Sopenharmony_ci    }
12594514f5e3Sopenharmony_ci    // Match {EQ((X or constant1) & constant2, 0)} { (constan2 !=0 && constant1 & constant2 !=0) }=> false
12604514f5e3Sopenharmony_ci    {
12614514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
12624514f5e3Sopenharmony_ci        auto constant1 = b.Int64(15);
12634514f5e3Sopenharmony_ci        auto constant2 = b.Int64(7);
12644514f5e3Sopenharmony_ci        auto zero = b.Int64(0);
12654514f5e3Sopenharmony_ci        auto result = instcombie.VisitGate(b.Equal(b.Int64And(b.Int64Or(x, constant1), constant2), zero));
12664514f5e3Sopenharmony_ci        EXPECT_EQ(result, b.False());
12674514f5e3Sopenharmony_ci    }
12684514f5e3Sopenharmony_ci}
12694514f5e3Sopenharmony_ci
12704514f5e3Sopenharmony_ciHWTEST_F_L0(InstructionCombineTests, ConvertTest)
12714514f5e3Sopenharmony_ci{
12724514f5e3Sopenharmony_ci    // construct a circuit
12734514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
12744514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
12754514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
12764514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
12774514f5e3Sopenharmony_ci    CircuitBuilder b(&circuit);
12784514f5e3Sopenharmony_ci    Environment env(0, &b);
12794514f5e3Sopenharmony_ci    b.SetEnvironment(&env);
12804514f5e3Sopenharmony_ci    CombinedPassVisitor visitor(&circuit, false, "InstCombie", &chunk);
12814514f5e3Sopenharmony_ci    InstructionCombine instcombie(&circuit, &visitor, &chunk);
12824514f5e3Sopenharmony_ci    {
12834514f5e3Sopenharmony_ci        auto x = b.Arguments(1);
12844514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.ChangeFloat64ToInt32(b.ChangeInt32ToFloat64(x))), x);
12854514f5e3Sopenharmony_ci    }
12864514f5e3Sopenharmony_ci
12874514f5e3Sopenharmony_ci    {
12884514f5e3Sopenharmony_ci        auto x = b.Arguments(2);
12894514f5e3Sopenharmony_ci        EXPECT_EQ(instcombie.VisitGate(b.ChangeInt32ToFloat64(b.ChangeFloat64ToInt32(x))), x);
12904514f5e3Sopenharmony_ci    }
12914514f5e3Sopenharmony_ci}
12924514f5e3Sopenharmony_ci} // namespace panda::test