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] Fix FMA_EXPR expansion if fma insn isn't supported (PR target/47312)


On Thu, Feb 3, 2011 at 12:25 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> If target setting ends up being different between cc1 and lto1 compilation,
> we can have FMA_EXPRs in the IL which ICE during expansion, as there is no
> insn for them. ?The following patch fixes it by expanding it as a fma{,l,f}
> call in that case (x * y + z). ?Bootstrapped/regtested on x86_64-linux and
> i686-linux, ok for trunk?
>
> 2011-02-02 ?Jakub Jelinek ?<jakub@redhat.com>
>
> ? ? ? ?PR target/47312
> ? ? ? ?* expr.c (expand_expr_real_2) <case FMA_EXPR>: If target doesn't expand
> ? ? ? ?fma, expand FMA_EXPR as fma{,f,l} call.
>
> ? ? ? ?* gcc.target/i386/pr47312.c: New test.
>
> --- gcc/expr.c.jj ? ? ? 2011-01-28 20:35:51.000000000 +0100
> +++ gcc/expr.c ?2011-02-02 17:34:32.121461641 +0100
> @@ -7695,6 +7695,34 @@ expand_expr_real_2 (sepops ops, rtx targ
> ? ? ? ?optab opt = fma_optab;
> ? ? ? ?gimple def0, def2;
>
> + ? ? ? /* If there is no insn for FMA, emit it as __builtin_fma{,f,l}
> + ? ? ? ? ?call. ?*/
> + ? ? ? if (optab_handler (fma_optab, mode) == CODE_FOR_nothing)
> + ? ? ? ? {
> + ? ? ? ? ? tree fn = built_in_decls[BUILT_IN_FMA], call_expr;
> +
> + ? ? ? ? ? if (fn != NULL_TREE
> + ? ? ? ? ? ? ? && mode != TYPE_MODE (TREE_TYPE (TREE_TYPE (fn))))
> + ? ? ? ? ? ? fn = NULL_TREE;
> + ? ? ? ? ? if (fn == NULL_TREE)
> + ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? fn = built_in_decls[BUILT_IN_FMAF];
> + ? ? ? ? ? ? ? if (fn != NULL_TREE
> + ? ? ? ? ? ? ? ? ? && mode != TYPE_MODE (TREE_TYPE (TREE_TYPE (fn))))
> + ? ? ? ? ? ? ? ? fn = NULL_TREE;
> + ? ? ? ? ? ? }
> + ? ? ? ? ? if (fn == NULL_TREE)
> + ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? fn = built_in_decls[BUILT_IN_FMAL];
> + ? ? ? ? ? ? ? if (fn != NULL_TREE
> + ? ? ? ? ? ? ? ? ? && mode != TYPE_MODE (TREE_TYPE (TREE_TYPE (fn))))
> + ? ? ? ? ? ? ? ? fn = NULL_TREE;
> + ? ? ? ? ? ? }

Ick ;)  Can you use mathfn_built_in for this please?

Otherwise ok.

Thanks,
Richard.

> + ? ? ? ? ? gcc_assert (fn != NULL_TREE);
> + ? ? ? ? ? call_expr = build_call_expr (fn, 3, treeop0, treeop1, treeop2);
> + ? ? ? ? ? return expand_builtin (call_expr, target, subtarget, mode, false);
> + ? ? ? ? }
> +
> ? ? ? ?def0 = get_def_for_expr (treeop0, NEGATE_EXPR);
> ? ? ? ?def2 = get_def_for_expr (treeop2, NEGATE_EXPR);
>
> --- gcc/testsuite/gcc.target/i386/pr47312.c.jj ?2011-02-02 17:39:11.600424932 +0100
> +++ gcc/testsuite/gcc.target/i386/pr47312.c ? ? 2011-02-02 17:48:59.407388842 +0100
> @@ -0,0 +1,23 @@
> +/* PR target/47312 */
> +/* { dg-do link } */
> +/* { dg-require-effective-target lto } */
> +/* { dg-require-effective-target xop } */
> +/* { dg-options "-O -flto -mno-sse3 -mxop" } */
> +
> +extern double fma (double, double, double);
> +extern float fmaf (float, float, float);
> +extern long double fmal (long double, long double, long double);
> +
> +volatile float f;
> +volatile double d;
> +volatile long double ld;
> +
> +int
> +main ()
> +{
> + ?f = fmaf (f, f, f);
> + ?d = fma (d, d, d);
> + ?ld = fmal (ld, ld, ld);
> + ?asm volatile ("" : : "r" (&f), "r" (&d), "r" (&ld) : "memory");
> + ?return 0;
> +}
>
> ? ? ? ?Jakub
>


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