"Kewen.Lin" <[email protected]> writes:
> Hi Jeff,
>
> Thanks for the patch, one question is inlined below.
>
> on 2022/7/4 14:58, Jiufu Guo wrote:
>> The high part of the symbol address is invalid for the constant pool. In
>> function rs6000_cannot_force_const_mem, we already return true for
>> "HIGH with UNSPEC" rtx. During debug GCC, I found that
>> rs6000_cannot_force_const_mem is called for some other HIGH code rtx
>> expressions which also indicate the high part of a symbol_ref.
>> For example:
>> (high:DI (const:DI (plus:DI (symbol_ref:DI ("xx") (const_int 12 [0xc])))))
>> (high:DI (symbol_ref:DI ("var_1")..)))
>>
>> In the below case, this kind of rtx could occur in the middle of
>> optimizations
>> pass but was not dumped to a file. So, no test case is attached to this
>> patch.
>>
>
> Could you help to expand this more on how it affects some tree-optimization
> pass?
> I guess some tree-opt will expand gimple expression to rtx, evaluate the cost
> or similar and make some decision basing on it. If that is the case, you
> probably
> can construct one test case to show that: without this patch, the evaluated
> cost
> or similar looks off, the optimization decision is sub-optimal; with this
> patch,
> the optimization result is expected.
Hi Kewen,
Thanks a lot for your comments!
>From my investigations, I find some cases for which
rs6000_cannot_force_const_mem is called on "HIGH code" rtx which is not
UNSPEC sub-code. The code "decSetCoeff" is an example.
In the middle of "combine" pass, function "recog_for_combine" invokes
"force_const_mem", and the invoking could fail.
src = force_const_mem (mode, src);
if (src)
{
SUBST (SET_SRC (pat), src);
changed = true;
}
Here, the rtx "(high:DI (unspec:DI [(symbol_ref" is the argument for
the example code "decSetCoeff".
I also tried to see if other passes(GIMPLE) could hit this kind cases,
but did not find.
BR,
Jiufu(Jeff)
>
> BR,
> Kewen
>
>
>> extern const unsigned int __decPOWERS[10];
>> void
>> decSetCoeff (int *residue, const unsigned int *up)
>> {
>> unsigned int half = (unsigned int) __decPOWERS1[3] >> 1;
>>
>> if (*up >= half)
>> *residue = 7;
>>
>> return;
>> }
>>
>> This patch updates rs6000_cannot_force_const_mem to return true for
>> rtx with HIGH code.
>>
>>
>> Bootstrapped and regtested on ppc64le and ppc64.
>> Is it ok for trunk?
>>
>> BR,
>> Jiufu Guo
>>
>>
>> gcc/ChangeLog:
>>
>> * config/rs6000/rs6000.cc (rs6000_cannot_force_const_mem):
>> Return true for HIGH code rtx.
>>
>> ---
>> gcc/config/rs6000/rs6000.cc | 7 +++++--
>> 1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
>> index 3ff16b8ae04..c2b10669627 100644
>> --- a/gcc/config/rs6000/rs6000.cc
>> +++ b/gcc/config/rs6000/rs6000.cc
>> @@ -9707,8 +9707,11 @@ rs6000_init_stack_protect_guard (void)
>> static bool
>> rs6000_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
>> {
>> - if (GET_CODE (x) == HIGH
>> - && GET_CODE (XEXP (x, 0)) == UNSPEC)
>> + /* High part of a symbol ref/address can not be put into constant pool.
>> e.g.
>> + (high:DI (symbol_ref:DI ("var")..)) or
>> + (high:DI (unspec:DI [(symbol_ref/u:DI ("*.LC0")..)
>> + (high:DI (const:DI (plus:DI (symbol_ref:DI ("xx")) (const_int 12)))).
>> */
>> + if (GET_CODE (x) == HIGH)
>> return true;
>>
>> /* A TLS symbol in the TOC cannot contain a sum. */