Mercurial > hg > truffle
comparison src/share/vm/opto/superword.cpp @ 6893:b2c669fd8114
8001183: incorrect results of char vectors right shift operaiton
Summary: do vector right shift operation for small int types only after loads
Reviewed-by: jrose, dlong
author | kvn |
---|---|
date | Tue, 23 Oct 2012 13:06:37 -0700 |
parents | f6badecb7ea7 |
children | 410afdc6a07c |
comparison
equal
deleted
inserted
replaced
6892:fd1d564dd460 | 6893:b2c669fd8114 |
---|---|
1774 for (int i = 0; i < _block.length(); i++) { | 1774 for (int i = 0; i < _block.length(); i++) { |
1775 Node* n = _block.at(i); | 1775 Node* n = _block.at(i); |
1776 set_velt_type(n, container_type(n)); | 1776 set_velt_type(n, container_type(n)); |
1777 } | 1777 } |
1778 | 1778 |
1779 // Propagate narrowed type backwards through operations | 1779 // Propagate integer narrowed type backwards through operations |
1780 // that don't depend on higher order bits | 1780 // that don't depend on higher order bits |
1781 for (int i = _block.length() - 1; i >= 0; i--) { | 1781 for (int i = _block.length() - 1; i >= 0; i--) { |
1782 Node* n = _block.at(i); | 1782 Node* n = _block.at(i); |
1783 // Only integer types need be examined | 1783 // Only integer types need be examined |
1784 const Type* vt = velt_type(n); | 1784 const Type* vtn = velt_type(n); |
1785 if (vt->basic_type() == T_INT) { | 1785 if (vtn->basic_type() == T_INT) { |
1786 uint start, end; | 1786 uint start, end; |
1787 VectorNode::vector_operands(n, &start, &end); | 1787 VectorNode::vector_operands(n, &start, &end); |
1788 const Type* vt = velt_type(n); | |
1789 | 1788 |
1790 for (uint j = start; j < end; j++) { | 1789 for (uint j = start; j < end; j++) { |
1791 Node* in = n->in(j); | 1790 Node* in = n->in(j); |
1792 // Don't propagate through a memory | 1791 // Don't propagate through a memory |
1793 if (!in->is_Mem() && in_bb(in) && velt_type(in)->basic_type() == T_INT && | 1792 if (!in->is_Mem() && in_bb(in) && velt_type(in)->basic_type() == T_INT && |
1799 same_type = false; | 1798 same_type = false; |
1800 break; | 1799 break; |
1801 } | 1800 } |
1802 } | 1801 } |
1803 if (same_type) { | 1802 if (same_type) { |
1803 // For right shifts of small integer types (bool, byte, char, short) | |
1804 // we need precise information about sign-ness. Only Load nodes have | |
1805 // this information because Store nodes are the same for signed and | |
1806 // unsigned values. And any arithmetic operation after a load may | |
1807 // expand a value to signed Int so such right shifts can't be used | |
1808 // because vector elements do not have upper bits of Int. | |
1809 const Type* vt = vtn; | |
1810 if (VectorNode::is_shift(in)) { | |
1811 Node* load = in->in(1); | |
1812 if (load->is_Load() && (velt_type(load)->basic_type() == T_INT)) { | |
1813 vt = velt_type(load); | |
1814 } else if (in->Opcode() != Op_LShiftI) { | |
1815 // Widen type to Int to avoid creation of right shift vector | |
1816 // (align + data_size(s1) check in stmts_can_pack() will fail). | |
1817 // Note, left shifts work regardless type. | |
1818 vt = TypeInt::INT; | |
1819 } | |
1820 } | |
1804 set_velt_type(in, vt); | 1821 set_velt_type(in, vt); |
1805 } | 1822 } |
1806 } | 1823 } |
1807 } | 1824 } |
1808 } | 1825 } |
1839 | 1856 |
1840 //---------------------------container_type--------------------------- | 1857 //---------------------------container_type--------------------------- |
1841 // Smallest type containing range of values | 1858 // Smallest type containing range of values |
1842 const Type* SuperWord::container_type(Node* n) { | 1859 const Type* SuperWord::container_type(Node* n) { |
1843 if (n->is_Mem()) { | 1860 if (n->is_Mem()) { |
1844 return Type::get_const_basic_type(n->as_Mem()->memory_type()); | 1861 BasicType bt = n->as_Mem()->memory_type(); |
1862 if (n->is_Store() && (bt == T_CHAR)) { | |
1863 // Use T_SHORT type instead of T_CHAR for stored values because any | |
1864 // preceding arithmetic operation extends values to signed Int. | |
1865 bt = T_SHORT; | |
1866 } | |
1867 if (n->Opcode() == Op_LoadUB) { | |
1868 // Adjust type for unsigned byte loads, it is important for right shifts. | |
1869 // T_BOOLEAN is used because there is no basic type representing type | |
1870 // TypeInt::UBYTE. Use of T_BOOLEAN for vectors is fine because only | |
1871 // size (one byte) and sign is important. | |
1872 bt = T_BOOLEAN; | |
1873 } | |
1874 return Type::get_const_basic_type(bt); | |
1845 } | 1875 } |
1846 const Type* t = _igvn.type(n); | 1876 const Type* t = _igvn.type(n); |
1847 if (t->basic_type() == T_INT) { | 1877 if (t->basic_type() == T_INT) { |
1848 // A narrow type of arithmetic operations will be determined by | 1878 // A narrow type of arithmetic operations will be determined by |
1849 // propagating the type of memory operations. | 1879 // propagating the type of memory operations. |