Bug 35083 - [4.3 regression] ICE: in extract_insn, at recog.c:1990
Summary: [4.3 regression] ICE: in extract_insn, at recog.c:1990
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.3.0
: P2 normal
Target Milestone: 4.3.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2008-02-05 04:34 UTC by Ralf Corsepius
Modified: 2008-02-06 12:03 UTC (History)
4 users (show)

See Also:
Host:
Target: i386-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-02-05 08:26:16


Attachments
preprocessed source of file producing ICE (6.58 KB, text/plain)
2008-02-05 05:11 UTC, Ralf Corsepius
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ralf Corsepius 2008-02-05 04:34:27 UTC
Building gcc-trunk rev 132111 (2008-02-05) for i386-rtems* (elf w/ newlib) fails with:
...
make[7]: Entering directory `/users/rtems/src/toolchains/BUILD/i386-rtems4.9/i386-rtems4.9/soft-float/newlib/libm'
Making all in math
make[8]: Entering directory `/users/rtems/src/toolchains/BUILD/i386-rtems4.9/i386-rtems4.9/soft-float/newlib/libm/math'
/users/rtems/src/toolchains/BUILD/i386-rtems4.9/./gcc/xgcc -B/users/rtems/src/toolchains/BUILD/i386-rtems4.9/./gcc/ -nostdinc -B/users/rtems/src/toolchains/BUILD/i386-rtems4.9/i386-rtems4.9/soft-float/newlib/ -isystem /users/rtems/src/toolchains/BUILD/i386-rtems4.9/i386-rtems4.9/soft-float/newlib/targ-include -isystem /users/rtems/src/toolchains/gcc-trunk/newlib/libc/include -B/opt/rtems-4.9/i386-rtems4.9/bin/ -B/opt/rtems-4.9/i386-rtems4.9/lib/ -isystem /opt/rtems-4.9/i386-rtems4.9/include -isystem /opt/rtems-4.9/i386-rtems4.9/sys-include  -msoft-float -DPACKAGE_NAME=\"newlib\" -DPACKAGE_TARNAME=\"newlib\" -DPACKAGE_VERSION=\"1.16.0\" -DPACKAGE_STRING=\"newlib\ 1.16.0\" -DPACKAGE_BUGREPORT=\"\" -I. -I../../../../../../../gcc-trunk/newlib/libm/math -I../../../../../../../gcc-trunk/newlib/libm/math/../common -O2 -DMALLOC_PROVIDED -DEXIT_PROVIDED -DMISSING_SYSCALL_NAMES -DSIGNAL_PROVIDED -DREENTRANT_SYSCALLS_PROVIDED -DHAVE_OPENDIR -DNO_EXEC -DHAVE_FCNTL -fno-builtin      -O2 -g -g -O2    -msoft-float -c -o lib_a-sf_erf.o `test -f 'sf_erf.c' || echo '../../../../../../../gcc-trunk/newlib/libm/math/'`sf_erf.c
../../../../../../../gcc-trunk/newlib/libm/math/sf_erf.c: In function 'erfcf':
../../../../../../../gcc-trunk/newlib/libm/math/sf_erf.c:222: error: unrecognizable insn:
(insn 33 32 34 6 ../../../../../../../gcc-trunk/newlib/libm/math/sf_erf.c:171 (set (reg:SF 84)
        (plus:SF (reg:SF 85)
            (reg:SF 85))) -1 (nil))
../../../../../../../gcc-trunk/newlib/libm/math/sf_erf.c:222: internal compiler error: in extract_insn, at recog.c:1990
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make[8]: *** [lib_a-sf_erf.o] Error 1
Comment 1 Ralf Corsepius 2008-02-05 05:11:50 UTC
Created attachment 15097 [details]
preprocessed source of file producing ICE
Comment 2 Uroš Bizjak 2008-02-05 07:33:45 UTC
Confirmed.

The testcase:

float test(unsigned int x)
{
  return (float)x;
}

gcc -O2 -mno-80387

t.c: In function âtestâ:
t.c:4: error: unrecognizable insn:
(insn 20 19 21 5 t.c:2 (set (reg:SF 60)
        (plus:SF (reg:SF 61)
            (reg:SF 61))) -1 (nil))
