Bug 44695 - [4.6 Regression] ice in simplify_subreg, at simplify-rtx.c:5117
Summary: [4.6 Regression] ice in simplify_subreg, at simplify-rtx.c:5117
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: 4.6.0
Assignee: Not yet assigned to anyone
URL: http://gcc.gnu.org/ml/gcc-patches/201...
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-28 06:00 UTC by John Regehr
Modified: 2010-07-05 12:21 UTC (History)
4 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2010-06-28 09:17:18


Attachments
A patch (337 bytes, patch)
2010-06-28 23:21 UTC, H.J. Lu
Details | Diff
A patch (861 bytes, patch)
2010-06-30 18:15 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description John Regehr 2010-06-28 06:00:53 UTC
regehr@john-home:~/volatile/bugs/tmp319$ current-gcc -v

Using built-in specs.
COLLECT_GCC=current-gcc
COLLECT_LTO_WRAPPER=/home/regehr/z/compiler-install/gcc-r161425-install/libexec/gcc/i686-pc-linux-gnu/4.6.0/lto-wrapper
Target: i686-pc-linux-gnu
Configured with: ../configure --with-libelf=/usr/local --enable-lto --prefix=/home/regehr/z/compiler-install/gcc-r161425-install --program-prefix=r161425- --enable-languages=c,c++
Thread model: posix
gcc version 4.6.0 20100626 (experimental) (GCC) 

regehr@john-home:~/volatile/bugs/tmp319$ current-gcc -O2 small.c -c 

small.c: In function ‘int81’:
small.c:20:1: internal compiler error: in simplify_subreg, at simplify-rtx.c:5117
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

regehr@john-home:~/volatile/bugs/tmp319$ cat small.c

typedef int int32_t;
typedef unsigned char uint8_t;

static uint8_t
safe_div_func_uint8_t_u_u (uint8_t ui1, uint8_t ui2)
{
  return ui2 ? : (ui1 / ui2);
}

int safe (int);
int func_51 (int);

void
int81 (void)
{
  int32_t l_219 = 8L;
  if (safe (safe_div_func_uint8_t_u_u (1 || 0, l_219 & func_51 (0))))
    {
    }
}
Comment 1 Richard Biener 2010-06-28 09:17:18 UTC
Confirmed.  A recent regression.

#2  0x00000000009ad621 in simplify_subreg (outermode=HImode, 
    op=0x7ffff7facd40, innermode=QImode, byte=0)
    at /space/rguenther/src/svn/trunk/gcc/simplify-rtx.c:5116
5116      gcc_assert (GET_MODE (op) == innermode
5117                  || GET_MODE (op) == VOIDmode);
(gdb) call debug_rtx (op)
(reg:HI 68)

during combine.
Comment 2 H.J. Lu 2010-06-28 21:57:09 UTC
I think it is a latent bug exposed by revision 161329. Now
x86 backend may generate:

(ior:HI (ashift:HI (zero_extend:HI (umod:QI (reg:HI 68)
                (reg:QI 61 [ D.2750 ])))
        (const_int 8 [0x8]))
    (zero_extend:HI (udiv:QI (reg:HI 68)
            (reg:QI 61 [ D.2750 ]))))

Combine ran into trouble:
(gdb) bt
#0  fancy_abort (
    file=0x11e5860 "/export/gnu/import/git/gcc/gcc/simplify-rtx.c", line=5117, 
    function=0x11e6be0 "simplify_subreg")
    at /export/gnu/import/git/gcc/gcc/diagnostic.c:879
#1  0x00000000009d76ad in simplify_subreg (outermode=HImode, 
    op=0x7ffff1d04f00, innermode=QImode, byte=0)
    at /export/gnu/import/git/gcc/gcc/simplify-rtx.c:5116
#2  0x00000000009d87e6 in simplify_gen_subreg (outermode=HImode, 
    op=0x7ffff1d04f00, innermode=QImode, byte=0)
    at /export/gnu/import/git/gcc/gcc/simplify-rtx.c:5426
