This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Real purpose for failure in "Too restrictive sanity check"
> On Thu, Apr 20, 2000 at 10:33:54AM -0600, Jeffrey A Law wrote:
> > However, they are caused you recent loop.c change:
> >
> > * loop.c (emit_iv_add_mult): Simplify it's input and emit
> > REG_EQUAL note explaining the calculated value.
> >
> > This is causing the stage1 compiler to mis-compile genattrtab.
>
> It breaks Alpha too. I've reverted the change.
Oops, I fell so embrassed by causing yet another breakage. This patch looked
very innocent to me.
>
> The problem is that it emits notes like this:
>
> (insn 234 229 239 (set (reg:DI 133)
> (reg:DI 122)) -1 (nil)
> (expr_list:REG_EQUAL (reg:DI 122)
> (nil)))
>
> which is wrong. The notes must be limited to function-wide invariants.
I don't think this holds for REG_EQUAL notes. (and it don't even hold for some
REG_EQUIV notes we emit). This looks like problem with single REG in the
REG_EQUAL note. I remember Jeff claiming this to be prohibited (even when the
reason is not clear to me). I didn't seen yet such an note emited by this code
(and I am very surprised, that loop.c uses emit_iv_add_mult to do no-op moves),
but it is probably used for giv initialization with add_val=0, since we don't strength
reduce much on i386, this didn't show to me.
Proper fix seems to be to avoid single register in the notes.
In case REG_EQUIV notes needs to be invariants, I guess my patch to gcse.c needs
fixing. Please can someone confirm this?
Anyway can you please test a patch I will send shortly that will not emit REG_EQUAL
notes for single register? Perhaps this will fix the problem.
I didn't bootstrapped this patch yet, but since it is just trivial change, I expect
that i386 bootstrap will not show much.
Honza
Sun Apr 9 19:15:24 CEST 2000 Jan Hubicka <jh@suse.cz>
* loop.c (emit_iv_add_mult): Simplify it's input and emit REG_EQUAL note
explaining the calculated value.
Index: egcs/gcc/loop.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/loop.c,v
retrieving revision 1.239
diff -c -3 -p -r1.239 loop.c
*** loop.c 2000/04/21 02:56:58 1.239
--- loop.c 2000/04/21 12:03:11
*************** emit_iv_add_mult (b, m, a, reg, insert_b
*** 7640,7650 ****
--- 7640,7663 ----
{
rtx seq;
rtx result;
+ rtx last;
+ rtx set;
+ rtx exp;
+ enum machine_mode mode = GET_MODE (reg);
/* Prevent unexpected sharing of these rtx. */
a = copy_rtx (a);
b = copy_rtx (b);
+ /* We may be faced to (plus (symbol_ref) (const_int)). We want to simplify this
+ to CONST rtx. */
+ exp = simplify_rtx (a);
+ if (exp)
+ a = exp;
+ exp = simplify_rtx (b);
+ if (exp)
+ b = exp;
+
/* Increase the lifetime of any invariants moved further in code. */
update_reg_last_use (a, insert_before);
update_reg_last_use (b, insert_before);
*************** emit_iv_add_mult (b, m, a, reg, insert_b
*** 7657,7663 ****
seq = gen_sequence ();
end_sequence ();
! emit_insn_before (seq, insert_before);
/* It is entirely possible that the expansion created lots of new
registers. Iterate over the sequence we just created and
--- 7670,7676 ----
seq = gen_sequence ();
end_sequence ();
! last = emit_insn_before (seq, insert_before);
/* It is entirely possible that the expansion created lots of new
registers. Iterate over the sequence we just created and
*************** emit_iv_add_mult (b, m, a, reg, insert_b
*** 7668,7681 ****
int i;
for (i = 0; i < XVECLEN (seq, 0); ++i)
{
! rtx set = single_set (XVECEXP (seq, 0, i));
if (set && GET_CODE (SET_DEST (set)) == REG)
record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
}
}
! else if (GET_CODE (seq) == SET
! && GET_CODE (SET_DEST (seq)) == REG)
! record_base_value (REGNO (SET_DEST (seq)), SET_SRC (seq), 0);
}
/* Test whether A * B can be computed without
--- 7681,7730 ----
int i;
for (i = 0; i < XVECLEN (seq, 0); ++i)
{
! set = single_set (XVECEXP (seq, 0, i));
if (set && GET_CODE (SET_DEST (set)) == REG)
record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
}
+ last = XVECEXP (seq, 0, i - 1);
+ }
+ else
+ {
+ set = single_set (last);
+ if (set && GET_CODE (SET_DEST (set)) == REG)
+ record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
}
! if (!last)
! return;
! /* Sequence really ought to end by set storing final value to the register.
!
! Attach note indicating expression we've just calculated to it. This is important
! for second run of loop optimizer to understand strength reduced givs from
! the first run. */
! if (GET_CODE (last) != INSN)
! abort();
! set = single_set (last);
! if (!set)
! return;
! if (SET_DEST (set) != reg)
! abort();
!
! /* In case we start to emit some usefull notes to these insns, get abort here,
! since we need to decide what information is more important. */
! if (find_reg_note (last, REG_EQUIV, NULL_RTX)
! || find_reg_note (last, REG_EQUAL, NULL_RTX))
! abort();
!
! /* Expression we've just caluclated. */
! exp = simplify_gen_binary (PLUS, mode,
! simplify_gen_binary (MULT, mode, b, m),
! a);
! /* Single register REG_EQUAL notes are not allowed, and they are useless anyway. */
! if (REG_P (exp))
! return;
! REG_NOTES (last)
! = gen_rtx_EXPR_LIST (REG_EQUAL,
! exp,
! REG_NOTES (last));
}
/* Test whether A * B can be computed without