https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54089

--- Comment #96 from Alexander Klepikov <klepikov.alex+bugs at gmail dot com> 
---
(In reply to Oleg Endo from comment #95)
> The infinite loop is in splitting of the 'ashrsi3_n_call' pattern with the
> constant 1.  This is because 'ashrsi3_n_call' match overlaps with the 'shar'
> pattern.

Yes, I confirm that. 'operands[2] != const1_rtx' works well, thank you!

> Another point is that you had the
> 'cfun->machine->ashrsi3_libcall_expanded++;' in the wrong place.  It was
> counting up even if it wouldn't have emitted the libcall.

Not really. 'expand_ashiftrt' could emit

mov  #imm, r1
shad r1,   r0

and 'mov' instruction would be loop invariant if there's a loop. It looks like
'ashrsi3_libcall_expanded' is a bad name. I think name
'ashrsi3_n_call_expanded' would be more appropriate.

> However, there is one case from  your previous posts in PR 49263:
> 
> int f_rshift(char v){
>     return v >> S;
> }
> 
> This will not work on SH2 and expand to a libcall.

I think you mean SH2A, because the same is going on with SH4.

>  On SH4 the combine pass
> converts it into:
> 
> Successfully matched this instruction:
> (set (reg:SI 166)
>     (ashiftrt:SI (reg/v:SI 164 [ v ])
>         (const_int 31 [0x1f])))
> 
> But it doesn't even try to do so with the 'ashrsi3_n_call' pattern.  Not
> sure why ...

Well, the same thing is going on when using vanilla GCC. It looks like it's
happening due to char sign extension. Then instruction is catched by
'ashrsi2_31' pattern. In another words, it looks to me like an optimization.

Reply via email to