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.