diff options
author | Andrew Pinski <andrew_pinski@playstation.sony.com> | 2008-03-31 18:22:05 +0000 |
---|---|---|
committer | Andrew Pinski <pinskia@gcc.gnu.org> | 2008-03-31 11:22:05 -0700 |
commit | a12bdb97c9bb28dc996017ec826612ac61dbe846 (patch) | |
tree | 05015805c094c492567941926cc55180a8afe552 /gcc/fold-const.c | |
parent | 2d4bba805eeeea81ee9e566e569528de83876e08 (diff) | |
download | gcc-a12bdb97c9bb28dc996017ec826612ac61dbe846.zip gcc-a12bdb97c9bb28dc996017ec826612ac61dbe846.tar.gz gcc-a12bdb97c9bb28dc996017ec826612ac61dbe846.tar.bz2 |
re PR tree-optimization/30186 (accessing an element via a "pointer" on a vector does not cause vec_extract to be used (non-zero index))
2008-03-31 Andrew Pinski <andrew_pinski@playstation.sony.com>
PR middle-end/30186
* fold-const.c (fold_indirect_ref_1): Support accessing non first
element of the vector via a pointer.
2008-03-31 Andrew Pinski <andrew_pinski@playstation.sony.com>
PR middle-end/30186
* gcc.dg/tree-ssa/vector-1.c: New testcase.
* gcc.c-torture/execute/vector-1.c: New testcase.
* gcc.c-torture/execute/vector-2.c: New testcase.
From-SVN: r133766
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 6e5d940..9fa3137 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -14963,6 +14963,34 @@ fold_indirect_ref_1 (tree type, tree op0) } } + /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */ + if (TREE_CODE (sub) == POINTER_PLUS_EXPR + && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST) + { + tree op00 = TREE_OPERAND (sub, 0); + tree op01 = TREE_OPERAND (sub, 1); + tree op00type; + + STRIP_NOPS (op00); + op00type = TREE_TYPE (op00); + if (TREE_CODE (op00) == ADDR_EXPR + && TREE_CODE (TREE_TYPE (op00type)) == VECTOR_TYPE + && type == TREE_TYPE (TREE_TYPE (op00type))) + { + HOST_WIDE_INT offset = tree_low_cst (op01, 0); + tree part_width = TYPE_SIZE (type); + unsigned HOST_WIDE_INT part_widthi = tree_low_cst (part_width, 0)/BITS_PER_UNIT; + unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; + tree index = bitsize_int (indexi); + + if (offset/part_widthi <= TYPE_VECTOR_SUBPARTS (TREE_TYPE (op00type))) + return fold_build3 (BIT_FIELD_REF, type, TREE_OPERAND (op00, 0), + part_width, index); + + } + } + + /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ if (TREE_CODE (sub) == POINTER_PLUS_EXPR && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST) |