http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51994
Bug #: 51994 Summary: [4.6/4.7 Regression] git-1.7.8.3 miscompiled due to negative bitpos from get_inner_reference Classification: Unclassified Product: gcc Version: 4.6.3 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: tree-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: ubiz...@gmail.com Target: alpha-linux-gnu Created attachment 26457 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26457 preprocessed source git-1.7.8.3 is miscompiled [1] due to negative bit position returned from get_inner_reference. Start with following patch that ICEs for negative positions: --cut here-- Index: expr.c =================================================================== --- expr.c (revision 183510) +++ expr.c (working copy) @@ -6300,6 +6300,9 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbit *poffset = offset; } + /* Negative bit positions are not allowed. */ + gcc_assert (*pbitpos >= 0); + /* We can use BLKmode for a byte-aligned BLKmode bitfield. */ if (mode == VOIDmode && blkmode_bitfield --cut here-- Crosscompile attached config.i with -O2 for alpha-linux-gnu target: Breakpoint 1, fancy_abort (file=0x9b5378 "../../gcc-svn/branches/gcc-4_6-branch/gcc/expr.c", line=6304, function=0x9b6490 "get_inner_reference") at ../../gcc-svn/branches/gcc-4_6-branch/gcc/diagnostic.c:892 892 { (gdb) up #1 0x0000000000587234 in get_inner_reference (exp=0x2aaaaf2996e0, pbitsize=0x7fffffffc1b8, pbitpos=0x7fffffffc1b0, poffset=<value optimized out>, pmode=<value optimized out>, punsignedp=<value optimized out>, pvolatilep=0x7fffffffc1c4, keep_aligning=1 '\001') at ../../gcc-svn/branches/gcc-4_6-branch/gcc/expr.c:6304 6304 gcc_assert (*pbitpos >= 0); (gdb) p *pbitpos $2 = -8 (gdb) Negative bit positions should not be allowed. This is what happens with negative positions: #17 0x000000000057147b in adjust_address_1 (memref=0x2aaaaf8fd570, mode=QImode, offset=2305843009213693951, validate=1, adjust=<value optimized out>) at ../../gcc-svn/branches/gcc-4_6-branch/gcc/emit-rtl.c:2033 #18 0x000000000058156d in store_bit_field_1 (str_rtx=0x2aaaaf8fd570, bitsize=8, bitnum=18446744073709551608, fieldmode=<value optimized out>, value=0x2aaaae770500, fallback_p=<value optimized out>) at ../../gcc-svn/branches/gcc-4_6-branch/gcc/expmed.c:469 #19 0x00000000005817cf in store_bit_field (str_rtx=0x2aaaaf8f5fc0, bitsize=46912578215904, bitnum=46912559843392, fieldmode=370, value=0x7) at ../../gcc-svn/branches/gcc-4_6-branch/gcc/expmed.c:838 ---Type <return> to continue, or q <return> to quit--- #20 0x000000000059483b in store_field (target=0x2aaaaf8fd570, bitsize=8, bitpos=-8, mode=QImode, exp=0x2aaaaf29f3e8, type=<value optimized out>, alias_set=0, nontemporal=0 '\000') at ../../gcc-svn/branches/gcc-4_6-branch/gcc/expr.c:6056 #21 0x000000000058921a in expand_assignment (to=0x2aaaaf8ac6c0, from=0x2aaaaf29f3e8, nontemporal=0 '\000') at ../../gcc-svn/branches/gcc-4_6-branch/gcc/expr.c:4465 Please see frame #19. Kind of funny bitsizes and bitnums. To trigger this problem on attached config.i, please put a breakpoint on gen_ashldi3 and skip a couple of triggers, so operand2 is (const_int 61): Breakpoint 1, gen_ashldi3 (operand0=0x2aaaaf8f5fc0, operand1=0x2aaaaf8f5fe0, operand2=0x2aaaae770840) at insn-emit.c:429 429 { (gdb) p debug_rtx (operand2) (const_int 61 [0x3d]) The compiler falls apart at: (gdb) up #20 0x000000000059483b in store_field (target=0x2aaaaf8fd570, bitsize=8, bitpos=-8, mode=QImode, exp=0x2aaaaf29f3e8, type=<value optimized out>, alias_set=0, nontemporal=0 '\000') at ../../gcc-svn/branches/gcc-4_6-branch/gcc/expr.c:6056 6056 store_bit_field (target, bitsize, bitpos, mode, temp); (gdb) p bitpos $14 = -8 However, store_bit_field is declared as: void store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, enum machine_mode fieldmode, rtx value) Compilation goes down the drain from here. The problematic code is located in git_config_rename_section (see also [1]): 19765 output += offset + i; 19766 if (strlen(output) > 0) { <blanks> 19773 output -= 1; 19774 output[0] = '\t'; [1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=655518