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

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: git cl try 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
« no previous file with comments | « src/compiler/simplified-lowering.cc ('k') | test/mjsunit/asm/int32-div.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 CompilationInfo info(zone->isolate(), zone); 62 CompilationInfo info(zone->isolate(), zone);
63 Linkage linkage( 63 Linkage linkage(
64 &info, Linkage::GetSimplifiedCDescriptor(zone, this->machine_sig_)); 64 &info, Linkage::GetSimplifiedCDescriptor(zone, this->machine_sig_));
65 ChangeLowering lowering(&jsgraph, &linkage); 65 ChangeLowering lowering(&jsgraph, &linkage);
66 GraphReducer reducer(this->graph()); 66 GraphReducer reducer(this->graph());
67 reducer.AddReducer(&lowering); 67 reducer.AddReducer(&lowering);
68 reducer.ReduceGraph(); 68 reducer.ReduceGraph();
69 Verifier::Run(this->graph()); 69 Verifier::Run(this->graph());
70 } 70 }
71 71
72 void CheckNumberCall(double expected, double input) {
73 // TODO(titzer): make calls to NewNumber work in cctests.
74 if (expected <= Smi::kMinValue) return;
75 if (expected >= Smi::kMaxValue) return;
76 Handle<Object> num = factory()->NewNumber(input);
77 Object* result = this->Call(*num);
78 CHECK(factory()->NewNumber(expected)->SameValue(result));
79 }
80
72 Factory* factory() { return this->isolate()->factory(); } 81 Factory* factory() { return this->isolate()->factory(); }
73 Heap* heap() { return this->isolate()->heap(); } 82 Heap* heap() { return this->isolate()->heap(); }
74 }; 83 };
75 84
76 85
77 // TODO(titzer): factor these tests out to test-run-simplifiedops.cc. 86 // TODO(titzer): factor these tests out to test-run-simplifiedops.cc.
78 // TODO(titzer): test tagged representation for input to NumberToInt32. 87 // TODO(titzer): test tagged representation for input to NumberToInt32.
79 TEST(RunNumberToInt32_float64) { 88 TEST(RunNumberToInt32_float64) {
80 // TODO(titzer): explicit load/stores here are only because of representations 89 // TODO(titzer): explicit load/stores here are only because of representations
81 double input; 90 double input;
(...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 Node* num = t.NumberToInt32(t.Parameter(0)); 1566 Node* num = t.NumberToInt32(t.Parameter(0));
1558 Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1)); 1567 Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1));
1559 Node* trunc = t.NumberToInt32(div); 1568 Node* trunc = t.NumberToInt32(div);
1560 t.Return(trunc); 1569 t.Return(trunc);
1561 1570
1562 if (Pipeline::SupportedTarget()) { 1571 if (Pipeline::SupportedTarget()) {
1563 t.LowerAllNodesAndLowerChanges(); 1572 t.LowerAllNodesAndLowerChanges();
1564 t.GenerateCode(); 1573 t.GenerateCode();
1565 1574
1566 FOR_INT32_INPUTS(i) { 1575 FOR_INT32_INPUTS(i) {
1567 Handle<HeapNumber> num = t.factory()->NewHeapNumber(*i);
1568 int32_t x = 0 - *i; 1576 int32_t x = 0 - *i;
1569 // TODO(titzer): make calls to NewHeapNumber work in cctests. 1577 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
1570 if (x <= Smi::kMinValue) continue;
1571 if (x >= Smi::kMaxValue) continue;
1572 Handle<HeapNumber> expected = t.factory()->NewHeapNumber(x);
1573 Object* result = t.Call(*num);
1574 CHECK(expected->SameValue(result));
1575 } 1578 }
1576 } 1579 }
1577 } 1580 }
1581
1582
1583 TEST(NumberMultiply_TruncatingToInt32) {
1584 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000};
1585
1586 for (size_t i = 0; i < arraysize(constants); i++) {
1587 TestingGraph t(Type::Signed32());
1588 Node* k = t.jsgraph.Constant(constants[i]);
1589 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
1590 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul);
1591 t.Return(trunc);
1592 t.Lower();
1593
1594 CHECK_EQ(IrOpcode::kInt32Mul, mul->opcode());
1595 }
1596 }
1597
1598
1599 TEST(RunNumberMultiply_TruncatingToInt32) {
1600 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000, 3000999};
1601
1602 for (size_t i = 0; i < arraysize(constants); i++) {
1603 double k = static_cast<double>(constants[i]);
1604 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1605 Node* num = t.NumberToInt32(t.Parameter(0));
1606 Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k));
1607 Node* trunc = t.NumberToInt32(mul);
1608 t.Return(trunc);
1609
1610 if (Pipeline::SupportedTarget()) {
1611 t.LowerAllNodesAndLowerChanges();
1612 t.GenerateCode();
1613
1614 FOR_INT32_INPUTS(i) {
1615 int32_t x = DoubleToInt32(static_cast<double>(*i) * k);
1616 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
1617 }
1618 }
1619 }
1620 }
1621
1622
1623 TEST(RunNumberMultiply_TruncatingToUint32) {
1624 uint32_t constants[] = {0, 1, 2, 3, 4, 100, 1000, 1024, 2048, 3000999};
1625
1626 for (size_t i = 0; i < arraysize(constants); i++) {
1627 double k = static_cast<double>(constants[i]);
1628 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1629 Node* num = t.NumberToUint32(t.Parameter(0));
1630 Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k));
1631 Node* trunc = t.NumberToUint32(mul);
1632 t.Return(trunc);
1633
1634 if (Pipeline::SupportedTarget()) {
1635 t.LowerAllNodesAndLowerChanges();
1636 t.GenerateCode();
1637
1638 FOR_UINT32_INPUTS(i) {
1639 uint32_t x = DoubleToUint32(static_cast<double>(*i) * k);
1640 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
1641 }
1642 }
1643 }
1644 }
1578 1645
1579 1646
1580 TEST(RunNumberDivide_2_TruncatingToUint32) { 1647 TEST(RunNumberDivide_2_TruncatingToUint32) {
1581 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); 1648 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1582 Node* num = t.NumberToUint32(t.Parameter(0)); 1649 Node* num = t.NumberToUint32(t.Parameter(0));
1583 Node* div = t.NumberDivide(num, t.jsgraph.Constant(2)); 1650 Node* div = t.NumberDivide(num, t.jsgraph.Constant(2));
1584 Node* trunc = t.NumberToUint32(div); 1651 Node* trunc = t.NumberToUint32(div);
1585 t.Return(trunc); 1652 t.Return(trunc);
1586 1653
1587 if (Pipeline::SupportedTarget()) { 1654 if (Pipeline::SupportedTarget()) {
1588 t.LowerAllNodesAndLowerChanges(); 1655 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(); 1656 t.GenerateCode();
1596 1657
1597 FOR_UINT32_INPUTS(i) { 1658 FOR_UINT32_INPUTS(i) {
1598 Handle<HeapNumber> num = 1659 uint32_t x = DoubleToUint32(static_cast<double>(*i / 2.0));
1599 t.factory()->NewHeapNumber(static_cast<double>(*i)); 1660 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
1600 uint32_t x = *i / 2; 1661 }
1601 // TODO(titzer): make calls to NewHeapNumber work in cctests. 1662 }
1602 if (x >= static_cast<uint32_t>(Smi::kMaxValue)) continue; 1663 }
1603 Handle<HeapNumber> expected = 1664
1604 t.factory()->NewHeapNumber(static_cast<double>(x)); 1665
1605 Object* result = t.Call(*num); 1666 TEST(NumberMultiply_ConstantOutOfRange) {
1606 CHECK(expected->SameValue(result)); 1667 TestingGraph t(Type::Signed32());
1607 } 1668 Node* k = t.jsgraph.Constant(1000000023);
1608 } 1669 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
1609 } 1670 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul);
1671 t.Return(trunc);
1672 t.Lower();
1673
1674 CHECK_EQ(IrOpcode::kFloat64Mul, mul->opcode());
1675 }
1676
1677
1678 TEST(NumberMultiply_NonTruncating) {
1679 TestingGraph t(Type::Signed32());
1680 Node* k = t.jsgraph.Constant(111);
1681 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
1682 t.Return(mul);
1683 t.Lower();
1684
1685 CHECK_EQ(IrOpcode::kFloat64Mul, mul->opcode());
1686 }
1687
1688
1689 TEST(NumberDivide_TruncatingToInt32) {
1690 int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
1691
1692 for (size_t i = 0; i < arraysize(constants); i++) {
1693 TestingGraph t(Type::Signed32());
1694 Node* k = t.jsgraph.Constant(constants[i]);
1695 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
1696 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), div);
1697 t.Return(trunc);
1698 t.Lower();
1699
1700 CHECK_EQ(IrOpcode::kInt32Div, div->opcode());
1701 }
1702 }
1703
1704
1705 TEST(RunNumberDivide_TruncatingToInt32) {
1706 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048};
1707
1708 for (size_t i = 0; i < arraysize(constants); i++) {
1709 int32_t k = constants[i];
1710 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1711 Node* num = t.NumberToInt32(t.Parameter(0));
1712 Node* div = t.NumberDivide(num, t.jsgraph.Constant(k));
1713 Node* trunc = t.NumberToInt32(div);
1714 t.Return(trunc);
1715
1716 if (Pipeline::SupportedTarget()) {
1717 t.LowerAllNodesAndLowerChanges();
1718 t.GenerateCode();
1719
1720 FOR_INT32_INPUTS(i) {
1721 if (*i == INT_MAX) continue; // exclude max int.
1722 int32_t x = DoubleToInt32(static_cast<double>(*i) / k);
1723 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
1724 }
1725 }
1726 }
1727 }
1728
1729
1730 TEST(NumberDivide_TruncatingToUint32) {
1731 double constants[] = {1, 3, 100, 1000, 100998348};
1732
1733 for (size_t i = 0; i < arraysize(constants); i++) {
1734 TestingGraph t(Type::Unsigned32());
1735 Node* k = t.jsgraph.Constant(constants[i]);
1736 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
1737 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), div);
1738 t.Return(trunc);
1739 t.Lower();
1740
1741 CHECK_EQ(IrOpcode::kUint32Div, div->opcode());
1742 }
1743 }
1744
1745
1746 TEST(RunNumberDivide_TruncatingToUint32) {
1747 uint32_t constants[] = {100, 10, 1, 1, 2, 4, 1000, 1024, 2048};
1748
1749 for (size_t i = 0; i < arraysize(constants); i++) {
1750 uint32_t k = constants[i];
1751 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1752 Node* num = t.NumberToUint32(t.Parameter(0));
1753 Node* div = t.NumberDivide(num, t.jsgraph.Constant(static_cast<double>(k)));
1754 Node* trunc = t.NumberToUint32(div);
1755 t.Return(trunc);
1756
1757 if (Pipeline::SupportedTarget()) {
1758 t.LowerAllNodesAndLowerChanges();
1759 t.GenerateCode();
1760
1761 FOR_UINT32_INPUTS(i) {
1762 uint32_t x = *i / k;
1763 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
1764 }
1765 }
1766 }
1767 }
1768
1769
1770 TEST(NumberDivide_BadConstants) {
1771 int32_t constants[] = {-1, 0};
1772
1773 for (size_t i = 0; i < arraysize(constants); i++) {
1774 TestingGraph t(Type::Signed32());
1775 Node* k = t.jsgraph.Constant(constants[i]);
1776 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
1777 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), div);
1778 t.Return(trunc);
1779 t.Lower();
1780
1781 CHECK_EQ(IrOpcode::kFloat64Div, div->opcode());
1782 }
1783
1784 {
1785 TestingGraph t(Type::Unsigned32());
1786 Node* k = t.jsgraph.Constant(0);
1787 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
1788 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), div);
1789 t.Return(trunc);
1790 t.Lower();
1791
1792 CHECK_EQ(IrOpcode::kFloat64Div, div->opcode());
1793 }
1794 }
1795
1796
1797 TEST(NumberModulus_TruncatingToInt32) {
1798 int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
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* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1804 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mod);
1805 t.Return(trunc);
1806 t.Lower();
1807
1808 CHECK_EQ(IrOpcode::kInt32Mod, mod->opcode());
1809 }
1810 }
1811
1812
1813 TEST(RunNumberModulus_TruncatingToInt32) {
1814 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048};
1815
1816 for (size_t i = 0; i < arraysize(constants); i++) {
1817 int32_t k = constants[i];
1818 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1819 Node* num = t.NumberToInt32(t.Parameter(0));
1820 Node* mod = t.NumberModulus(num, t.jsgraph.Constant(k));
1821 Node* trunc = t.NumberToInt32(mod);
1822 t.Return(trunc);
1823
1824 if (Pipeline::SupportedTarget()) {
1825 t.LowerAllNodesAndLowerChanges();
1826 t.GenerateCode();
1827
1828 FOR_INT32_INPUTS(i) {
1829 if (*i == INT_MAX) continue; // exclude max int.
1830 int32_t x = DoubleToInt32(std::fmod(static_cast<double>(*i), k));
1831 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
1832 }
1833 }
1834 }
1835 }
1836
1837
1838 TEST(NumberModulus_TruncatingToUint32) {
1839 double constants[] = {1, 3, 100, 1000, 100998348};
1840
1841 for (size_t i = 0; i < arraysize(constants); i++) {
1842 TestingGraph t(Type::Unsigned32());
1843 Node* k = t.jsgraph.Constant(constants[i]);
1844 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1845 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), mod);
1846 t.Return(trunc);
1847 t.Lower();
1848
1849 CHECK_EQ(IrOpcode::kUint32Mod, mod->opcode());
1850 }
1851 }
1852
1853
1854 TEST(RunNumberModulus_TruncatingToUint32) {
1855 uint32_t constants[] = {1, 2, 100, 1000, 1024, 2048};
1856
1857 for (size_t i = 0; i < arraysize(constants); i++) {
1858 uint32_t k = constants[i];
1859 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1860 Node* num = t.NumberToUint32(t.Parameter(0));
1861 Node* mod =
1862 t.NumberModulus(num, t.jsgraph.Constant(static_cast<double>(k)));
1863 Node* trunc = t.NumberToUint32(mod);
1864 t.Return(trunc);
1865
1866 if (Pipeline::SupportedTarget()) {
1867 t.LowerAllNodesAndLowerChanges();
1868 t.GenerateCode();
1869
1870 FOR_UINT32_INPUTS(i) {
1871 uint32_t x = *i % k;
1872 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
1873 }
1874 }
1875 }
1876 }
1877
1878
1879 TEST(NumberModulus_Int32) {
1880 int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
1881
1882 for (size_t i = 0; i < arraysize(constants); i++) {
1883 TestingGraph t(Type::Signed32());
1884 Node* k = t.jsgraph.Constant(constants[i]);
1885 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1886 t.Return(mod);
1887 t.Lower();
1888
1889 CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode()); // Pesky -0 behavior.
1890 }
1891 }
1892
1893
1894 TEST(NumberModulus_Uint32) {
1895 double constants[] = {1, 3, 100, 1000, 100998348};
1896
1897 for (size_t i = 0; i < arraysize(constants); i++) {
1898 TestingGraph t(Type::Unsigned32());
1899 Node* k = t.jsgraph.Constant(constants[i]);
1900 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1901 t.Return(mod);
1902 t.Lower();
1903
1904 CHECK_EQ(IrOpcode::kUint32Mod, mod->opcode());
1905 }
1906 }
1907
1908
1909 TEST(NumberModulus_BadConstants) {
1910 int32_t constants[] = {-1, 0};
1911
1912 for (size_t i = 0; i < arraysize(constants); i++) {
1913 TestingGraph t(Type::Signed32());
1914 Node* k = t.jsgraph.Constant(constants[i]);
1915 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1916 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mod);
1917 t.Return(trunc);
1918 t.Lower();
1919
1920 CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode());
1921 }
1922
1923 {
1924 TestingGraph t(Type::Unsigned32());
1925 Node* k = t.jsgraph.Constant(0);
1926 Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
1927 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), mod);
1928 t.Return(trunc);
1929 t.Lower();
1930
1931 CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode());
1932 }
1933 }
OLDNEW
« no previous file with comments | « src/compiler/simplified-lowering.cc ('k') | test/mjsunit/asm/int32-div.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698