regehr@john-home:~/volatile/tmp51$ current-gcc -O small.c small.c: In function ‘func_142’: small.c:15: internal compiler error: in smallest_mode_for_size, at stor-layout.c:219 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. regehr@john-home:~/volatile/tmp51$ current-gcc -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../configure --program-prefix=current- --enable-languages=c,c++ --prefix=/home/regehr Thread model: posix gcc version 4.4.0 20081027 (experimental) (GCC) regehr@john-home:~/volatile/tmp51$ cat small.c inline int rshift_u_s (unsigned int left, int right) { return left >> right; } char g_95; const int g_126 = 9L; int func_142 (int p_143, int p_144, int p_145, int p_146) { int l_152 = -1; if (lshift_u_u (func_26 (rshift_u_s (g_95 ^ l_152, g_126)), 1)); }
(gdb) up #1 0x08491138 in smallest_mode_for_size (size=4294967295, class=MODE_INT) at /home/richard/src/gcc-4_3-branch/gcc/stor-layout.c:219 219 gcc_unreachable (); #3 0x0898cb61 in make_compound_operation (x=0xb7caf300, in_code=COMPARE) at /home/richard/src/gcc-4_3-branch/gcc/combine.c:7030 7030 new = make_extraction (mode, new, (gdb) l 7025 && GET_CODE (lhs) == ASHIFT 7026 && GET_CODE (XEXP (lhs, 1)) == CONST_INT 7027 && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1))) 7028 { 7029 new = make_compound_operation (XEXP (lhs, 0), next_code); 7030 new = make_extraction (mode, new, 7031 INTVAL (rhs) - INTVAL (XEXP (lhs, 1)), 7032 NULL_RTX, mode_width - INTVAL (rhs), 7033 code == LSHIFTRT, 0, in_code == COMPARE); 7034 break; (gdb) call debug_rtx (rhs) (const_int 33 [0x21]) (gdb) call debug_rtx (lhs) (ashift:SI (subreg:SI (mem/c/i:QI (symbol_ref:SI ("g_95") <var_decl 0xb7c3c1b8 g_95>) [0 g_95+0 S1 A8]) 0) (const_int 24 [0x18]))
Reduced testcase: char a; int test (void) { int b = -1; return ((unsigned int) (a ^ b)) >> 9; }
I see at least 2 bugs. One is simplify_shift_const "optimizes" (lshiftrt:SI (xor:SI (ashiftrt:SI (ashift:SI (subreg:SI (mem/c/i:QI (symbol_ref:DI ("a") <var_decl 0x7ffff33f0820 a>) [0 a+0 S1 A8]) 0) (const_int 24 [0x18])) (const_int 24 [0x18])) (const_int -512 [0xfffffffffffffe00])) (const_int 9 [0x9])) into invalid: (and:SI (not:SI (ashiftrt:SI (ashift:SI (subreg:SI (mem/c/i:QI (symbol_ref:DI ("a") <var_decl 0x7ffff33f0820 a>) [0 a+0 S1 A8]) 0) (const_int 24 [0x18])) (const_int 33 [0x21]))) (const_int 8388607 [0x7fffff])) (it should IMHO never create a shift bigger than precision, as that has undefined behavior, while the original did not have one). The other bug is that make_compound_operation should && mode_width >= INTVAL (rhs), even if the user passes in undefined behavior code, GCC shouldn't ICE on it.
As an asside, I wonder why we don't optimize: D.1576_3 = (int) a.0_2; D.1577_4 = ~D.1576_3; D.1578_5 = (unsigned int) D.1577_4; Into just: D_1 = ~a.0_2; D_2 = (unsigned int)D_1; Like it is done for the case were we manually replace b with -1. Maybe this is a tree combiner issue again ...
Subject: Bug 37924 Author: jakub Date: Tue Oct 28 19:02:36 2008 New Revision: 141413 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141413 Log: PR c/37924 * combine.c (make_compound_operation): Don't call make_extraction with non-positive length. (simplify_shift_const_1): Canonicalize count even if complement_p. * gcc.c-torture/execute/pr37924.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/execute/pr37924.c Modified: trunk/gcc/ChangeLog trunk/gcc/combine.c trunk/gcc/testsuite/ChangeLog
Fixed in 4.4 so far.
Subject: Bug 37924 Author: jakub Date: Wed Nov 5 20:42:43 2008 New Revision: 141621 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141621 Log: PR c/37924 * combine.c (make_compound_operation): Don't call make_extraction with non-positive length. (simplify_shift_const_1): Canonicalize count even if complement_p. * gcc.c-torture/execute/pr37924.c: New test. Added: branches/gcc-4_3-branch/gcc/testsuite/gcc.c-torture/execute/pr37924.c Modified: branches/gcc-4_3-branch/gcc/ChangeLog branches/gcc-4_3-branch/gcc/combine.c branches/gcc-4_3-branch/gcc/testsuite/ChangeLog
Fixed on 4.3 branch as well.
Closing 4.2 branch, fixed for 4.3.3 and 4.4.