Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: test/cctest/compiler/test-simplified-lowering.cc

Issue 620553008: Lower NumberMultiply, NumberDivide, and NumberModulus to Int32Mul, Int32[U]Div, and Int32[U]Mod whe… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add mjsunit and cctests. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 void LowerAllNodes() { 51 void LowerAllNodes() {
52 this->End(); 52 this->End();
53 lowering.LowerAllNodes(); 53 lowering.LowerAllNodes();
54 } 54 }
55 55
56 void LowerAllNodesAndLowerChanges() { 56 void LowerAllNodesAndLowerChanges() {
57 this->End(); 57 this->End();
58 typer.Run(jsgraph.graph(), MaybeHandle<Context>()); 58 typer.Run(jsgraph.graph(), MaybeHandle<Context>());
59 lowering.LowerAllNodes(); 59 lowering.LowerAllNodes();
60 60
61 {
62 FILE* dot_file = fopen("/tmp/test-lowered.dot", "w+");
Michael Starzinger 2014/10/08 09:01:28 Looks like a left-over, let's drop it again.
titzer 2014/10/08 09:12:29 Done.
63 OFStream dot_of(dot_file);
64 dot_of << AsDOT(*jsgraph.graph());
65 fclose(dot_file);
66 }
67
61 Zone* zone = this->zone(); 68 Zone* zone = this->zone();
62 CompilationInfo info(zone->isolate(), zone); 69 CompilationInfo info(zone->isolate(), zone);
63 Linkage linkage( 70 Linkage linkage(
64 &info, Linkage::GetSimplifiedCDescriptor(zone, this->machine_sig_)); 71 &info, Linkage::GetSimplifiedCDescriptor(zone, this->machine_sig_));
65 ChangeLowering lowering(&jsgraph, &linkage); 72 ChangeLowering lowering(&jsgraph, &linkage);
66 GraphReducer reducer(this->graph()); 73 GraphReducer reducer(this->graph());
67 reducer.AddReducer(&lowering); 74 reducer.AddReducer(&lowering);
68 reducer.ReduceGraph(); 75 reducer.ReduceGraph();
69 Verifier::Run(this->graph()); 76 Verifier::Run(this->graph());
70 } 77 }
(...skipping 1499 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 if (x <= Smi::kMinValue) continue; 1577 if (x <= Smi::kMinValue) continue;
1571 if (x >= Smi::kMaxValue) continue; 1578 if (x >= Smi::kMaxValue) continue;
1572 Handle<HeapNumber> expected = t.factory()->NewHeapNumber(x); 1579 Handle<HeapNumber> expected = t.factory()->NewHeapNumber(x);
1573 Object* result = t.Call(*num); 1580 Object* result = t.Call(*num);
1574 CHECK(expected->SameValue(result)); 1581 CHECK(expected->SameValue(result));
1575 } 1582 }
1576 } 1583 }
1577 } 1584 }
1578 1585
1579 1586
1587 TEST(NumberMultiply_TruncatingToInt32) {
1588 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000};
1589
1590 for (size_t i = 0; i < arraysize(constants); i++) {
1591 TestingGraph t(Type::Signed32());
1592 Node* k = t.jsgraph.Constant(constants[i]);
1593 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
1594 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul);
1595 t.Return(trunc);
1596 t.Lower();
1597
1598 CHECK_EQ(IrOpcode::kInt32Mul, mul->opcode());
1599 }
1600 }
1601
1602
1603 TEST(RunNumberMultiply_TruncatingToInt32) {
1604 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000, 3000999};
1605
1606 for (size_t i = 0; i < arraysize(constants); i++) {
1607 double k = static_cast<double>(constants[i]);
1608 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1609 Node* num = t.NumberToInt32(t.Parameter(0));
1610 Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k));
1611 Node* trunc = t.NumberToInt32(mul);
1612 t.Return(trunc);
1613
1614 if (Pipeline::SupportedTarget()) {
1615 t.LowerAllNodesAndLowerChanges();
1616 t.GenerateCode();
1617
1618 FOR_INT32_INPUTS(i) {
1619 Handle<HeapNumber> num = t.factory()->NewHeapNumber(*i);
1620 int32_t x = DoubleToInt32(static_cast<double>(*i) * k);
1621 Handle<HeapNumber> expected =
1622 t.factory()->NewHeapNumber(static_cast<double>(x));
1623 Object* result = t.Call(*num);
1624 CHECK(expected->SameValue(result));
1625 }
1626 }
1627 }
1628 }
1629
1630
1631 TEST(RunNumberMultiply_TruncatingToUint32) {
1632 uint32_t constants[] = {0, 1, 2, 3, 4, 100, 1000, 1024, 2048, 3000999};
1633
1634 for (size_t i = 0; i < arraysize(constants); i++) {
1635 double k = static_cast<double>(constants[i]);
1636 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1637 Node* num = t.NumberToUint32(t.Parameter(0));
1638 Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k));
1639 Node* trunc = t.NumberToUint32(mul);
1640 t.Return(trunc);
1641
1642 if (Pipeline::SupportedTarget()) {
1643 t.LowerAllNodesAndLowerChanges();
1644 t.GenerateCode();
1645
1646 FOR_UINT32_INPUTS(i) {
1647 Handle<HeapNumber> num =
1648 t.factory()->NewHeapNumber(static_cast<double>(*i));
1649 uint32_t x = DoubleToUint32(static_cast<double>(*i) * k);
1650 Handle<HeapNumber> expected =
1651 t.factory()->NewHeapNumber(static_cast<double>(x));
1652 Object* result = t.Call(*num);
1653 CHECK(expected->SameValue(result));
1654 }
1655 }
1656 }
1657 }
1658
1659
1580 TEST(RunNumberDivide_2_TruncatingToUint32) { 1660 TEST(RunNumberDivide_2_TruncatingToUint32) {
1581 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); 1661 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1582 Node* num = t.NumberToUint32(t.Parameter(0)); 1662 Node* num = t.NumberToUint32(t.Parameter(0));
1583 Node* div = t.NumberDivide(num, t.jsgraph.Constant(2)); 1663 Node* div = t.NumberDivide(num, t.jsgraph.Constant(2));
1584 Node* trunc = t.NumberToUint32(div); 1664 Node* trunc = t.NumberToUint32(div);
1585 t.Return(trunc); 1665 t.Return(trunc);
1586 1666
1587 if (Pipeline::SupportedTarget()) { 1667 if (Pipeline::SupportedTarget()) {
1588 t.LowerAllNodesAndLowerChanges(); 1668 t.LowerAllNodesAndLowerChanges();
1589 {
1590 FILE* dot_file = fopen("/tmp/test.dot", "w+");
1591 OFStream dot_of(dot_file);
1592 dot_of << AsDOT(*t.jsgraph.graph());
1593 fclose(dot_file);
1594 }
1595 t.GenerateCode(); 1669 t.GenerateCode();
1596 1670
1597 FOR_UINT32_INPUTS(i) { 1671 FOR_UINT32_INPUTS(i) {
1598 Handle<HeapNumber> num = 1672 Handle<HeapNumber> num =
1599 t.factory()->NewHeapNumber(static_cast<double>(*i)); 1673 t.factory()->NewHeapNumber(static_cast<double>(*i));
1600 uint32_t x = *i / 2; 1674 uint32_t x = DoubleToUint32(static_cast<double>(*i / 2.0));
1601 // TODO(titzer): make calls to NewHeapNumber work in cctests. 1675 // TODO(titzer): make calls to NewHeapNumber work in cctests.
1602 if (x >= static_cast<uint32_t>(Smi::kMaxValue)) continue; 1676 if (x >= static_cast<uint32_t>(Smi::kMaxValue)) continue;
1603 Handle<HeapNumber> expected = 1677 Handle<HeapNumber> expected =
1604 t.factory()->NewHeapNumber(static_cast<double>(x)); 1678 t.factory()->NewHeapNumber(static_cast<double>(x));
1605 Object* result = t.Call(*num); 1679 Object* result = t.Call(*num);
1606 CHECK(expected->SameValue(result)); 1680 CHECK(expected->SameValue(result));
1607 } 1681 }
1608 } 1682 }
1609 } 1683 }
1684
1685
1686 TEST(NumberMultiply_ConstantOutOfRange) {
1687 TestingGraph t(Type::Signed32());
1688 Node* k = t.jsgraph.Constant(1000000023);
1689 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
1690 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul);
1691 t.Return(trunc);
1692 t.Lower();
1693
1694 CHECK_EQ(IrOpcode::kFloat64Mul, mul->opcode());
1695 }
1696
1697
1698 TEST(NumberMultiply_NonTruncating) {
1699 TestingGraph t(Type::Signed32());
1700 Node* k = t.jsgraph.Constant(111);
1701 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
1702 t.Return(mul);
1703 t.Lower();
1704
1705 CHECK_EQ(IrOpcode::kFloat64Mul, mul->opcode());
1706 }
1707
1708
1709 TEST(NumberDivide_TruncatingToInt32) {
1710 int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
1711
1712 for (size_t i = 0; i < arraysize(constants); i++) {
1713 TestingGraph t(Type::Signed32());
1714 Node* k = t.jsgraph.Constant(constants[i]);
1715 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
1716 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), div);
1717 t.Return(trunc);
1718 t.Lower();
1719
1720 CHECK_EQ(IrOpcode::kInt32Div, div->opcode());
1721 }
1722 }
1723
1724
1725 TEST(RunNumberDivide_TruncatingToInt32) {
1726 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048};
1727
1728 for (size_t i = 0; i < arraysize(constants); i++) {
1729 int32_t k = constants[i];
1730 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1731 Node* num = t.NumberToInt32(t.Parameter(0));
1732 Node* div = t.NumberDivide(num, t.jsgraph.Constant(k));
1733 Node* trunc = t.NumberToInt32(div);
1734 t.Return(trunc);
1735
1736 if (Pipeline::SupportedTarget()) {
1737 t.LowerAllNodesAndLowerChanges();
1738 t.GenerateCode();
1739
1740 FOR_INT32_INPUTS(i) {
1741 if (*i == INT_MAX) continue; // exclude max int.
1742 Handle<HeapNumber> num = t.factory()->NewHeapNumber(*i);
1743 int32_t x = DoubleToInt32(static_cast<double>(*i) / k);
1744 Handle<HeapNumber> expected = t.factory()->NewHeapNumber(x);
1745 Object* result = t.Call(*num);
1746 CHECK(expected->SameValue(result));
1747 }
1748 }
1749 }
1750 }
1751
1752
1753 TEST(NumberDivide_TruncatingToUint32) {
1754 double constants[] = {1, 3, 100, 1000, 100998348};
1755
1756 for (size_t i = 0; i < arraysize(constants); i++) {
1757 TestingGraph t(Type::Unsigned32());
1758 Node* k = t.jsgraph.Constant(constants[i]);
1759 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
1760 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), div);
1761 t.Return(trunc);
1762 t.Lower();
1763
1764 CHECK_EQ(IrOpcode::kUint32Div, div->opcode());
1765 }
1766 }
1767
1768
1769 TEST(RunNumberDivide_TruncatingToUint32) {
1770 uint32_t constants[] = {100, 10, 1, 1, 2, 4, 1000, 1024, 2048};
1771
1772 for (size_t i = 0; i < arraysize(constants); i++) {
1773 uint32_t k = constants[i];
1774 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1775 Node* num = t.NumberToUint32(t.Parameter(0));
1776 Node* div = t.NumberDivide(num, t.jsgraph.Constant(static_cast<double>(k)));
1777 Node* trunc = t.NumberToUint32(div);
1778 t.Return(trunc);
1779
1780 if (Pipeline::SupportedTarget()) {
1781 t.LowerAllNodesAndLowerChanges();
1782 t.GenerateCode();
1783
1784 FOR_UINT32_INPUTS(i) {
1785 Handle<HeapNumber> num =
1786 t.factory()->NewHeapNumber(static_cast<double>(*i));
1787 Handle<HeapNumber> expected =
1788 t.factory()->NewHeapNumber(static_cast<double>(*i / k));
1789 Object* result = t.Call(*num);
1790 CHECK(expected->SameValue(result));
1791 }
1792 }
1793 }
1794 }
1795
1796
1797 TEST(NumberDivide_BadConstants) {
1798 int32_t constants[] = {-1, 0};
1799
1800 for (size_t i = 0; i < arraysize(constants); i++) {
1801 TestingGraph t(Type::Signed32());
1802 Node* k = t.jsgraph.Constant(constants[i]);
1803 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
1804 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), div);
1805 t.Return(trunc);
1806 t.Lower();
1807
1808 CHECK_EQ(IrOpcode::kFloat64Div, div->opcode());
1809 }
1810
1811 {
1812 TestingGraph t(Type::Unsigned32());
1813 Node* k = t.jsgraph.Constant(0);
1814 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
1815 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), div);
1816 t.Return(trunc);
1817 t.Lower();
1818
1819 CHECK_EQ(IrOpcode::kFloat64Div, div->opcode());
1820 }
1821 }
1822
1823
1824 TEST(NumberModulus_TruncatingToInt32) {
1825 int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
1826
1827 for (size_t i = 0; i < arraysize(constants); i++) {
1828 TestingGraph t(Type::Signed32());
1829 Node* k = t.jsgraph.Constant(constants[i]);
1830 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1831 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mod);
1832 t.Return(trunc);
1833 t.Lower();
1834
1835 CHECK_EQ(IrOpcode::kInt32Mod, mod->opcode());
1836 }
1837 }
1838
1839
1840 TEST(RunNumberModulus_TruncatingToInt32) {
1841 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048};
1842
1843 for (size_t i = 0; i < arraysize(constants); i++) {
1844 int32_t k = constants[i];
1845 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1846 Node* num = t.NumberToInt32(t.Parameter(0));
1847 Node* mod = t.NumberModulus(num, t.jsgraph.Constant(k));
1848 Node* trunc = t.NumberToInt32(mod);
1849 t.Return(trunc);
1850
1851 if (Pipeline::SupportedTarget()) {
1852 t.LowerAllNodesAndLowerChanges();
1853 t.GenerateCode();
1854
1855 FOR_INT32_INPUTS(i) {
1856 if (*i == INT_MAX) continue; // exclude max int.
1857 Handle<HeapNumber> num = t.factory()->NewHeapNumber(*i);
1858 int32_t x = DoubleToInt32(std::fmod(static_cast<double>(*i), k));
1859 Handle<HeapNumber> expected = t.factory()->NewHeapNumber(x);
1860 Object* result = t.Call(*num);
1861 CHECK(expected->SameValue(result));
1862 }
1863 }
1864 }
1865 }
1866
1867
1868 TEST(NumberModulus_TruncatingToUint32) {
1869 double constants[] = {1, 3, 100, 1000, 100998348};
1870
1871 for (size_t i = 0; i < arraysize(constants); i++) {
1872 TestingGraph t(Type::Unsigned32());
1873 Node* k = t.jsgraph.Constant(constants[i]);
1874 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1875 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), mod);
1876 t.Return(trunc);
1877 t.Lower();
1878
1879 CHECK_EQ(IrOpcode::kUint32Mod, mod->opcode());
1880 }
1881 }
1882
1883
1884 TEST(RunNumberModulus_TruncatingToUint32) {
1885 uint32_t constants[] = {1, 2, 100, 1000, 1024, 2048};
1886
1887 for (size_t i = 0; i < arraysize(constants); i++) {
1888 uint32_t k = constants[i];
1889 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1890 Node* num = t.NumberToUint32(t.Parameter(0));
1891 Node* mod =
1892 t.NumberModulus(num, t.jsgraph.Constant(static_cast<double>(k)));
1893 Node* trunc = t.NumberToUint32(mod);
1894 t.Return(trunc);
1895
1896 if (Pipeline::SupportedTarget()) {
1897 t.LowerAllNodesAndLowerChanges();
1898 t.GenerateCode();
1899
1900 FOR_UINT32_INPUTS(i) {
1901 Handle<HeapNumber> num =
1902 t.factory()->NewHeapNumber(static_cast<double>(*i));
1903 Handle<HeapNumber> expected =
1904 t.factory()->NewHeapNumber(static_cast<double>(*i % k));
1905 Object* result = t.Call(*num);
1906 CHECK(expected->SameValue(result));
1907 }
1908 }
1909 }
1910 }
1911
1912
1913 TEST(NumberModulus_Int32) {
1914 int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
1915
1916 for (size_t i = 0; i < arraysize(constants); i++) {
1917 TestingGraph t(Type::Signed32());
1918 Node* k = t.jsgraph.Constant(constants[i]);
1919 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1920 t.Return(mod);
1921 t.Lower();
1922
1923 CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode()); // Pesky -0 behavior.
1924 }
1925 }
1926
1927
1928 TEST(NumberModulus_Uint32) {
1929 double constants[] = {1, 3, 100, 1000, 100998348};
1930
1931 for (size_t i = 0; i < arraysize(constants); i++) {
1932 TestingGraph t(Type::Unsigned32());
1933 Node* k = t.jsgraph.Constant(constants[i]);
1934 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1935 t.Return(mod);
1936 t.Lower();
1937
1938 CHECK_EQ(IrOpcode::kUint32Mod, mod->opcode());
1939 }
1940 }
1941
1942
1943 TEST(NumberModulus_BadConstants) {
1944 int32_t constants[] = {-1, 0};
1945
1946 for (size_t i = 0; i < arraysize(constants); i++) {
1947 TestingGraph t(Type::Signed32());
1948 Node* k = t.jsgraph.Constant(constants[i]);
1949 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1950 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mod);
1951 t.Return(trunc);
1952 t.Lower();
1953
1954 CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode());
1955 }
1956
1957 {
1958 TestingGraph t(Type::Unsigned32());
1959 Node* k = t.jsgraph.Constant(0);
1960 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1961 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), mod);
1962 t.Return(trunc);
1963 t.Lower();
1964
1965 CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode());
1966 }
1967 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698