t.c:4: internal compiler error: in extract_insn, at recog.c:1990
Please submit a full bug report,
Comment 3 Uroš Bizjak 2008-02-05 08:26:16 UTC
Mine.
Comment 4 Uroš Bizjak 2008-02-05 09:36:12 UTC
Following patch fixes ICE (and avoids nasty runtime/code-size regression for x87 math where we don't use fildll):

--cut here--
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 132088)
+++ config/i386/i386.md (working copy)
@@ -5306,9 +5306,9 @@
 (define_expand "floatunssisf2"
   [(use (match_operand:SF 0 "register_operand" ""))
    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
-  "!TARGET_64BIT"
+  "!TARGET_64BIT && TARGET_SSE_MATH"
 {
-  if (TARGET_SSE_MATH && TARGET_SSE2)
+  if (TARGET_SSE2)
     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
   else
     x86_emit_floatuns (operands);
--cut here--

but there is another problem for soft-float, where neither signed or unsigned float pattern is provided. Instead of calling __floatunssfsi() directly for soft-float targets, we expand as:

test:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $24, %esp
        movl    8(%ebp), %edx
        testl   %edx, %edx
        js      .L3
        movl    %edx, (%esp)
        call    __floatsisf
        leave
        ret
.L3:
        movl    %edx, %eax
        andl    $1, %eax
        shrl    %edx
        orl     %edx, %eax
        movl    %eax, (%esp)
        call    __floatsisf
        movl    %eax, 4(%esp)
        movl    %eax, (%esp)
        call    __addsf3
        leave
        ret

This is a huge code-size (and performance?) regression from 4.2 where we generated:

test:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $24, %esp
        movl    8(%ebp), %eax
        movl    %eax, (%esp)
        call    __floatunsisf
        leave
        ret

This is probably due to:

	2007-09-05  Janis Johnson  <janis187@us.ibm.com>

	* optabs.c (expand_float): Convert unsigned integer as signed only
	if it provides sufficient accuracy; add mode argument to real_2expN.
	...
Comment 5 Uroš Bizjak 2008-02-05 09:45:47 UTC
optabs.c, line 5150:

--cut here--
  /* Unsigned integer, and no way to convert directly.  Convert as signed,
     then unconditionally adjust the result.  For decimal float values we
     do this only if we have already determined that a signed conversion
     provides sufficient accuracy.  */
  if (unsignedp && (can_do_signed || !DECIMAL_FLOAT_MODE_P (GET_MODE (to))))
--cht here--

Hm? We shortcut with !DECIMAL_FLOAT_MODE_P (...) here. Janis?
Comment 6 uros 2008-02-05 11:28:20 UTC
Subject: Bug 35083

Author: uros
Date: Tue Feb  5 11:27:41 2008
New Revision: 132114

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132114
Log:
	PR target/35083
	* config/i386/i386.md (floatunsisf2): Enable for TARGET_SSE_MATH only.
	Call ix86_expand_convert_uns_sisf_sse for TARGET_SSE2.

testsuite/ChangeLog:

	PR target/35083
	* gcc.target/i386/pr35083.c: New test.


Added:
    trunk/gcc/testsuite/gcc.target/i386/pr35083.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.md
    trunk/gcc/testsuite/ChangeLog

Comment 7 Uroš Bizjak 2008-02-05 13:58:08 UTC
This is the diff of expand_float() between gcc-4.2 and gcc-4.3. The relevant part is logic at the top of the diff that has changed substantially:

--- 222 2008-02-05 14:52:52.000000000 +0100
+++ 111 2008-02-05 14:52:32.000000000 +0100
@@ -52,11 +52,10 @@
          }
       }
 
-  /* Unsigned integer, and no way to convert directly.  Convert as signed,
-     then unconditionally adjust the result.  For decimal float values we
-     do this only if we have already determined that a signed conversion
-     provides sufficient accuracy.  */
-  if (unsignedp && (can_do_signed || !DECIMAL_FLOAT_MODE_P (GET_MODE (to))))
+  /* Unsigned integer, and no way to convert directly.  For binary
+     floating point modes, convert as signed, then conditionally adjust
+     the result.  */
+  if (unsignedp && can_do_signed && !DECIMAL_FLOAT_MODE_P (GET_MODE (to)))
     {
       rtx label = gen_label_rtx ();
       rtx temp;
@@ -147,7 +146,7 @@
                               0, label);
 
 
-      real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)), fmode);
+      real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
       temp = expand_binop (fmode, add_optab, target,
                           CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
                           target, 0, OPTAB_LIB_WIDEN);
@@ -169,7 +168,7 @@
       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
        from = convert_to_mode (SImode, from, unsignedp);
 
-      libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
+      libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
       gcc_assert (libfunc);
 
       start_sequence ();
Comment 8 uros 2008-02-06 10:46:15 UTC
Subject: Bug 35083

Author: uros
Date: Wed Feb  6 10:45:29 2008
New Revision: 132144

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132144
Log:
	PR target/35083
	* optabs.c (expand_float): Do not check for decimal modes when
	expanding unsigned integer through signed conversion.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/optabs.c

Comment 9 Uroš Bizjak 2008-02-06 11:11:06 UTC
Fixed.
Comment 10 Ralf Corsepius 2008-02-06 12:03:10 UTC
Thanks Uros, i386-rtems*-gcc now bootstraps again.