Richard, This patch fixes PR51990.
The patch adds handling of WITH_SIZE_EXPR in copy_reference_ops_from_ref and create_component_ref_by_pieces_1, preventing ICEs on the test-cases. Bootstrapped and reg-tested on x86_64. Ok for stage4 or stage1? Thanks, - Tom 2012-01-26 Tom de Vries <t...@codesourcery.com> PR tree-optimization/51990 * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Handle WITH_SIZE_EXPR. * tree-ssa-pre.c (create_component_ref_by_pieces_1): Same. * gcc.dg/pr51990.c: New test. * gcc.dg/pr51990-2.c: Same.
Index: gcc/tree-ssa-sccvn.c =================================================================== --- gcc/tree-ssa-sccvn.c (revision 183325) +++ gcc/tree-ssa-sccvn.c (working copy) @@ -624,6 +624,10 @@ copy_reference_ops_from_ref (tree ref, V switch (temp.opcode) { + case WITH_SIZE_EXPR: + temp.op0 = TREE_OPERAND (ref, 1); + temp.off = 0; + break; case MEM_REF: /* The base address gets its own vn_reference_op_s structure. */ temp.op0 = TREE_OPERAND (ref, 1); @@ -740,6 +744,7 @@ copy_reference_ops_from_ref (tree ref, V VEC_safe_push (vn_reference_op_s, heap, *result, &temp); if (REFERENCE_CLASS_P (ref) + || TREE_CODE (ref) == WITH_SIZE_EXPR || (TREE_CODE (ref) == ADDR_EXPR && !is_gimple_min_invariant (ref))) ref = TREE_OPERAND (ref, 0); Index: gcc/tree-ssa-pre.c =================================================================== --- gcc/tree-ssa-pre.c (revision 183325) +++ gcc/tree-ssa-pre.c (working copy) @@ -2780,6 +2780,7 @@ create_component_ref_by_pieces_1 (basic_ case REALPART_EXPR: case IMAGPART_EXPR: case VIEW_CONVERT_EXPR: + case WITH_SIZE_EXPR: { tree folded; tree genop0 = create_component_ref_by_pieces_1 (block, ref, @@ -2787,8 +2788,12 @@ create_component_ref_by_pieces_1 (basic_ stmts, domstmt); if (!genop0) return NULL_TREE; - folded = fold_build1 (currop->opcode, currop->type, - genop0); + + folded + = (currop->opcode == WITH_SIZE_EXPR + ? fold_build2 (currop->opcode, currop->type, genop0, currop->op0) + : fold_build1 (currop->opcode, currop->type, genop0)); + return folded; } break; Index: gcc/testsuite/gcc.dg/pr51990.c =================================================================== --- /dev/null (new file) +++ gcc/testsuite/gcc.dg/pr51990.c (revision 0) @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +zzz (char *s1, char *s2, int len, int *q) +{ + int z = 5; + unsigned int i, b; + struct s { char a[z]; }; + struct s x; + + extern int foo (int, ...) __attribute__((pure)); + + for (i = 0; i < len; i++) + s1[i] = s2[i]; + + b = z & 0x3; + + len += (b == 0 ? 0 : 1) + z; + + *q = len; + return foo (z, x, x); +} Index: gcc/testsuite/gcc.dg/pr51990-2.c =================================================================== --- /dev/null (new file) +++ gcc/testsuite/gcc.dg/pr51990-2.c (revision 0) @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int y; +extern int foo (int, ...) __attribute__((pure)); + +int +zzz (char *s1, char *s2, int len, int *q, int c) +{ + int z = 5; + unsigned int i, b; + struct s { char a[z]; }; + struct s x; + int y_tmp = 5; + + for (i = 0; i < len; i++) + s1[i] = s2[i]; + + b = z & 0x3; + + len += (b == 0 ? 0 : 1) + z; + + *q = len; + + if (c) + y_tmp = foo (z, x, x) + 4; + + z = foo (z, x, x) + 4; + y = y_tmp; + + return z; +}