| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits> | 5 #include <limits> |
| 6 | 6 |
| 7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
| 8 #include "src/compiler/change-lowering.h" | 8 #include "src/compiler/change-lowering.h" |
| 9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
| 10 #include "src/compiler/generic-node-inl.h" | 10 #include "src/compiler/generic-node-inl.h" |
| (...skipping 1702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1713 } | 1713 } |
| 1714 | 1714 |
| 1715 | 1715 |
| 1716 TEST(NumberDivide_TruncatingToInt32) { | 1716 TEST(NumberDivide_TruncatingToInt32) { |
| 1717 int32_t constants[] = {-100, -10, 1, 4, 100, 1000}; | 1717 int32_t constants[] = {-100, -10, 1, 4, 100, 1000}; |
| 1718 | 1718 |
| 1719 for (size_t i = 0; i < arraysize(constants); i++) { | 1719 for (size_t i = 0; i < arraysize(constants); i++) { |
| 1720 TestingGraph t(Type::Signed32()); | 1720 TestingGraph t(Type::Signed32()); |
| 1721 Node* k = t.jsgraph.Constant(constants[i]); | 1721 Node* k = t.jsgraph.Constant(constants[i]); |
| 1722 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); | 1722 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); |
| 1723 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), div); | 1723 Node* use = t.Use(div, kMachInt32); |
| 1724 t.Return(trunc); | 1724 t.Return(use); |
| 1725 t.Lower(); | 1725 t.Lower(); |
| 1726 | 1726 |
| 1727 CHECK_EQ(IrOpcode::kInt32Div, div->opcode()); | 1727 CHECK_EQ(IrOpcode::kInt32Div, use->InputAt(0)->opcode()); |
| 1728 } | 1728 } |
| 1729 } | 1729 } |
| 1730 | 1730 |
| 1731 | 1731 |
| 1732 TEST(RunNumberDivide_TruncatingToInt32) { | 1732 TEST(RunNumberDivide_TruncatingToInt32) { |
| 1733 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048}; | 1733 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048}; |
| 1734 | 1734 |
| 1735 for (size_t i = 0; i < arraysize(constants); i++) { | 1735 for (size_t i = 0; i < arraysize(constants); i++) { |
| 1736 int32_t k = constants[i]; | 1736 int32_t k = constants[i]; |
| 1737 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1737 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1754 } | 1754 } |
| 1755 | 1755 |
| 1756 | 1756 |
| 1757 TEST(NumberDivide_TruncatingToUint32) { | 1757 TEST(NumberDivide_TruncatingToUint32) { |
| 1758 double constants[] = {1, 3, 100, 1000, 100998348}; | 1758 double constants[] = {1, 3, 100, 1000, 100998348}; |
| 1759 | 1759 |
| 1760 for (size_t i = 0; i < arraysize(constants); i++) { | 1760 for (size_t i = 0; i < arraysize(constants); i++) { |
| 1761 TestingGraph t(Type::Unsigned32()); | 1761 TestingGraph t(Type::Unsigned32()); |
| 1762 Node* k = t.jsgraph.Constant(constants[i]); | 1762 Node* k = t.jsgraph.Constant(constants[i]); |
| 1763 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); | 1763 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); |
| 1764 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), div); | 1764 Node* use = t.Use(div, kMachUint32); |
| 1765 t.Return(trunc); | 1765 t.Return(use); |
| 1766 t.Lower(); | 1766 t.Lower(); |
| 1767 | 1767 |
| 1768 CHECK_EQ(IrOpcode::kUint32Div, div->opcode()); | 1768 CHECK_EQ(IrOpcode::kUint32Div, use->InputAt(0)->opcode()); |
| 1769 } | 1769 } |
| 1770 } | 1770 } |
| 1771 | 1771 |
| 1772 | 1772 |
| 1773 TEST(RunNumberDivide_TruncatingToUint32) { | 1773 TEST(RunNumberDivide_TruncatingToUint32) { |
| 1774 uint32_t constants[] = {100, 10, 1, 1, 2, 4, 1000, 1024, 2048}; | 1774 uint32_t constants[] = {100, 10, 1, 1, 2, 4, 1000, 1024, 2048}; |
| 1775 | 1775 |
| 1776 for (size_t i = 0; i < arraysize(constants); i++) { | 1776 for (size_t i = 0; i < arraysize(constants); i++) { |
| 1777 uint32_t k = constants[i]; | 1777 uint32_t k = constants[i]; |
| 1778 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1778 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
| 1779 Node* num = t.NumberToUint32(t.Parameter(0)); | 1779 Node* num = t.NumberToUint32(t.Parameter(0)); |
| 1780 Node* div = t.NumberDivide(num, t.jsgraph.Constant(static_cast<double>(k))); | 1780 Node* div = t.NumberDivide(num, t.jsgraph.Constant(static_cast<double>(k))); |
| 1781 Node* trunc = t.NumberToUint32(div); | 1781 Node* trunc = t.NumberToUint32(div); |
| 1782 t.Return(trunc); | 1782 t.Return(trunc); |
| 1783 | 1783 |
| 1784 if (Pipeline::SupportedTarget()) { | 1784 if (Pipeline::SupportedTarget()) { |
| 1785 t.LowerAllNodesAndLowerChanges(); | 1785 t.LowerAllNodesAndLowerChanges(); |
| 1786 t.GenerateCode(); | 1786 t.GenerateCode(); |
| 1787 | 1787 |
| 1788 FOR_UINT32_INPUTS(i) { | 1788 FOR_UINT32_INPUTS(i) { |
| 1789 uint32_t x = *i / k; | 1789 uint32_t x = *i / k; |
| 1790 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); | 1790 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); |
| 1791 } | 1791 } |
| 1792 } | 1792 } |
| 1793 } | 1793 } |
| 1794 } | 1794 } |
| 1795 | 1795 |
| 1796 | 1796 |
| 1797 TEST(NumberDivide_BadConstants) { | 1797 TEST(NumberDivide_BadConstants) { |
| 1798 int32_t constants[] = {-1, 0}; | 1798 { |
| 1799 | |
| 1800 for (size_t i = 0; i < arraysize(constants); i++) { | |
| 1801 TestingGraph t(Type::Signed32()); | 1799 TestingGraph t(Type::Signed32()); |
| 1802 Node* k = t.jsgraph.Constant(constants[i]); | 1800 Node* k = t.jsgraph.Constant(-1); |
| 1803 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); | 1801 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); |
| 1804 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), div); | 1802 Node* use = t.Use(div, kMachInt32); |
| 1805 t.Return(trunc); | 1803 t.Return(use); |
| 1806 t.Lower(); | 1804 t.Lower(); |
| 1807 | 1805 |
| 1808 CHECK_EQ(IrOpcode::kFloat64Div, div->opcode()); | 1806 CHECK_EQ(IrOpcode::kInt32Sub, use->InputAt(0)->opcode()); |
| 1807 } |
| 1808 |
| 1809 { |
| 1810 TestingGraph t(Type::Signed32()); |
| 1811 Node* k = t.jsgraph.Constant(0); |
| 1812 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); |
| 1813 Node* use = t.Use(div, kMachInt32); |
| 1814 t.Return(use); |
| 1815 t.Lower(); |
| 1816 |
| 1817 CHECK_EQ(IrOpcode::kInt32Constant, use->InputAt(0)->opcode()); |
| 1818 CHECK_EQ(0, OpParameter<int32_t>(use->InputAt(0))); |
| 1809 } | 1819 } |
| 1810 | 1820 |
| 1811 { | 1821 { |
| 1812 TestingGraph t(Type::Unsigned32()); | 1822 TestingGraph t(Type::Unsigned32()); |
| 1813 Node* k = t.jsgraph.Constant(0); | 1823 Node* k = t.jsgraph.Constant(0); |
| 1814 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); | 1824 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); |
| 1815 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), div); | 1825 Node* use = t.Use(div, kMachUint32); |
| 1816 t.Return(trunc); | 1826 t.Return(use); |
| 1817 t.Lower(); | 1827 t.Lower(); |
| 1818 | 1828 |
| 1819 CHECK_EQ(IrOpcode::kFloat64Div, div->opcode()); | 1829 CHECK_EQ(IrOpcode::kInt32Constant, use->InputAt(0)->opcode()); |
| 1830 CHECK_EQ(0, OpParameter<int32_t>(use->InputAt(0))); |
| 1820 } | 1831 } |
| 1821 } | 1832 } |
| 1822 | 1833 |
| 1823 | 1834 |
| 1824 TEST(NumberModulus_TruncatingToInt32) { | 1835 TEST(NumberModulus_TruncatingToInt32) { |
| 1825 int32_t constants[] = {-100, -10, 1, 4, 100, 1000}; | 1836 int32_t constants[] = {-100, -10, 1, 4, 100, 1000}; |
| 1826 | 1837 |
| 1827 for (size_t i = 0; i < arraysize(constants); i++) { | 1838 for (size_t i = 0; i < arraysize(constants); i++) { |
| 1828 TestingGraph t(Type::Signed32()); | 1839 TestingGraph t(Type::Signed32()); |
| 1829 Node* k = t.jsgraph.Constant(constants[i]); | 1840 Node* k = t.jsgraph.Constant(constants[i]); |
| 1830 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k); | 1841 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k); |
| 1831 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mod); | 1842 Node* use = t.Use(mod, kMachInt32); |
| 1832 t.Return(trunc); | 1843 t.Return(use); |
| 1833 t.Lower(); | 1844 t.Lower(); |
| 1834 | 1845 |
| 1835 CHECK_EQ(IrOpcode::kInt32Mod, mod->opcode()); | 1846 CHECK_EQ(IrOpcode::kInt32Mod, use->InputAt(0)->opcode()); |
| 1836 } | 1847 } |
| 1837 } | 1848 } |
| 1838 | 1849 |
| 1839 | 1850 |
| 1840 TEST(RunNumberModulus_TruncatingToInt32) { | 1851 TEST(RunNumberModulus_TruncatingToInt32) { |
| 1841 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048}; | 1852 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048}; |
| 1842 | 1853 |
| 1843 for (size_t i = 0; i < arraysize(constants); i++) { | 1854 for (size_t i = 0; i < arraysize(constants); i++) { |
| 1844 int32_t k = constants[i]; | 1855 int32_t k = constants[i]; |
| 1845 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1856 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1863 | 1874 |
| 1864 | 1875 |
| 1865 TEST(NumberModulus_TruncatingToUint32) { | 1876 TEST(NumberModulus_TruncatingToUint32) { |
| 1866 double constants[] = {1, 3, 100, 1000, 100998348}; | 1877 double constants[] = {1, 3, 100, 1000, 100998348}; |
| 1867 | 1878 |
| 1868 for (size_t i = 0; i < arraysize(constants); i++) { | 1879 for (size_t i = 0; i < arraysize(constants); i++) { |
| 1869 TestingGraph t(Type::Unsigned32()); | 1880 TestingGraph t(Type::Unsigned32()); |
| 1870 Node* k = t.jsgraph.Constant(constants[i]); | 1881 Node* k = t.jsgraph.Constant(constants[i]); |
| 1871 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k); | 1882 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k); |
| 1872 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), mod); | 1883 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), mod); |
| 1873 t.Return(trunc); | 1884 Node* ret = t.Return(trunc); |
| 1874 t.Lower(); | 1885 t.Lower(); |
| 1875 | 1886 |
| 1876 CHECK_EQ(IrOpcode::kUint32Mod, mod->opcode()); | 1887 CHECK_EQ(IrOpcode::kUint32Mod, ret->InputAt(0)->opcode()); |
| 1877 } | 1888 } |
| 1878 } | 1889 } |
| 1879 | 1890 |
| 1880 | 1891 |
| 1881 TEST(RunNumberModulus_TruncatingToUint32) { | 1892 TEST(RunNumberModulus_TruncatingToUint32) { |
| 1882 uint32_t constants[] = {1, 2, 100, 1000, 1024, 2048}; | 1893 uint32_t constants[] = {1, 2, 100, 1000, 1024, 2048}; |
| 1883 | 1894 |
| 1884 for (size_t i = 0; i < arraysize(constants); i++) { | 1895 for (size_t i = 0; i < arraysize(constants); i++) { |
| 1885 uint32_t k = constants[i]; | 1896 uint32_t k = constants[i]; |
| 1886 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1897 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1909 for (size_t i = 0; i < arraysize(constants); i++) { | 1920 for (size_t i = 0; i < arraysize(constants); i++) { |
| 1910 TestingGraph t(Type::Signed32()); | 1921 TestingGraph t(Type::Signed32()); |
| 1911 Node* k = t.jsgraph.Constant(constants[i]); | 1922 Node* k = t.jsgraph.Constant(constants[i]); |
| 1912 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k); | 1923 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k); |
| 1913 t.Return(mod); | 1924 t.Return(mod); |
| 1914 t.Lower(); | 1925 t.Lower(); |
| 1915 | 1926 |
| 1916 CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode()); // Pesky -0 behavior. | 1927 CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode()); // Pesky -0 behavior. |
| 1917 } | 1928 } |
| 1918 } | 1929 } |
| 1919 | |
| 1920 | |
| 1921 TEST(NumberModulus_Uint32) { | |
| 1922 double constants[] = {1, 3, 100, 1000, 100998348}; | |
| 1923 | |
| 1924 for (size_t i = 0; i < arraysize(constants); i++) { | |
| 1925 TestingGraph t(Type::Unsigned32()); | |
| 1926 Node* k = t.jsgraph.Constant(constants[i]); | |
| 1927 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k); | |
| 1928 t.Return(mod); | |
| 1929 t.Lower(); | |
| 1930 | |
| 1931 CHECK_EQ(IrOpcode::kUint32Mod, mod->opcode()); | |
| 1932 } | |
| 1933 } | |
| 1934 | |
| 1935 | |
| 1936 TEST(NumberModulus_BadConstants) { | |
| 1937 int32_t constants[] = {-1, 0}; | |
| 1938 | |
| 1939 for (size_t i = 0; i < arraysize(constants); i++) { | |
| 1940 TestingGraph t(Type::Signed32()); | |
| 1941 Node* k = t.jsgraph.Constant(constants[i]); | |
| 1942 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k); | |
| 1943 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mod); | |
| 1944 t.Return(trunc); | |
| 1945 t.Lower(); | |
| 1946 | |
| 1947 CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode()); | |
| 1948 } | |
| 1949 | |
| 1950 { | |
| 1951 TestingGraph t(Type::Unsigned32()); | |
| 1952 Node* k = t.jsgraph.Constant(0); | |
| 1953 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k); | |
| 1954 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), mod); | |
| 1955 t.Return(trunc); | |
| 1956 t.Lower(); | |
| 1957 | |
| 1958 CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode()); | |
| 1959 } | |
| 1960 } | |
| OLD | NEW |