Ilya Leoshkevich wrote:

> r265490 allowed the compiler to choose in a more flexible way whether to
> use load or load-address-relative-long (LARL) instruction.  When it
> chose LARL for literal pool references, the latter ones were rewritten
> by pass_s390_early_mach to use UNSPEC_LTREF, which assumes base register
> usage, which in turn is not compatible with LARL.  The end result was an
> ICE because of unrecognizable insn.
> 
> UNSPEC_LTREF and friends are necessary in order to communicate the
> dependency on the base register to pass_sched2.  When LARL is used, no
> base register is necessary, so in such cases the rewrite must be
> avoided.

This is true.  But something else must still be going on here.  Note that
many other instruction patterns might contain constant pool addresses,
since they are accepted e.g. by the 'b' constraint.  In all of those
cases, we shouldn't add the UNSPEC_LTREF.  So just checking for the
specific LARL instruction pattern in annotate_constant_pool_refs does
not feel like a correct fix here.

In fact, before r265490, the pattern for movdi_larl could also contain a
constant pool address, so why didn't the problem occur then?  What's the
difference whether this is part of movdi_larl or just movdi?

> @@ -8184,7 +8200,8 @@ annotate_constant_pool_refs (rtx *x)
>         rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
>                                    UNSPEC_LTREF);
>  
> -       SET_SRC (*x) = plus_constant (Pmode, addr, off);
> +       SET_SRC (*x) = gen_rtx_CONST (Pmode,
> +                                     plus_constant (Pmode, addr, off));

This looks like an unrelated change ... it seems incorrect to me, given
the UNSPEC_LTREF actually contains a register reference, so it shouldn't
really be CONST.  (And if it were, why make the change just here and not
everywhere a UNSPEC_LTREF is generated?)

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  ulrich.weig...@de.ibm.com

Reply via email to