hardcmp: split before dispatch edge
If we harden a compare at the end of a block with an edge to the abnormal dispatch block, it won't have a single successor. Arrange to split the block at its final stmt so as to have a single succ. for gcc/ChangeLog PR middle-end/104975 * gimple-harden-conditionals.cc (pass_harden_compares::execute): Force split in case of multiple edges. for gcc/testsuite/ChangeLog PR middle-end/104975 * gcc.dg/pr104975.c: New.
This commit is contained in:
parent
11fb784ac5
commit
b8c4171ebd
|
@ -509,10 +509,16 @@ pass_harden_compares::execute (function *fun)
|
|||
gsi_insert_before (&gsi_split, asgnck, GSI_SAME_STMT);
|
||||
|
||||
/* We wish to insert a cond_expr after the compare, so arrange
|
||||
for it to be at the end of a block if it isn't. */
|
||||
if (!gsi_end_p (gsi_split))
|
||||
for it to be at the end of a block if it isn't, and for it
|
||||
to have a single successor in case there's more than
|
||||
one, as in PR104975. */
|
||||
if (!gsi_end_p (gsi_split)
|
||||
|| !single_succ_p (gsi_bb (gsi_split)))
|
||||
{
|
||||
gsi_prev (&gsi_split);
|
||||
if (!gsi_end_p (gsi_split))
|
||||
gsi_prev (&gsi_split);
|
||||
else
|
||||
gsi_split = gsi_last_bb (gsi_bb (gsi_split));
|
||||
basic_block obb = gsi_bb (gsi_split);
|
||||
basic_block nbb = split_block (obb, gsi_stmt (gsi_split))->dest;
|
||||
gsi_next (&gsi_split);
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fharden-compares -fno-inline -fno-ipa-pure-const" } */
|
||||
|
||||
__attribute__ ((pure, returns_twice)) int
|
||||
bar (int);
|
||||
|
||||
int
|
||||
quux (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
foo (short int x)
|
||||
{
|
||||
x = !x;
|
||||
bar (quux ());
|
||||
|
||||
return x;
|
||||
}
|
Loading…
Reference in New Issue