This PR shows that array_ref_element_size may apply spurious casts which in turn end up confusing VN/PRE.
Fixed as follows, bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2016-07-15 Richard Biener <rguent...@suse.de> PR tree-optimization/71893 * tree-ssa-pre.c (create_component_ref_by_pieces_1): Compensate for sizetype cast added by array_ref_element_size. * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Likewise. Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c (revision 238370) --- gcc/tree-ssa-pre.c (working copy) *************** create_component_ref_by_pieces_1 (basic_ *** 2576,2581 **** --- 2587,2595 ---- { genop3 = size_binop (EXACT_DIV_EXPR, genop3, size_int (TYPE_ALIGN_UNIT (elmt_type))); + /* We may have a useless conversion added by + array_ref_element_size via copy_reference_opts_from_ref. */ + STRIP_USELESS_TYPE_CONVERSION (genop3); genop3 = find_or_generate_expression (block, genop3, stmts); if (!genop3) return NULL_TREE; Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 238370) --- gcc/tree-ssa-sccvn.c (working copy) *************** copy_reference_ops_from_ref (tree ref, v *** 810,815 **** --- 810,818 ---- /* Always record lower bounds and element size. */ temp.op1 = array_ref_low_bound (ref); temp.op2 = array_ref_element_size (ref); + /* array_ref_element_size forces the result to sizetype + even if that is the same as bitsizetype. */ + STRIP_USELESS_TYPE_CONVERSION (temp.op2); if (TREE_CODE (temp.op0) == INTEGER_CST && TREE_CODE (temp.op1) == INTEGER_CST && TREE_CODE (temp.op2) == INTEGER_CST)