[Bug c/34668] [4.3 Regression] ICE in find_compatible_field with -combine
jakub at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Thu Jan 10 01:05:00 GMT 2008
------- Comment #8 from jakub at gcc dot gnu dot org 2008-01-10 00:00 -------
Patch which cures this:
--- gcc/tree-inline.c.jj 2008-01-04 00:53:03.000000000 +0100
+++ gcc/tree-inline.c 2008-01-10 00:48:07.000000000 +0100
@@ -700,7 +700,30 @@ copy_body_r (tree *tp, int *walk_subtree
if (! *tp)
{
if (TREE_CODE (new) == ADDR_EXPR)
- *tp = TREE_OPERAND (new, 0);
+ {
+ tree t = TREE_OPERAND (new, 0);
+ if (types_compatible_p (type, TREE_TYPE (t)))
+ *tp = t;
+ else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
+ && types_compatible_p (TREE_TYPE (TREE_TYPE
(t)),
+ type))
+ {
+ tree type_domain = TYPE_DOMAIN (TREE_TYPE (t));
+ tree min_val = size_zero_node;
+ if (type_domain && TYPE_MIN_VALUE (type_domain))
+ min_val = TYPE_MIN_VALUE (type_domain);
+ *tp = build4 (ARRAY_REF, type, t, min_val,
+ NULL_TREE, NULL_TREE);
+ }
+ else
+ {
+ t = build_fold_addr_expr (t);
+ t = fold_convert (TREE_TYPE (new), t);
+ *tp = build1 (INDIRECT_REF, type, t);
+ TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
+ id->regimplify = true;
+ }
+ }
else
{
*tp = build1 (INDIRECT_REF, type, new);
@@ -1210,13 +1233,15 @@ copy_phis_for_bb (basic_block bb, copy_b
tree arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
tree new_arg = arg;
+ id->regimplify = false;
walk_tree (&new_arg, copy_body_r, id, NULL);
gcc_assert (new_arg);
/* With return slot optimization we can end up with
non-gimple (foo *)&this->m, fix that here. */
- if (TREE_CODE (new_arg) != SSA_NAME
- && TREE_CODE (new_arg) != FUNCTION_DECL
- && !is_gimple_val (new_arg))
+ if ((TREE_CODE (new_arg) != SSA_NAME
+ && TREE_CODE (new_arg) != FUNCTION_DECL
+ && !is_gimple_val (new_arg))
+ || id->regimplify)
{
tree stmts = NULL_TREE;
new_arg = force_gimple_operand (new_arg, &stmts,
--- gcc/tree-ssa-operands.c.jj 2008-01-04 00:53:03.000000000 +0100
+++ gcc/tree-ssa-operands.c 2008-01-10 00:38:25.000000000 +0100
@@ -1663,7 +1663,7 @@ get_addr_dereference_operands (tree stmt
/* If we don't know what this pointer points to then we have
to make sure to not prune virtual operands based on offset
and size. */
- if (v_ann->symbol_mem_tag)
+ if (v_ann && v_ann->symbol_mem_tag)
{
add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags,
full_ref, 0, -1, false);
--- gcc/testsuite/gcc.dg/pr34668-1.c.jj 2008-01-10 00:55:59.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr34668-1.c 2008-01-10 00:59:02.000000000 +0100
@@ -0,0 +1,19 @@
+/* PR c/34668 */
+/* { dg-do compile } */
+/* { dg-options "--combine -O2" } */
+/* { dg-additional-sources "pr34668-2.c" } */
+
+struct optab { unsigned code; };
+extern struct optab optab_table[1];
+
+void
+init_optab (struct optab *op)
+{
+ op->code = 0xdead;
+}
+
+void
+set_conv_libfunc (void)
+{
+ init_optab (&optab_table[0]);
+}
--- gcc/testsuite/gcc.dg/pr34668-2.c.jj 2008-01-10 00:56:02.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr34668-2.c 2008-01-10 00:56:36.000000000 +0100
@@ -0,0 +1,5 @@
+/* PR c/34668 */
+/* { dg-do compile } */
+
+struct optab { unsigned code; };
+extern struct optab optab_table[1];
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34668
More information about the Gcc-bugs
mailing list