> Am 29.10.2018 um 19:45 schrieb Ulrich Weigand <uweig...@de.ibm.com>:
>
> Ilya Leoshkevich wrote:
>
>>
>> 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.
I have changed the patch to skip all larl_operands, regardless of which
context they appear in. Regtest is running.
>
> 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?
>
The difference is usage of "X" constraint. Before, when we initially
chose movdi_larl, we could still put UNSPEC_LTREF inside it without
consequences, because during UNSPEC_LTREF lifetime only constraints are
checked. Example:
pr59037.c.274r.reload: Recognized as movdi_larl.
(insn 7 9 14 2 (set (reg/f:DI 1 %r1 [65])
(const:DI (plus:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2])
(const_int 16 [0x10])))) 1269 {*movdi_larl})
pr59037.c.281r.early_mach: Rewrite with UNSPEC_LTREF.
pr59037.c.291r.cprop_hardreg: We fail here today, because constraints
don't match. We would have also failed in
the past, if predicates were also checked.
(insn 7 9 14 2 (set (reg/f:DI 1 %r1 [65])
(plus:DI (unspec:DI [
(symbol_ref/u:DI ("*.LC0") [flags 0x2])
(reg:DI 5 %r5)
] UNSPEC_LTREF)
(const_int 16 [0x10]))) 1269 {*movdi_larl})
pr59037.c.306r.shorten: Re-recognized as la_64.
(insn 7 21 14 (set (reg/f:DI 1 %r1 [65])
(plus:DI (reg:DI 5 %r5)
(const:DI (plus:DI (unspec:DI [
(label_ref:DI 35)
(label_ref:DI 34)
] UNSPEC_POOL_OFFSET)
(const_int 16 [0x10]))))) 1272 {*la_64})
>> @@ -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?)
You are right, this is a leftover from the first attempt to fix the
symptom: larl_operand did not match non-CONST PLUS rtxs. I have removed
it from the patch and will send it separately later, if it somehow
proves useful.