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