Fix PR43305: ICE in emit_unop_insn

Richard Guenther richard.guenther@gmail.com
Thu Mar 18 18:24:00 GMT 2010


On Thu, Mar 18, 2010 at 5:36 PM, Michael Matz <matz@suse.de> wrote:
> Hello,
>
> emit_unop_insn must not fail, but some patterns do fail for -Os.  And it's
> reasonable that they do.  In the builtin expander we can care for this
> just fine (we'll emit libcalls).  So, let's use maybe_emit_unop_insn.  If
> it fails we simply remove the instructions we generated up to that point
> (and take care to also undo the effect of fiddling with the call
> expressions arguments directly), and continue on.
>
> Fixes the testcase, regstrapping on x86_64-linux in progress.  Okay for
> trunk?

Ok.

Thanks,
Richard.

>
> Ciao,
> Michael.
> --
>        PR 43305
>        * builtins.c (expand_builtin_interclass_mathfn,
>        expand_builtin_signbit): Use maybe_emit_unop_insn, emit libcalls
>        if that fails.
>
> testsuite/
>        * gcc.dg/pr43305.c: New testcase.
>
> Index: builtins.c
> ===================================================================
> --- builtins.c  (revision 157543)
> +++ builtins.c  (working copy)
> @@ -2312,6 +2312,8 @@ expand_builtin_interclass_mathfn (tree e
>
>   if (icode != CODE_FOR_nothing)
>     {
> +      rtx last = get_last_insn ();
> +      tree orig_arg = arg;
>       /* Make a suitable register to place result in.  */
>       if (!target
>          || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
> @@ -2332,8 +2334,10 @@ expand_builtin_interclass_mathfn (tree e
>
>       /* Compute into TARGET.
>         Set TARGET to wherever the result comes back.  */
> -      emit_unop_insn (icode, target, op0, UNKNOWN);
> -      return target;
> +      if (maybe_emit_unop_insn (icode, target, op0, UNKNOWN))
> +       return target;
> +      delete_insns_since (last);
> +      CALL_EXPR_ARG (exp, 0) = orig_arg;
>     }
>
>   return NULL_RTX;
> @@ -5197,9 +5201,11 @@ expand_builtin_signbit (tree exp, rtx ta
>   icode = signbit_optab->handlers [(int) fmode].insn_code;
>   if (icode != CODE_FOR_nothing)
>     {
> +      rtx last = get_last_insn ();
>       target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
> -      emit_unop_insn (icode, target, temp, UNKNOWN);
> -      return target;
> +      if (maybe_emit_unop_insn (icode, target, temp, UNKNOWN))
> +       return target;
> +      delete_insns_since (last);
>     }
>
>   /* For floating point formats without a sign bit, implement signbit
> Index: testsuite/gcc.dg/pr43305.c
> ===================================================================
> --- testsuite/gcc.dg/pr43305.c  (revision 0)
> +++ testsuite/gcc.dg/pr43305.c  (revision 0)
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-Os -ffast-math" } */
> +extern int ilogbl(long double);
> +extern int printf(const char *format, ...);
> +
> +__attribute__((noinline, noclone))
> +int foo(long double x)
> +{
> +  return ilogbl(x);
> +}
> +
> +int main()
> +{
> +  printf("%d\n", foo(100));
> +  return 0;
> +}
>



More information about the Gcc-patches mailing list