The following patch fixes missing constant propagation in SSA propagators and FRE. Noticed this when working on sth else.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2016-07-19 Richard Biener <rguent...@suse.de> * gimple-fold.c (get_base_constructor): Add VIEW_CONVERT case, handle all tcc_constant bases and valueize SSA names. * tree-ssa-sccvn.c (fully_constant_vn_reference_p): Handle tcc_constant bases. * c-c++-common/vector-subscript-6.c: New testcase. * c-c++-common/vector-subscript-7.c: Likewise. Index: gcc/gimple-fold.c =================================================================== *** gcc/gimple-fold.c (revision 238426) --- gcc/gimple-fold.c (working copy) *************** get_base_constructor (tree base, HOST_WI *** 5508,5513 **** --- 5499,5507 ---- return NULL_TREE; base = TREE_OPERAND (base, 0); } + else if (valueize + && TREE_CODE (base) == SSA_NAME) + base = valueize (base); /* Get a CONSTRUCTOR. If BASE is a VAR_DECL, get its DECL_INITIAL. If BASE is a nested reference into another *************** get_base_constructor (tree base, HOST_WI *** 5529,5534 **** --- 5523,5532 ---- return init; } + case VIEW_CONVERT_EXPR: + return get_base_constructor (TREE_OPERAND (base, 0), + bit_offset, valueize); + case ARRAY_REF: case COMPONENT_REF: base = get_ref_base_and_extent (base, &bit_offset2, &size, &max_size, *************** get_base_constructor (tree base, HOST_WI *** 5538,5548 **** *bit_offset += bit_offset2; return get_base_constructor (base, bit_offset, valueize); - case STRING_CST: case CONSTRUCTOR: return base; default: return NULL_TREE; } } --- 5536,5548 ---- *bit_offset += bit_offset2; return get_base_constructor (base, bit_offset, valueize); case CONSTRUCTOR: return base; default: + if (CONSTANT_CLASS_P (base)) + return base; + return NULL_TREE; } } Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 238426) --- gcc/tree-ssa-sccvn.c (working copy) *************** fully_constant_vn_reference_p (vn_refere *** 1331,1336 **** --- 1337,1347 ---- unsigned i; for (i = 0; i < operands.length (); ++i) { + if (TREE_CODE_CLASS (operands[i].opcode) == tcc_constant) + { + ++i; + break; + } if (operands[i].off == -1) return NULL_TREE; off += operands[i].off; Index: gcc/testsuite/c-c++-common/vector-subscript-6.c =================================================================== *** gcc/testsuite/c-c++-common/vector-subscript-6.c (revision 0) --- gcc/testsuite/c-c++-common/vector-subscript-6.c (working copy) *************** *** 0 **** --- 1,14 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fno-tree-ccp -fdump-tree-fre1" } */ + + typedef int v4si __attribute__ ((vector_size (16))); + + int + main (int argc, char** argv) + { + int i = 2; + int j = ((v4si){0, 1, 2, 3})[i]; + return ((v4si){1, 2, 42, 0})[j]; + } + + /* { dg-final { scan-tree-dump "return 42;" "fre1" } } */ Index: gcc/testsuite/c-c++-common/vector-subscript-7.c =================================================================== *** gcc/testsuite/c-c++-common/vector-subscript-7.c (revision 0) --- gcc/testsuite/c-c++-common/vector-subscript-7.c (working copy) *************** *** 0 **** --- 1,14 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fdump-tree-ccp1" } */ + + typedef int v4si __attribute__ ((vector_size (16))); + + int + main (int argc, char** argv) + { + int i = 2; + int j = ((v4si){0, 1, 2, 3})[i]; + return ((v4si){1, 2, 42, 0})[j]; + } + + /* { dg-final { scan-tree-dump "return 42;" "ccp1" } } */