"Kewen.Lin" <li...@linux.ibm.com> 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.  */

Reply via email to