This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][RTL-ifcvt] PR rtl-optimization/68841: Make sure one basic block doesn't clobber CC reg usage of the other
- From: Bernd Schmidt <bschmidt at redhat dot com>
- To: Kyrill Tkachov <kyrylo dot tkachov at foss dot arm dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 5 Jan 2016 17:34:22 +0100
- Subject: Re: [PATCH][RTL-ifcvt] PR rtl-optimization/68841: Make sure one basic block doesn't clobber CC reg usage of the other
- Authentication-results: sourceware.org; auth=none
- References: <56740520 dot 30908 at foss dot arm dot com> <56740734 dot 1080107 at redhat dot com> <5677C50F dot 2010302 at foss dot arm dot com> <568BC82D dot 20004 at redhat dot com> <568BD193 dot 9020802 at foss dot arm dot com>
On 01/05/2016 03:22 PM, Kyrill Tkachov wrote:
This works around the issue but we don't want to do perform the check
for pairs of
simple basic blocks because then we'll end up rejecting code that does
things like:
x = cond ? x + 1 : x - 1
i.e. source of the set in both blocks reads and writes the same register.
We can deal with this safely later on in the function since we rename
the destinations
of the two sets, so we don't want to reject this case here.
So we need to teach bbs_ok_for_cmove_arith that this is going to happen.
How about the approach below? Still seems to fix the issue, and it looks
like the CC set is present in the df info so everything should work as
intended. Right?
Bernd
Index: gcc/ifcvt.c
===================================================================
--- gcc/ifcvt.c (revision 232056)
+++ gcc/ifcvt.c (working copy)
@@ -1866,11 +1866,13 @@ insn_valid_noce_process_p (rtx_insn *ins
}
-/* 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. WILL_RENAME is true if we expect that BB_A consists
+ of a single single_set insn with a destination that the caller will
+ rename to a new pseudo. */
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, bool will_rename)
{
rtx_insn *a_insn;
bitmap bba_sets = BITMAP_ALLOC (®_obstack);
@@ -1887,13 +1889,15 @@ bbs_ok_for_cmove_arith (basic_block bb_a
if (!sset_a)
{
+ gcc_assert (!will_rename);
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 (!will_rename || DF_REF_REG (def) != SET_DEST (sset_a))
+ bitmap_set_bit (bba_sets, DF_REF_REGNO (def));
}
rtx_insn *b_insn;
@@ -2082,9 +2086,9 @@ noce_try_cmove_arith (struct noce_if_inf
}
}
- 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, a_simple)
+ || !bbs_ok_for_cmove_arith (else_bb, then_bb, b_simple)))
return FALSE;
start_sequence ();