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)))) { } }
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.
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
Created attachment 21033 [details] A patch This patch avoids ICE. But it probably isn't the right fix.
A patch is posted at http://gcc.gnu.org/ml/gcc-patches/2010-06/msg03033.html
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).
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?
A patch is posted at http://gcc.gnu.org/ml/gcc-patches/2010-06/msg03173.html
The updated patch is at http://gcc.gnu.org/ml/gcc-patches/2010-07/msg00076.html
An updated patch is at http://gcc.gnu.org/ml/gcc-patches/2010-07/msg00099.html
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
Fixed.
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