#3  0x0000000000fcc60a in if_then_else_cond (x=0x7ffff1b6d390, 
    ptrue=0x7fffffffd448, pfalse=0x7fffffffd438)
    at /export/gnu/import/git/gcc/gcc/combine.c:8219
#4  0x0000000000fcbf66 in if_then_else_cond (x=0x7ffff1b6d3a8, 
    ptrue=0x7fffffffd4d0, pfalse=0x7fffffffd4c8)
    at /export/gnu/import/git/gcc/gcc/combine.c:8103
#5  0x0000000000fc305a in combine_simplify_rtx (x=0x7ffff1b6d3a8, 
    op0_mode=VOIDmode, in_dest=0)
    at /export/gnu/import/git/gcc/gcc/combine.c:4864
#6  0x0000000000fc2def in subst (x=0x7ffff1b6d3a8, from=0x7ffff1c170c0, 
    to=0x7ffff1c170c0, in_dest=0, unique_copy=0)
    at /export/gnu/import/git/gcc/gcc/combine.c:4803
#7  0x0000000000fc2ba7 in subst (x=0x7ffff1b64720, from=0x7ffff1c170c0, 
---Type <return> to continue, or q <return> to quit---
    to=0x7ffff1c170c0, in_dest=0, unique_copy=0)
    at /export/gnu/import/git/gcc/gcc/combine.c:4741
#8  0x0000000000fc2ba7 in subst (x=0x7ffff1b64738, from=0x7ffff1c170c0, 
    to=0x7ffff1c170c0, in_dest=0, unique_copy=0)
    at /export/gnu/import/git/gcc/gcc/combine.c:4741
#9  0x0000000000fbd20b in try_combine (i3=0x7ffff1b0a870, i2=0x7ffff1b0a798, 
    i1=0x0, new_direct_jump_p=0x7fffffffdaf4)
    at /export/gnu/import/git/gcc/gcc/combine.c:2885
#10 0x0000000000fb911e in combine_instructions (f=0x7ffff1c227c0, nregs=70)
    at /export/gnu/import/git/gcc/gcc/combine.c:1152
#11 0x0000000000fd898f in rest_of_handle_combine ()
    at /export/gnu/import/git/gcc/gcc/combine.c:13342
Comment 3 H.J. Lu 2010-06-28 23:21:30 UTC
Created attachment 21033 [details]
A patch

This patch avoids ICE. But it probably isn't the right fix.
Comment 4 H.J. Lu 2010-06-29 19:16:11 UTC
A patch is posted at

http://gcc.gnu.org/ml/gcc-patches/2010-06/msg03033.html
Comment 5 Paolo Bonzini 2010-06-30 11:51:54 UTC
I agree that the problem is a wrong pattern.

Here you have non-matching mode between the udiv/umod and the first argument:

> (ior:HI (ashift:HI (zero_extend:HI (umod:QI (reg:HI 68)
>                 (reg:QI 61 [ D.2750 ])))
>         (const_int 8 [0x8]))
>     (zero_extend:HI (udiv:QI (reg:HI 68)
>             (reg:QI 61 [ D.2750 ]))))

Instead you need to have this before reload:

