Flow crash for conditional branches against a constant
Daniel Jacobowitz
drow@false.org
Sun Jun 13 12:02:00 GMT 2004
On Fri, Jun 11, 2004 at 01:05:34PM -0400, Daniel Jacobowitz wrote:
> Rather than adding it I'm testing removal of the invariant. I don't
> see anything besides the boolean arithmetic functions which relies on
> the exact form of the condition... yet.
I still don't see any problems. The attached patch causes no
differences in the generated libstdc++ on arm-elf (both -marm and
-mthumb), and no testsuite changes for C, C++, or libstdc++-v3 (again
-marm and -mthumb).
[Well, no real testsuite changes. Four libstdc++ tests failed, but
pass when rerunning them by hand; the error is symptomatic of a missing
input file. Two g++ tests pass, where they used to fail to link
referencing a symbol in libstdc++, but libstdc++ is exactly the same.
I think I botched something running the tests.]
I imagine there's some case where this permits slightly better code on
Thumb. It also allows me to use cond_exec patterns which compare
against non-zero constants.
OK?
--
Daniel Jacobowitz
2004-06-12 Daniel Jacobowitz <dan@debian.org>
* flow.c (init_propagate_block_info): Reallow more complex
conditions.
(ior_reg_cond, not_reg_cond, and_reg_cond, elim_reg_cond): Handle
more complex conditions.
Index: flow.c
===================================================================
RCS file: /big/fsf/rsync/gcc-cvs/gcc/gcc/flow.c,v
retrieving revision 1.588
diff -u -p -r1.588 flow.c
--- a/flow.c 15 May 2004 09:39:29 -0000 1.588
+++ b/flow.c 11 Jun 2004 19:35:32 -0000
@@ -1865,51 +1865,43 @@ init_propagate_block_info (basic_block b
rtx set_src = SET_SRC (pc_set (BB_END (bb)));
rtx cond_true = XEXP (set_src, 0);
rtx reg = XEXP (cond_true, 0);
+ rtx cond_false
+ = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond_true)),
+ GET_MODE (cond_true), XEXP (cond_true, 0),
+ XEXP (cond_true, 1));
if (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg);
- /* We can only track conditional lifetimes if the condition is
- in the form of a comparison of a register against zero.
- If the condition is more complex than that, then it is safe
- not to record any information. */
- if (GET_CODE (reg) == REG
- && XEXP (cond_true, 1) == const0_rtx)
+ if (GET_CODE (XEXP (set_src, 1)) == PC)
{
- rtx cond_false
- = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond_true)),
- GET_MODE (cond_true), XEXP (cond_true, 0),
- XEXP (cond_true, 1));
- if (GET_CODE (XEXP (set_src, 1)) == PC)
- {
- rtx t = cond_false;
- cond_false = cond_true;
- cond_true = t;
- }
+ rtx t = cond_false;
+ cond_false = cond_true;
+ cond_true = t;
+ }
- SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));
+ SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));
- /* For each such register, mark it conditionally dead. */
- EXECUTE_IF_SET_IN_REG_SET
- (diff, 0, i,
- {
- struct reg_cond_life_info *rcli;
- rtx cond;
-
- rcli = xmalloc (sizeof (*rcli));
-
- if (REGNO_REG_SET_P (bb_true->global_live_at_start, i))
- cond = cond_false;
- else
- cond = cond_true;
- rcli->condition = cond;
- rcli->stores = const0_rtx;
- rcli->orig_condition = cond;
-
- splay_tree_insert (pbi->reg_cond_dead, i,
- (splay_tree_value) rcli);
- });
- }
+ /* For each such register, mark it conditionally dead. */
+ EXECUTE_IF_SET_IN_REG_SET
+ (diff, 0, i,
+ {
+ struct reg_cond_life_info *rcli;
+ rtx cond;
+
+ rcli = xmalloc (sizeof (*rcli));
+
+ if (REGNO_REG_SET_P (bb_true->global_live_at_start, i))
+ cond = cond_false;
+ else
+ cond = cond_true;
+ rcli->condition = cond;
+ rcli->stores = const0_rtx;
+ rcli->orig_condition = cond;
+
+ splay_tree_insert (pbi->reg_cond_dead, i,
+ (splay_tree_value) rcli);
+ });
}
FREE_REG_SET (diff);
@@ -2994,11 +2986,19 @@ ior_reg_cond (rtx old, rtx x, int add)
{
if (COMPARISON_P (x)
&& REVERSE_CONDEXEC_PREDICATES_P (GET_CODE (x), GET_CODE (old))
- && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
+ && rtx_equal_p (XEXP (x, 0), XEXP (old, 0))
+ && rtx_equal_p (XEXP (x, 1), XEXP (old, 1)))
return const1_rtx;
- if (GET_CODE (x) == GET_CODE (old)
- && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
+
+ if (GET_CODE (x) == GET_CODE (old) && rtx_equal_p (x, old))
return old;
+
+ if (COMPARISON_P (x)
+ && swap_condition (GET_CODE (x)) == GET_CODE (old)
+ && rtx_equal_p (XEXP (x, 0), XEXP (old, 1))
+ && rtx_equal_p (XEXP (x, 1), XEXP (old, 0)))
+ return old;
+
if (! add)
return NULL;
return gen_rtx_IOR (0, old, x);
@@ -3085,15 +3085,9 @@ not_reg_cond (rtx x)
x_code = GET_CODE (x);
if (x_code == NOT)
return XEXP (x, 0);
- if (COMPARISON_P (x)
- && GET_CODE (XEXP (x, 0)) == REG)
- {
- if (XEXP (x, 1) != const0_rtx)
- abort ();
-
- return gen_rtx_fmt_ee (reverse_condition (x_code),
- VOIDmode, XEXP (x, 0), const0_rtx);
- }
+ if (COMPARISON_P (x))
+ return gen_rtx_fmt_ee (reverse_condition (x_code),
+ VOIDmode, XEXP (x, 0), XEXP (x, 1));
return gen_rtx_NOT (0, x);
}
@@ -3106,11 +3100,18 @@ and_reg_cond (rtx old, rtx x, int add)
{
if (COMPARISON_P (x)
&& GET_CODE (x) == reverse_condition (GET_CODE (old))
- && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
+ && rtx_equal_p (XEXP (x, 0), XEXP (old, 0))
+ && rtx_equal_p (XEXP (x, 1), XEXP (old, 1)))
return const0_rtx;
- if (GET_CODE (x) == GET_CODE (old)
- && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
+
+ if (GET_CODE (x) == GET_CODE (old) && rtx_equal_p (x, old))
return old;
+ if (COMPARISON_P (x)
+ && GET_CODE (x) == swap_condition (GET_CODE (old))
+ && rtx_equal_p (XEXP (x, 0), XEXP (old, 1))
+ && rtx_equal_p (XEXP (x, 1), XEXP (old, 0)))
+ return old;
+
if (! add)
return NULL;
return gen_rtx_AND (0, old, x);
@@ -3197,7 +3198,8 @@ elim_reg_cond (rtx x, unsigned int regno
if (COMPARISON_P (x))
{
- if (REGNO (XEXP (x, 0)) == regno)
+ int nregs = HARD_REGNO_NREGS (regno, GET_MODE (XEXP (x, 0)));
+ if (refers_to_regno_p (regno, regno + nregs, x, NULL))
return const0_rtx;
return x;
}
More information about the Gcc-patches
mailing list