Commit 3b5fda81 by Jakub Jelinek Committed by Jakub Jelinek

re PR middle-end/44071 (ICE with asm goto and __builtin_unreachable())

	PR middle-end/44071
	* cfglayout.c (fixup_reorder_chain): Allow asm goto to have
	no fallthru edge.
	* cfgcleanup.c (try_optimize_cfg): When in cfglayout mode
	optimizing away empty bb with no successors, move over its
	footer chain to fallthru predecessor.
	* cfgrtl.c (patch_jump_insn): Update also REG_LABEL_OPERAND.
	(rtl_split_edge): For asm goto call patch_jump_insn even if
	splitting fallthru edge.

	* c-c++-common/asmgoto-4.c: New test.
	* gcc.target/i386/pr44071.c: New test.

From-SVN: r159288
parent 3895ec53
2010-05-11 Jakub Jelinek <jakub@redhat.com>
PR middle-end/44071
* cfglayout.c (fixup_reorder_chain): Allow asm goto to have
no fallthru edge.
* cfgcleanup.c (try_optimize_cfg): When in cfglayout mode
optimizing away empty bb with no successors, move over its
footer chain to fallthru predecessor.
* cfgrtl.c (patch_jump_insn): Update also REG_LABEL_OPERAND.
(rtl_split_edge): For asm goto call patch_jump_insn even if
splitting fallthru edge.
PR c++/44059
* config/elfos.h (ASM_DECLARE_OBJECT_NAME): Use qnu_unique_object
even for DECL_ONE_ONLY DECL_ARTIFICIAL !TREE_READONLY decls.
......
......@@ -1999,6 +1999,25 @@ try_optimize_cfg (int mode)
&& single_succ_edge (ENTRY_BLOCK_PTR)->dest != b))
{
c = b->prev_bb;
if ((mode & CLEANUP_CFGLAYOUT)
&& EDGE_COUNT (b->preds) > 0
&& b->il.rtl->footer
&& BARRIER_P (b->il.rtl->footer))
{
edge e;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, b->preds)
if (e->flags & EDGE_FALLTHRU)
{
if (e->src->il.rtl->footer == NULL)
{
e->src->il.rtl->footer = b->il.rtl->footer;
b->il.rtl->footer = NULL;
}
break;
}
}
delete_basic_block (b);
if (!(mode & CLEANUP_CFGLAYOUT))
changed = true;
......
/* Basic block reordering routines for the GNU compiler.
Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GCC.
......@@ -861,8 +861,11 @@ fixup_reorder_chain (void)
}
else if (extract_asm_operands (PATTERN (bb_end_insn)) != NULL)
{
/* If the old fallthru is still next, nothing to do. */
if (bb->aux == e_fall->dest
/* If the old fallthru is still next or if
asm goto doesn't have a fallthru (e.g. when followed by
__builtin_unreachable ()), nothing to do. */
if (! e_fall
|| bb->aux == e_fall->dest
|| e_fall->dest == EXIT_BLOCK_PTR)
continue;
......
......@@ -994,6 +994,9 @@ patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb)
&& !find_reg_note (insn, REG_LABEL_TARGET, new_label))
add_reg_note (insn, REG_LABEL_TARGET, new_label);
}
while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label))
!= NULL_RTX)
XEXP (note, 0) = new_label;
}
else
{
......@@ -1407,7 +1410,22 @@ rtl_split_edge (edge edge_in)
gcc_assert (redirected);
}
else
redirect_edge_succ (edge_in, bb);
{
if (edge_in->src != ENTRY_BLOCK_PTR)
{
/* For asm goto even splitting of fallthru edge might
need insn patching, as other labels might point to the
old label. */
rtx last = BB_END (edge_in->src);
if (last
&& JUMP_P (last)
&& edge_in->dest != EXIT_BLOCK_PTR
&& extract_asm_operands (PATTERN (last)) != NULL_RTX
&& patch_jump_insn (last, before, bb))
df_set_bb_dirty (edge_in->src);
}
redirect_edge_succ (edge_in, bb);
}
return bb;
}
......
2010-05-11 Jakub Jelinek <jakub@redhat.com>
PR middle-end/44071
* c-c++-common/asmgoto-4.c: New test.
* gcc.target/i386/pr44071.c: New test.
PR c++/44062
* c-c++-common/Wunused-var-7.c: New test.
* g++.dg/warn/Wunused-var-9.C: New test.
......
/* PR middle-end/44071 */
/* { dg-do compile } */
/* { dg-options "-O2" } */
static inline int
f1 (void)
{
asm goto ("" : : : : l1, l2);
__builtin_unreachable ();
l1:
return 1;
l2:
return 0;
}
int
b1 (int x)
{
if (f1 () || x == 6)
x = 1;
else
x = 2;
return x;
}
static inline int
f2 (void)
{
asm goto ("" : : : : l1, l2);
l1:
return 1;
l2:
return 0;
}
int
b2 (int x)
{
if (f2 () || x == 6)
x = 1;
else
x = 2;
return x;
}
/* PR middle-end/44071 */
/* { dg-do run } */
/* { dg-options "-O2" } */
static inline int
f1 (void)
{
asm goto ("jmp %l[l1]" : : : : l1, l2);
__builtin_unreachable ();
l1:
return 1;
l2:
return 0;
}
__attribute__((noinline)) int
b1 (int x)
{
if (f1 () || x == 6)
x = 1;
else
x = 2;
return x;
}
static inline int
f2 (void)
{
asm goto ("jmp %l[l2]" : : : : l1, l2);
__builtin_unreachable ();
l1:
return 1;
l2:
return 0;
}
__attribute__((noinline)) int
b2 (int x)
{
if (f2 () || x == 6)
x = 1;
else
x = 2;
return x;
}
static inline int
f3 (void)
{
asm goto ("jmp %l[l1]" : : : : l1, l2);
l1:
return 1;
l2:
return 0;
}
__attribute__((noinline)) int
b3 (int x)
{
if (f3 () || x == 6)
x = 1;
else
x = 2;
return x;
}
static inline int
f4 (void)
{
asm goto ("jmp %l[l2]" : : : : l1, l2);
l1:
return 1;
l2:
return 0;
}
__attribute__((noinline)) int
b4 (int x)
{
if (f4 () || x == 6)
x = 1;
else
x = 2;
return x;
}
extern void abort (void);
int
main (void)
{
int x;
asm ("" : "=r" (x) : "0" (0));
if (b1 (x) != 1 || b1 (x + 6) != 1)
abort ();
if (b2 (x) != 2 || b2 (x + 6) != 1)
abort ();
if (b3 (x) != 1 || b3 (x + 6) != 1)
abort ();
if (b4 (x) != 2 || b4 (x + 6) != 1)
abort ();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment