diff --git a/gcc/testsuite/gcc.dg/pr109410.c b/gcc/testsuite/gcc.dg/pr109410.c new file mode 100644 index 00000000000..a6401fc100c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr109410.c @@ -0,0 +1,19 @@ +/* PR tree-optimization/109410 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +__attribute__((returns_twice)) int baz (int, int); + +int +bar (int x) +{ + return x; +} + +int +foo (int x, int y) +{ + baz (x, y); + int a = bar (x); + return y || a == 42 || a > 42; +} diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 3a4d7e046c5..1a665928c13 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -1495,6 +1495,15 @@ build_and_add_sum (tree type, tree op1, tree op2, enum tree_code opcode) && (!op2def || gimple_nop_p (op2def))) { gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun))); + if (!gsi_end_p (gsi) + && is_gimple_call (gsi_stmt (gsi)) + && (gimple_call_flags (gsi_stmt (gsi)) & ECF_RETURNS_TWICE)) + { + /* Don't add statements before a returns_twice call at the start + of a function. */ + split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))); + gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun))); + } if (gsi_end_p (gsi)) { gimple_stmt_iterator gsi2