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). > 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. Jim