===================================================================
@@ -4729,7 +4729,7 @@ inherit_reload_reg (bool def_p, int orig
}
return false;
}
- lra_substitute_pseudo_within_insn (insn, original_regno, new_reg);
+ lra_substitute_pseudo_within_insn (insn, original_regno, new_reg, false);
lra_update_insn_regno_info (insn);
if (! def_p)
/* We now have a new usage insn for original regno. */
@@ -4761,7 +4761,7 @@ inherit_reload_reg (bool def_p, int orig
lra_assert (DEBUG_INSN_P (usage_insn));
next_usage_insns = XEXP (next_usage_insns, 1);
}
- lra_substitute_pseudo (&usage_insn, original_regno, new_reg);
+ lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false);
lra_update_insn_regno_info (as_a <rtx_insn *> (usage_insn));
if (lra_dump_file != NULL)
{
@@ -5023,7 +5023,7 @@ split_reg (bool before_p, int original_r
usage_insn = XEXP (next_usage_insns, 0);
lra_assert (DEBUG_INSN_P (usage_insn));
next_usage_insns = XEXP (next_usage_insns, 1);
- lra_substitute_pseudo (&usage_insn, original_regno, new_reg);
+ lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false);
lra_update_insn_regno_info (as_a <rtx_insn *> (usage_insn));
if (lra_dump_file != NULL)
{
@@ -5955,8 +5955,9 @@ remove_inheritance_pseudos (bitmap remov
{
if (change_p && bitmap_bit_p (remove_pseudos, regno))
{
- lra_substitute_pseudo_within_insn (
- curr_insn, regno, regno_reg_rtx[restore_regno]);
+ lra_substitute_pseudo_within_insn
+ (curr_insn, regno, regno_reg_rtx[restore_regno],
+ false);
restored_regs_p = true;
}
else
@@ -6079,9 +6080,9 @@ undo_optional_reloads (void)
we remove the inheritance pseudo and the optional
reload. */
}
- lra_substitute_pseudo_within_insn (
- insn, regno,
- regno_reg_rtx[lra_reg_info[regno].restore_regno]);
+ lra_substitute_pseudo_within_insn
+ (insn, regno, regno_reg_rtx[lra_reg_info[regno].restore_regno],
+ false);
lra_update_insn_regno_info (insn);
if (lra_dump_file != NULL)
{
===================================================================
@@ -314,8 +314,8 @@ extern void lra_update_dups (lra_insn_re
extern void lra_process_new_insns (rtx_insn *, rtx_insn *, rtx_insn *,
const char *);
-extern bool lra_substitute_pseudo (rtx *, int, rtx);
-extern bool lra_substitute_pseudo_within_insn (rtx_insn *, int, rtx);
+extern bool lra_substitute_pseudo (rtx *, int, rtx, bool);
+extern bool lra_substitute_pseudo_within_insn (rtx_insn *, int, rtx, bool);
extern lra_insn_recog_data_t lra_set_insn_recog_data (rtx_insn *);
extern lra_insn_recog_data_t lra_update_insn_recog_data (rtx_insn *);
===================================================================
@@ -759,7 +759,7 @@ process_bb_lives (basic_block bb, int &c
{
insn = lra_insn_recog_data[uid]->insn;
lra_substitute_pseudo_within_insn (insn, dst_regno,
- SET_SRC (set));
+ SET_SRC (set), true);
lra_update_insn_regno_info (insn);
}
}
===================================================================
@@ -1818,9 +1818,10 @@ lra_process_new_insns (rtx_insn *insn, r
/* Replace all references to register OLD_REGNO in *LOC with pseudo
- register NEW_REG. Return true if any change was made. */
+ register NEW_REG. Try to simplify subreg of constant if SUBREG_P.
+ Return true if any change was made. */
bool
-lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg)
+lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p)
{
rtx x = *loc;
bool result = false;
@@ -1832,9 +1833,25 @@ lra_substitute_pseudo (rtx *loc, int old
return false;
code = GET_CODE (x);
- if (code == REG && (int) REGNO (x) == old_regno)
+ if (code == SUBREG && subreg_p)
{
- machine_mode mode = GET_MODE (*loc);
+ rtx subst, inner = SUBREG_REG (x);
+ /* Transform subreg of constant while we still have inner mode
+ of the subreg. The subreg internal should not be an insn
+ operand. */
+ if (REG_P (inner) && (int) REGNO (inner) == old_regno
+ && CONSTANT_P (new_reg)
+ && (subst = simplify_subreg (GET_MODE (x), new_reg, GET_MODE (inner),
+ SUBREG_BYTE (x))) != NULL_RTX)
+ {
+ *loc = subst;
+ return true;
+ }
+
+ }
+ else if (code == REG && (int) REGNO (x) == old_regno)
+ {
+ machine_mode mode = GET_MODE (x);
machine_mode inner_mode = GET_MODE (new_reg);
if (mode != inner_mode
@@ -1856,26 +1873,30 @@ lra_substitute_pseudo (rtx *loc, int old
{
if (fmt[i] == 'e')
{
- if (lra_substitute_pseudo (&XEXP (x, i), old_regno, new_reg))
+ if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
+ new_reg, subreg_p))
result = true;
}
else if (fmt[i] == 'E')
{
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno, new_reg))
+ if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno,
+ new_reg, subreg_p))
result = true;
}
}
return result;
}
-/* Call lra_substitute_pseudo within an insn. This won't update the insn ptr,
- just the contents of the insn. */
+/* Call lra_substitute_pseudo within an insn. Try to simplify subreg
+ of constant if SUBREG_P. This won't update the insn ptr, just the
+ contents of the insn. */
bool
-lra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno, rtx new_reg)
+lra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno,
+ rtx new_reg, bool subreg_p)
{
rtx loc = insn;
- return lra_substitute_pseudo (&loc, old_regno, new_reg);
+ return lra_substitute_pseudo (&loc, old_regno, new_reg, subreg_p);
}
===================================================================
@@ -0,0 +1,64 @@
+/* PR debug/66691 */
+/* { dg-do compile } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-O3 -g -mtune=generic -march=i686" } */
+
+unsigned int a;
+int b[2], c, d, e, f, g, h, i, k[8], l, m, s, t, w;
+static int j;
+
+void
+fn1 (long long p)
+{
+ int t = p;
+ c = c ^ b[c ^ (t & 1)];
+}
+
+static void
+fn2 (long long p)
+{
+ c = c ^ b[1 ^ (d & 1)];
+ fn1 (p >> 1 & 1);
+ fn1 (p >> 2);
+}
+
+static void
+fn3 ()
+{
+ unsigned char p;
+ f = g = 0;
+ for (h = 0; h < 6; h++)
+ {
+ for (s = 0; s < 7; s++)
+ if (k[s+1])
+ g = 0;
+ else
+ for (j = 0; j < 2; j++)
+ ;
+ t = j > 2 ? 0 : 1 >> j;
+ }
+ if (l)
+ {
+ short q[2];
+ q[0] = q[1] = 0;
+ if (m)
+ for (i = 0; i < 2; i++)
+ {
+ unsigned char r = q[i];
+ p = f ? r % f : r;
+ e = ((p > 0) <= (q[i] ^ 1)) + a;
+ if (k[1])
+ for (e = 0; e != 18; ++e)
+ k[0] = 0;
+ }
+ }
+}
+
+int
+main ()
+{
+ fn3 ();
+ fn2 (w);
+ fn2 (j);
+ return 0;
+}