Commit 470512c3 by Kyrylo Tkachov Committed by Kyrylo Tkachov

[RTL-ifcvt] PR rtl-optimization/67465: Handle pairs of complex+simple blocks and…

[RTL-ifcvt] PR rtl-optimization/67465: Handle pairs of complex+simple blocks and empty blocks more gracefully

        PR rtl-optimization/67456
        PR rtl-optimization/67464
        PR rtl-optimization/67465
        * ifcvt.c (noce_try_cmove_arith): Bail out if cannot conditionally
        move in the mode of x.  Handle combination of complex and simple
        block pairs as well as the case when one is empty.

        * gcc.dg/pr67465.c: New test.

From-SVN: r228194
parent a681b758
2015-09-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR rtl-optimization/67456
PR rtl-optimization/67464
PR rtl-optimization/67465
* ifcvt.c (noce_try_cmove_arith): Bail out if cannot conditionally
move in the mode of x. Handle combination of complex and simple
block pairs as well as the case when one is empty.
2015-09-28 Trevor Saunders <tbsaunde+gcc@tbsaunde.org>
* doc/gimple.texi: Update references to gimple_statement_base.
......@@ -1961,6 +1961,11 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
insn_a = if_info->insn_a;
insn_b = if_info->insn_b;
machine_mode x_mode = GET_MODE (x);
if (!can_conditionally_move_p (x_mode))
return FALSE;
unsigned int then_cost;
unsigned int else_cost;
if (insn_a)
......@@ -1997,13 +2002,38 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
}
}
if (!a_simple && then_bb && !b_simple && else_bb
if (then_bb && else_bb && !a_simple && !b_simple
&& (!bbs_ok_for_cmove_arith (then_bb, else_bb)
|| !bbs_ok_for_cmove_arith (else_bb, then_bb)))
return FALSE;
start_sequence ();
/* If one of the blocks is empty then the corresponding B or A value
came from the test block. The non-empty complex block that we will
emit might clobber the register used by B or A, so move it to a pseudo
first. */
if (b_simple || !else_bb)
{
rtx tmp_b = gen_reg_rtx (x_mode);
/* Perform the simplest kind of set. The register allocator
should remove it if it's not actually needed. If this set is not
a valid insn (can happen on the is_mem path) then end_ifcvt_sequence
will cancel the whole sequence. Don't try any of the fallback paths
from noce_emit_move_insn since we want this to be the simplest kind
of move. */
emit_insn (gen_rtx_SET (tmp_b, b));
b = tmp_b;
}
if (a_simple || !then_bb)
{
rtx tmp_a = gen_reg_rtx (x_mode);
emit_insn (gen_rtx_SET (tmp_a, a));
a = tmp_a;
}
orig_a = a;
orig_b = b;
......
2015-09-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR rtl-optimization/67456
PR rtl-optimization/67464
PR rtl-optimization/67465
* gcc.dg/pr67465.c: New test.
2015-09-28 Tom de Vries <tom@codesourcery.com>
* gcc.dg/vect/pr62171.c: New test.
......
/* { dg-do run } */
/* { dg-options "-O3 -std=gnu99" } */
int a, b, c, d, e, h;
int
fn1 (int p1)
{
{
int g[2];
for (int i = 0; i < 1; i++)
g[i] = 0;
if (g[0] < c)
{
a = (unsigned) (1 ^ p1) % 2;
return 0;
}
}
return 0;
}
void
fn2 ()
{
for (h = 0; h < 1; h++)
{
for (int j = 0; j < 2; j++)
{
for (b = 1; b; b = 0)
a = 1;
for (; b < 1; b++)
;
if (e)
continue;
a = 2;
}
fn1 (h);
short k = -16;
d = k > a;
}
}
int
main ()
{
fn2 ();
if (a != 2)
__builtin_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