On Thu, 28 Jan 2016, Jim Wilson wrote: > On Thu, Jan 28, 2016 at 5:37 AM, Richard Biener <rguent...@suse.de> wrote: > >> To workaround this, I defined a new hook expand_divmod_libfunc, which > >> targets must override for expanding call to target-specific dimovd. > >> The "default" hook default_expand_divmod_libfunc() expands call to > >> libgcc2.c:__udivmoddi4() since that's the only "generic" divmod > >> available. > >> Is this a reasonable approach ? > > > > Hum. How do they get to expand/generate it today? That said, I'm > > no expert in this area. > > Currently, the only place where a divmod libfunc can be called is in > expand_divmod in expmed.c, which can return either the div or mod > result, but not both. If this is called for the mod result, and there > is no div insn, and no mod insn, and no mod libfunc, then it will call > the divmod libfunc to generate the mod result. This is exactly the > case where the ARM port needs it, as this code was written for the > arm. > > There are 3 targets that define a divmod libfunc: arm, c6x, and spu. > The arm port is OK, because expand_divmod does the right thing for > arm, using the arm divmod calling convention. The c6x port is OK > because it defines mod insns and libfuncs, and hence the divmod > libfunc will never be called and is redundant. The spu port is also > OK, because it defines mod libcalls, and hence the divmod libfunc will > never be called, and is likewise redundant. Both the c6x and spu > ports have their own divmod library functions in > libgcc/config/$target. The divmod library functions are called by the > div and mod library functions, so they are necessary, they are just > never directly called. Both the c6x and spu port uses the current > libgcc __udivmoddi4 calling convention with a pointer to the mod > result, which is different and incompatible to the ARM convention of > returning a double size result that contains div and mod. > > WIth Prathamesh's patch to add support to the tree optimizers to > create divmod operations, the c6x and spu ports break. The divmod > libfuncs are no longer redundant, and will be called, except with the > wrong ABI, so we need to extend the divmod support to handle multiple > ABIs. This is why Prathamesh added the target hook for the divmod > libcall, so the target can specify the ABI used by its divmod > libcalls. Prathamesh has correct support for ARM (current code), and > apparently correct code for c6x and spu (libgcc udivmodsi4).
Thanks for the explanation. I wonder if rather than introducing a target hook ports could use a define_expand expanding to a libcall for this case? That said, I've reviewed the GIMPLE parts of the patch and am happy with that. I'd prefer if somebody with more RTL-expansion fu would review the rest of the patch. > > A simpler solution may be to not do the transform if there is no > > instruction for divmod. > > This prevents the optimization from happening on ARM, which has divmod > libfuncs but no divmod insn. We want the optimization to happen > there, as if we need both div and mod results, then calling the divmod > libfunc is faster than calling both the div and mod libfuncs. Ok, understood. It also affects all > word mode ops on all targets I think (not sure if we have TImode divmod in libgcc...). Richard. -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)