On 12/1/20 2:07 PM, Jakub Jelinek wrote:
> Hi!
>
> Jeff has reported that my earlier patch broke rl78-elf, e.g. with
> unsigned short foo (unsigned short x) { return x % 7; }
> when compiled with -O2 -mg14. The problem is that rl78 is a BITS_PER_WORD
> == 8 target which doesn't have 8-bit modulo or divmod optab, but has instead
> 16-bit divmod, so my patch attempted to optimize it, then called
> expand_divmod to do 8-bit modulo and that in turn tried to do 16-bit modulo
> again.
>
> The following patch fixes it in two ways.
> One is to not perform the optimization when we have {u,s}divmod_optab
> handler for the double-word mode, in that case it is IMHO better to just
> do whatever we used to do before. This alone should fix the infinite
> recursion. But I'd be afraid some other target might have similar problem
> and might not have a divmod pattern, but only say a library call.
> So the patch also introduces a methods argument to expand_divmod such that
> normally we allow everything that was allowed before (using libcalls and
> widening), but when called from these expand_doubleword*mod routines we
> restrict it to no widening and no libcalls.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2020-12-01 Jakub Jelinek <ja...@redhat.com>
>
> * expmed.h (expand_divmod): Only declare if GCC_OPTABS_H is defined.
> Add enum optabs_method argument defaulted to OPTAB_LIB_WIDEN.
> * expmed.c: Include expmed.h after optabs.h.
> (expand_divmod): Add methods argument, if it is not OPTAB_{,LIB_}WIDEN,
> don't choose a wider mode, and pass it to other calls instead of
> hardcoded OPTAB_LIB_WIDEN. Avoid emitting libcalls if not
> OPTAB_LIB or OPTAB_LIB_WIDEN.
> * optabs.c: Include expmed.h after optabs.h.
> (expand_doubleword_mod, expand_doubleword_divmod): Pass OPTAB_DIRECT
> as last argument to expand_divmod.
> (expand_binop): Punt if {s,u}divmod_optab has handler for double-word
> int_mode.
> * expr.c: Include expmed.h after optabs.h.
> * explow.c: Include expmed.h after optabs.h.
OK.
jeff