(set (match_operand:HI "register_operand" "=a")
    (ior:HI (ashift:HI
        (zero_extend:HI (umod:QI (match_operand:QI "register_operand" "0")
                                 (match_operand:QI "register_operand" "q")))
            (const_int 8 [0x8]))
        (zero_extend:HI (udiv:QI (match_dup 1) (match_dup 2))))

and after reload split it into a zero/sign extension of al into ax followed by

(set (match_dup 0)
    (ior:HI (ashift:HI (umod:HI (match_dup 0)
                 (zero_extend:HI (match_dup 2)))
        (const_int 8 [0x8]))
    (udiv:HI (match_dup 0)
            (zero_extend:HI (match_dup 2))))

(or maybe sign extend into eax? QImode->SImode is definitely cheaper for zero extension, I don't know about the cost of cbw because of partial register stalls).
Comment 6 H.J. Lu 2010-06-30 18:15:12 UTC
Created attachment 21045 [details]
A patch

Using

(set (match_operand:HI "register_operand" "=a")
    (ior:HI (ashift:HI
        (zero_extend:HI (umod:QI (match_operand:QI "register_operand" "0")
                                 (match_operand:QI "register_operand" "q")))
            (const_int 8 [0x8]))
        (zero_extend:HI (udiv:QI (match_dup 1) (match_dup 2))))

before reload and split to

(set (match_dup 0)
    (ior:HI (ashift:HI (umod:HI (match_dup 0)
                 (zero_extend:HI (match_dup 2)))
        (const_int 8 [0x8]))
    (udiv:HI (match_dup 0)
            (zero_extend:HI (match_dup 2))))

will generate extra QI->HI extend during split. This patch
uses subreg instead. Does it look OK?
Comment 7 H.J. Lu 2010-06-30 18:46:58 UTC
A patch is posted at

http://gcc.gnu.org/ml/gcc-patches/2010-06/msg03173.html
Comment 8 H.J. Lu 2010-07-01 17:46:51 UTC
The updated patch is at

http://gcc.gnu.org/ml/gcc-patches/2010-07/msg00076.html
Comment 9 H.J. Lu 2010-07-02 00:37:14 UTC
An updated patch is at

http://gcc.gnu.org/ml/gcc-patches/2010-07/msg00099.html
Comment 10 hjl@gcc.gnu.org 2010-07-04 23:18:20 UTC
Subject: Bug 44695

Author: hjl
Date: Sun Jul  4 23:18:06 2010
New Revision: 161813

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=161813
Log:
Change 8bit divmod to HImode.

gcc/

2010-07-04  H.J. Lu  <hongjiu.lu@intel.com>

	PR rtl-optimization/44695
	* config/i386/i386.md (extract_code): Removed.
	(<u>divmodqi4): Likewise.
	(divmodqi4): New.
	(udivmodqi4): Likewise.
	(divmodhiqi3): Change div/mod to HImode and extend operand 2 to
	HImode.
	(udivmodhiqi3): Likewise.

gcc/testsuite/

2010-07-04  H.J. Lu  <hongjiu.lu@intel.com>

	PR rtl-optimization/44695
	* gcc.dg/torture/pr44695.c: New.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr44695.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.md
    trunk/gcc/testsuite/ChangeLog

Comment 11 Jakub Jelinek 2010-07-05 12:21:43 UTC
Fixed.
Comment 12 hjl@gcc.gnu.org 2010-07-07 21:11:48 UTC
Subject: Bug 44695

Author: hjl
Date: Wed Jul  7 21:11:25 2010
New Revision: 161933

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=161933
Log:
Backport 8bit div/mod improvements.

gcc/

2010-07-07  H.J. Lu  <hongjiu.lu@intel.com>

	Backport from mainline
	2010-07-04  H.J. Lu  <hongjiu.lu@intel.com>

	PR rtl-optimization/44695
	* config/i386/i386.md (extract_code): Removed.
	(<u>divmodqi4): Likewise.
	(divmodqi4): New.
	(udivmodqi4): Likewise.
	(divmodhiqi3): Change div/mod to HImode and extend operand 2 to
	HImode.
	(udivmodhiqi3): Likewise.

	2010-06-24  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/44588
	* config/i386/i386.md (extract_code): New.
	(<u>divmodqi4): Likewise.
	(divmodhiqi3): Likewise.
	(udivmodhiqi3): Likewise.
	(<u>divqi3): Remvoved.

gcc/testsuite/

2010-07-07  H.J. Lu  <hongjiu.lu@intel.com>

	Backport from mainline
	2010-07-04  H.J. Lu  <hongjiu.lu@intel.com>

	PR rtl-optimization/44695
	* gcc.dg/torture/pr44695.c: New.

	2010-06-24  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/44588
	* gcc.target/i386/mod-1.c: New.
	* gcc.target/i386/umod-1.c: Likewise.
	* gcc.target/i386/umod-2.c: Likewise.
	* gcc.target/i386/umod-3.c: Likewise.

Modified:
    branches/ix86/gcc-4_5-branch/gcc/config/i386/i386.md