[RTL-ifcvt] PR rtl-optimization/68841: Make sure one basic block doesn't clobber CC reg usage of the other
PR rtl-optimization/68841 * ifcvt.c (struct noce_if_info): Add orig_x field. (bbs_ok_for_cmove_arith): Add to_rename parameter. Don't record conflicts on to_rename if it's present. Allow memory destinations in sets. (noce_try_cmove_arith): Call bbs_ok_for_cmove_arith even on simple blocks, passing orig_x to the checks. (noce_process_if_block): Set if_info->orig_x appropriately. * gcc.dg/pr68841.c: New test. * gcc.c-torture/execute/pr68841.c: New test. From-SVN: r232223
This commit is contained in:
parent
1c5211b13c
commit
5baf45323b
|
@ -1,3 +1,15 @@
|
|||
2016-01-11 Bernd Schmidt <bschmidt@redhat.com>
|
||||
Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||
|
||||
PR rtl-optimization/68841
|
||||
* ifcvt.c (struct noce_if_info): Add orig_x field.
|
||||
(bbs_ok_for_cmove_arith): Add to_rename parameter.
|
||||
Don't record conflicts on to_rename if it's present.
|
||||
Allow memory destinations in sets.
|
||||
(noce_try_cmove_arith): Call bbs_ok_for_cmove_arith even on simple
|
||||
blocks, passing orig_x to the checks.
|
||||
(noce_process_if_block): Set if_info->orig_x appropriately.
|
||||
|
||||
2016-01-11 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
PR tree-optimization/69069
|
||||
|
|
33
gcc/ifcvt.c
33
gcc/ifcvt.c
|
@ -793,6 +793,9 @@ struct noce_if_info
|
|||
/* The SET_DEST of INSN_A. */
|
||||
rtx x;
|
||||
|
||||
/* The original set destination that the THEN and ELSE basic blocks finally
|
||||
write their result to. */
|
||||
rtx orig_x;
|
||||
/* True if this if block is not canonical. In the canonical form of
|
||||
if blocks, the THEN_BB is the block reached via the fallthru edge
|
||||
from TEST_BB. For the noce transformations, we allow the symmetric
|
||||
|
@ -1867,11 +1870,13 @@ insn_valid_noce_process_p (rtx_insn *insn, rtx cc)
|
|||
}
|
||||
|
||||
|
||||
/* Return true iff the registers that the insns in BB_A set do not
|
||||
get used in BB_B. */
|
||||
/* Return true iff the registers that the insns in BB_A set do not get
|
||||
used in BB_B. If TO_RENAME is non-NULL then it is a location that will be
|
||||
renamed later by the caller and so conflicts on it should be ignored
|
||||
in this function. */
|
||||
|
||||
static bool
|
||||
bbs_ok_for_cmove_arith (basic_block bb_a, basic_block bb_b)
|
||||
bbs_ok_for_cmove_arith (basic_block bb_a, basic_block bb_b, rtx to_rename)
|
||||
{
|
||||
rtx_insn *a_insn;
|
||||
bitmap bba_sets = BITMAP_ALLOC (®_obstack);
|
||||
|
@ -1891,10 +1896,10 @@ bbs_ok_for_cmove_arith (basic_block bb_a, basic_block bb_b)
|
|||
BITMAP_FREE (bba_sets);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Record all registers that BB_A sets. */
|
||||
FOR_EACH_INSN_DEF (def, a_insn)
|
||||
bitmap_set_bit (bba_sets, DF_REF_REGNO (def));
|
||||
if (!(to_rename && DF_REF_REG (def) == to_rename))
|
||||
bitmap_set_bit (bba_sets, DF_REF_REGNO (def));
|
||||
}
|
||||
|
||||
rtx_insn *b_insn;
|
||||
|
@ -1913,8 +1918,15 @@ bbs_ok_for_cmove_arith (basic_block bb_a, basic_block bb_b)
|
|||
}
|
||||
|
||||
/* Make sure this is a REG and not some instance
|
||||
of ZERO_EXTRACT or SUBREG or other dangerous stuff. */
|
||||
if (!REG_P (SET_DEST (sset_b)))
|
||||
of ZERO_EXTRACT or SUBREG or other dangerous stuff.
|
||||
If we have a memory destination then we have a pair of simple
|
||||
basic blocks performing an operation of the form [addr] = c ? a : b.
|
||||
bb_valid_for_noce_process_p will have ensured that these are
|
||||
the only stores present. In that case [addr] should be the location
|
||||
to be renamed. Assert that the callers set this up properly. */
|
||||
if (MEM_P (SET_DEST (sset_b)))
|
||||
gcc_assert (rtx_equal_p (SET_DEST (sset_b), to_rename));
|
||||
else if (!REG_P (SET_DEST (sset_b)))
|
||||
{
|
||||
BITMAP_FREE (bba_sets);
|
||||
return false;
|
||||
|
@ -2083,9 +2095,9 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
|
|||
}
|
||||
}
|
||||
|
||||
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)))
|
||||
if (then_bb && else_bb
|
||||
&& (!bbs_ok_for_cmove_arith (then_bb, else_bb, if_info->orig_x)
|
||||
|| !bbs_ok_for_cmove_arith (else_bb, then_bb, if_info->orig_x)))
|
||||
return FALSE;
|
||||
|
||||
start_sequence ();
|
||||
|
@ -3403,6 +3415,7 @@ noce_process_if_block (struct noce_if_info *if_info)
|
|||
/* Only operate on register destinations, and even then avoid extending
|
||||
the lifetime of hard registers on small register class machines. */
|
||||
orig_x = x;
|
||||
if_info->orig_x = orig_x;
|
||||
if (!REG_P (x)
|
||||
|| (HARD_REGISTER_P (x)
|
||||
&& targetm.small_register_classes_for_mode_p (GET_MODE (x))))
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2016-01-11 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||
|
||||
PR rtl-optimization/68841
|
||||
* gcc.dg/pr68841.c: New test.
|
||||
* gcc.c-torture/execute/pr68841.c: New test.
|
||||
|
||||
2016-01-11 Yuri Rumyantsev <ysrumyan@gmail.com>
|
||||
|
||||
PR rtl-optimization/68920
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
static inline int
|
||||
foo (int *x, int y)
|
||||
{
|
||||
int z = *x;
|
||||
while (y > z)
|
||||
z *= 2;
|
||||
return z;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < 17; i++)
|
||||
{
|
||||
int j;
|
||||
int k;
|
||||
j = foo (&i, 7);
|
||||
if (i >= 7)
|
||||
k = i;
|
||||
else if (i >= 4)
|
||||
k = 8 + (i - 4) * 2;
|
||||
else if (i == 3)
|
||||
k = 12;
|
||||
else
|
||||
k = 8;
|
||||
if (j != k)
|
||||
__builtin_abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-Og -fif-conversion -flive-range-shrinkage -fpeel-loops -frerun-cse-after-loop" } */
|
||||
|
||||
static inline int
|
||||
foo (int *x, int y)
|
||||
{
|
||||
int z = *x;
|
||||
while (y > z)
|
||||
z *= 2;
|
||||
return z;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < 17; i++)
|
||||
{
|
||||
int j;
|
||||
int k;
|
||||
j = foo (&i, 7);
|
||||
if (i >= 7)
|
||||
k = i;
|
||||
else if (i >= 4)
|
||||
k = 8 + (i - 4) * 2;
|
||||
else if (i == 3)
|
||||
k = 12;
|
||||
else
|
||||
k = 8;
|
||||
if (j != k)
|
||||
__builtin_abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue