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 <[email protected]>
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;
+}