This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH/RFC] Fix PR19402, __builtin_powi[lf]


On Mon, Jan 31, 2005 at 02:12:51PM +0100, Richard Guenther wrote:
> Any suggestions on how to do it "right" wrt libgcc?  I'm sure
> I got the #ifdefery wrong there and maybe the machine modes.
> And for sure I don't like the name.

A better name might be __powi<mode>2.  You must edit libgcc-std.ver.

You'll also have to use the optabs infrastructure to get the proper
function called from the expander, since there's no longer a 1-1
correspondence.  E.g. TYPE_MODE (double) == TYPE_MODE (long double)
on quite a lot of platforms.


> +       /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
> + 	 Otherwise, check the number of multiplications required.
> + 	 Note that pow never sets errno for an integer exponent.  */
> +       if ((TREE_INT_CST_HIGH (arg1) == 0
> + 	   || TREE_INT_CST_HIGH (arg1) == -1)
> + 	  && ((n >= -1 && n <= 2)
> + 	      || (flag_unsafe_math_optimizations
> + 		  && ! optimize_size
> + 		  && powi_cost (n) <= POWI_MAX_MULTS)))

Why is the number of multiplications relevant for __builtin_powi?
Other than the size of the generated code of course.  You cut and 
pasted this from the MULT_EXPR->POWI folder, didn't you.

Indeed, I might think that the code generaged by expand_powi using
the powi table would be more exact than that of the external 
function, if for no other reason than there are provably fewer
actual multiplications involved.

> + /* Integer power helper used from __builtin_powi for non-constant
> +    exponents.  */
> +
> + #define EXPAND_POWI_HELPER(name, mode) \
> + mode \
> + name (mode x, SItype m)	\
> + {				\
> +   USItype n = m < 0 ? -m : m;   \
> +   mode y = n % 2 ? x : 1;	\
> +   while (n >>= 1)		\
> +     {				\
> +       x = x * x;		\
> +       if (n % 2)		\
> + 	y = y * x;		\
> +     }				\
> +   return m < 0 ? (mode)1.0/y : y; \
> + }
> + #ifdef L_builtin_powif
> + EXPAND_POWI_HELPER(__builtin_powif, SFtype)
> + #endif
> + #ifdef L_builtin_powi
> + EXPAND_POWI_HELPER(__builtin_powi, DFtype)
> + #endif
> + #ifdef L_builtin_powil
> + #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80
> + EXPAND_POWI_HELPER(__builtin_powil, XFtype)
> + #endif
> + #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
> + EXPAND_POWI_HELPER(__builtin_powil, TFtype)
> + #endif
> + #endif
> + #undef EXPAND_POWI_HELPER

It would be much nicer if you could rearrange this such that the
actual function isn't totally macroized.  Something like

#if defined(L_powisf2) || defined(L_powidf2) ...
# if defined(L_powisf2)
#  define TYPE SFmode
#  define NAME __powisf2
# elif defined(L_powidf2)
  ...
# endif

TYPE
NAME (TYPE x, SItype m)
{
  ...
}
#endif /* All powi variants */

Also note that "1 / y" is sufficient.


r~


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]