Fix PR43305: ICE in emit_unop_insn
Michael Matz
matz@suse.de
Thu Mar 18 16:47:00 GMT 2010
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?
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