This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/51994] New: [4.6/4.7 Regression] git-1.7.8.3 miscompiled due to negative bitpos from get_inner_reference


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: unassigned@gcc.gnu.org
        ReportedBy: ubizjak@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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]