Bug 42896 - [4.5 Regression] Random debug generation differences, bootstrap fails
Summary: [4.5 Regression] Random debug generation differences, bootstrap fails
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.5.0
: P1 normal
Target Milestone: 4.5.0
Assignee: Alexandre Oliva
URL:
Keywords: build
Depends on:
Blocks:
 
Reported: 2010-01-29 13:10 UTC by Richard Biener
Modified: 2010-02-03 15:40 UTC (History)
3 users (show)

See Also:
Host:
Target: x86_64-*-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-01-29 16:43:04


Attachments
testcase (117.89 KB, application/octet-stream)
2010-01-29 14:00 UTC, Richard Biener
Details
gcc45-pr42896.patch (832 bytes, patch)
2010-01-29 15:00 UTC, Jakub Jelinek
Details | Diff
reduced testcase (3.45 KB, text/plain)
2010-01-29 16:26 UTC, Richard Biener
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2010-01-29 13:10:26 UTC
Configuring with --enable-languages=c --disable-multilib --without-build-config
bootstrap fails with

Comparing stages 2 and 3
warning: gcc/cc1-checksum.o differs
warning: gcc/cc1obj-checksum.o differs
warning: gcc/cc1plus-checksum.o differs
Bootstrap comparison failure!
gcc/dse.o differs
make[2]: *** [compare] Error 1

The difference happens randomly but always at the same place.  The difference
is in .debug_loc only, readelf -w differences are:

--- /tmp/t1     2010-01-29 14:06:09.000000000 +0100
+++ /tmp/t2     2010-01-29 14:06:14.000000000 +0100
@@ -29471,7 +29471,7 @@
 Raw dump of debug contents of section .debug_line:
 
   Offset:                      0x0
-  Length:                      4841
+  Length:                      4837
   DWARF Version:               2
   Prologue Length:             691
   Minimum Instruction Length:  1
@@ -30960,7 +30960,7 @@
   Extended opcode 4: set Discriminator to 1
   Set is_stmt to 0
   Special opcode 159: advance Address by 11 to 0x2412 and Line by 0 to 1384
-  Extended opcode 4: set Discriminator to 6
+  Extended opcode 4: set Discriminator to 3
   Special opcode 61: advance Address by 4 to 0x2416 and Line by 0 to 1384
   Set is_stmt to 1
   Advance Line by 217 to 1601
@@ -31171,7 +31171,7 @@
   Special opcode 132: advance Address by 9 to 0x297b and Line by 1 to 1350
   Special opcode 76: advance Address by 5 to 0x2980 and Line by 1 to 1351
   Special opcode 109: advance Address by 7 to 0x2987 and Line by 6 to 1357
-  Extended opcode 4: set Discriminator to 6
+  Extended opcode 4: set Discriminator to 3
   Special opcode 174: advance Address by 12 to 0x2993 and Line by 1 to 1358
   Special opcode 160: advance Address by 11 to 0x299e and Line by 1 to 1359
   Special opcode 202: advance Address by 14 to 0x29ac and Line by 1 to 1360
@@ -31181,12 +31181,10 @@
   Set is_stmt to 0
   Advance PC by constant 17 to 0x29cc
   Special opcode 89: advance Address by 6 to 0x29d2 and Line by 0 to 1374
-  Extended opcode 4: set Discriminator to 3
-  Special opcode 145: advance Address by 10 to 0x29dc and Line by 0 to 1374
   Set is_stmt to 1
   Advance Line by 195 to 1569
-  Advance PC by constant 17 to 0x29ed
-  Special opcode 173: advance Address by 12 to 0x29f9 and Line by 0 to 1569
+  Advance PC by 39 to 0x29f9
+  Copy
   Special opcode 76: advance Address by 5 to 0x29fe and Line by 1 to 1570
   Extended opcode 4: set Discriminator to 1
   Set is_stmt to 0
@@ -31240,7 +31238,7 @@
   Special opcode 6: advance Address by 0 to 0x2b78 and Line by 1 to 1434
   Advance Line by -912 to 522
   Special opcode 145: advance Address by 10 to 0x2b82 and Line by 0 to 522
-  Extended opcode 4: set Discriminator to 3
+  Extended opcode 4: set Discriminator to 1
   Advance Line by 930 to 1452
   Advance PC by constant 17 to 0x2b93
   Special opcode 201: advance Address by 14 to 0x2ba1 and Line by 0 to 1452
@@ -34190,10 +34188,10 @@
     0000778d 00000000000048b1 00000000000048bb (DW_OP_reg2)
     0000778d 00000000000048bb 000000000000490b (DW_OP_reg5)
     0000778d 0000000000004bfb 0000000000004c00 (DW_OP_reg5)
-    0000778d 0000000000004c00 0000000000004c04 (DW_OP_breg7: 32)
+    0000778d 0000000000004c00 0000000000004c04 (DW_OP_breg3: 24)
     0000778d 0000000000004c1f 0000000000004c32 (DW_OP_reg5)
     0000778d 0000000000004e01 0000000000004e1b (DW_OP_reg5)
-    0000778d 0000000000004e1b 0000000000004e1f (DW_OP_breg7: 32)
+    0000778d 0000000000004e1b 0000000000004e1f (DW_OP_breg3: 24)
     0000778d <End of list>
     00007837 0000000000004921 00000000000049c1 (DW_OP_reg13)
     00007837 00000000000049c1 00000000000049cb (DW_OP_reg13)


I now run into this regularly because contrib/compare-debug does not work
for me as the host compiler inserts a .comment.SUSE.OPT section whose
content depends on whether -g is specified or not.
Comment 1 Richard Biener 2010-01-29 13:51:50 UTC
r156291 is fine, r156292 is broken.
Comment 2 Richard Biener 2010-01-29 13:57:35 UTC
var-tracking dump difference:

--- dse.c.208r.vartrack.equal   2010-01-29 14:55:01.000000000 +0100
+++ dse.c.208r.vartrack.differs 2010-01-29 14:54:34.000000000 +0100
@@ -1889899,8 +1889899,8 @@
  (value/s/u:DI 44 @#/#)
     offset 0
       (reg:DI 5 di)
-      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
       (mem/s/f:DI (value/s/u:DI 4010 @#/#) [111 insn_info_26->read_rec+0 S8 A64
])
+      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
  (value/s/u:DI 40 @#/#)
     offset 0
       (mem/c:DI (value/s/u:DI 4015 @#/#) [134 %sfp+-88 S8 A64])
@@ -1890189,8 +1890189,8 @@
  (value/s/u:DI 44 @#/#)
     offset 0
       (reg:DI 5 di)
-      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
       (mem/s/f:DI (value/s/u:DI 4010 @#/#) [111 insn_info_26->read_rec+0 S8 A64
])
+      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
  (value/s/u:DI 40 @#/#)
     offset 0
       (mem/c:DI (value/s/u:DI 4015 @#/#) [134 %sfp+-88 S8 A64])
@@ -1890480,8 +1890480,8 @@
  (value/s/u:DI 44 @#/#)
     offset 0
       (reg:DI 5 di)
-      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
       (mem/s/f:DI (value/s/u:DI 4010 @#/#) [111 insn_info_26->read_rec+0 S8 A64
])
+      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
  (value/s/u:DI 40 @#/#)
     offset 0
       (mem/c:DI (value/s/u:DI 4015 @#/#) [134 %sfp+-88 S8 A64])
@@ -1890777,8 +1890777,8 @@
  (value/s/u:DI 44 @#/#)
     offset 0
       (reg:DI 5 di)
-      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
       (mem/s/f:DI (value/s/u:DI 4010 @#/#) [111 insn_info_26->read_rec+0 S8 A64
])
+      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
  (value/s/u:DI 40 @#/#)
     offset 0
       (mem/c:DI (value/s/u:DI 4015 @#/#) [134 %sfp+-88 S8 A64])
@@ -1891090,8 +1891090,8 @@
  (value/s/u:DI 44 @#/#)
     offset 0
       (reg:DI 5 di)
-      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
       (mem/s/f:DI (value/s/u:DI 4010 @#/#) [111 insn_info_26->read_rec+0 S8 A64
])
+      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
  (value/s/u:DI 4098 @#/#)
     offset 0
       (plus:DI (value/s/u:DI 42 @#/#)
@@ -1891392,8 +1891392,8 @@
  (value/s/u:DI 44 @#/#)
     offset 0
       (reg:DI 5 di)
-      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
       (mem/s/f:DI (value/s/u:DI 4010 @#/#) [111 insn_info_26->read_rec+0 S8 A64
])
+      (mem/c:DI (value/s/u:DI 4010 @#/#) [134 %sfp+-96 S8 A64])
  (value/s/u:DI 4098 @#/#)
     offset 0
       (plus:DI (value/s/u:DI 42 @#/#)
@@ -1891698,8 +1891698,8 @@

etc.

@@ -2077335,7 +2077335,9 @@
  into...
 expanding (value/s/u:DI 4010 @#/#)
  into...
-expanding (value/s/u:DI 42 @#/#)
+expanding (value/s/u:DI 50 @#/#)
+ into...
+expanding (value/s/u:DI 23 @#/#)
  into...
 expanding (value/s/u/f:DI 10 @#/#)
  into...
@@ -2077895,7 +2077897,9 @@
  into...
 expanding (value/s/u:DI 4010 @#/#)
  into...
-expanding (value/s/u:DI 42 @#/#)
+expanding (value/s/u:DI 50 @#/#)
+ into...
+expanding (value/s/u:DI 23 @#/#)
  into...
 expanding (value/s/u:DI 44 @#/#)
  into...
@@ -2080479,8 +2080483,8 @@
         (mem/c:DI (plus:DI (reg/f:DI 7 sp)
                 (const_int 48 [0x30])) [134 %sfp+-80 S8 A64])) 89 {*movdi_1_rex
64} (nil))
 
-(note 1296 190 1297 70 (var_location read_info (expr_list:REG_DEP_TRUE (mem/c:D
I (plus:DI (reg/f:DI 7 sp)
-            (const_int 32 [0x20])) [134 %sfp+-96 S8 A64])
+(note 1296 190 1297 70 (var_location read_info (expr_list:REG_DEP_TRUE (mem/s/f
:DI (plus:DI (reg/v/f:DI 3 bx [orig:83 insn_info ] [83])
+            (const_int 24 [0x18])) [111 insn_info_26->read_rec+0 S8 A64])
     (const_int 0 [0x0]))) NOTE_INSN_VAR_LOCATION)
 
 (note 1297 1296 191 70 (var_location mem (expr_list:REG_DEP_TRUE (reg/v/f:DI 6 
bp [orig:80 mem ] [80])
@@ -2081570,8 +2081574,8 @@
 (note 1389 173 1390 101 (var_location mem (expr_list:REG_DEP_TRUE (reg/v/f:DI 6
 bp [orig:80 mem ] [80])
     (const_int 0 [0x0]))) NOTE_INSN_VAR_LOCATION)
 
-(note 1390 1389 174 101 (var_location read_info (expr_list:REG_DEP_TRUE (mem/c:
DI (plus:DI (reg/f:DI 7 sp)
-            (const_int 32 [0x20])) [134 %sfp+-96 S8 A64])
+(note 1390 1389 174 101 (var_location read_info (expr_list:REG_DEP_TRUE (mem/s/
f:DI (plus:DI (reg/v/f:DI 3 bx [orig:83 insn_info ] [83])
+            (const_int 24 [0x18])) [111 insn_info_26->read_rec+0 S8 A64])
     (const_int 0 [0x0]))) NOTE_INSN_VAR_LOCATION)
 
 (call_insn:TI 174 1390 1391 101 ../../trunk/gcc/dse.c:522 (call (mem:QI (symbol
_ref:DI ("vec_assert_fail") [flags 0x41]  <function_decl # vec_assert_fail>) [0 
S1 A8])
Comment 3 Richard Biener 2010-01-29 14:00:34 UTC
Created attachment 19750 [details]
testcase

inside stage3/gcc:

obj/gcc> /abuild/rguenther/obj/./prev-gcc/cc1 -fpreprocessed dse.i -quiet -dumpbase dse.c -mtune=generic -auxbase-strip dse.o -g -O2 -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-format-attribute -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -Wold-style-definition -Wc++-compat -version -fno-common -o dse.s1
obj/gcc> /abuild/rguenther/obj/./prev-gcc/cc1 -fpreprocessed dse.i -quiet -dumpbase dse.c -mtune=generic -auxbase-strip dse.o -g -O2 -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-format-attribute -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -Wold-style-definition -Wc++-compat -version -fno-common -o dse.s2
obj/gcc> cmp dse.s1 dse.s2 
dse.s1 dse.s2 differ: char 285950, line 18387

--- dse.s1      2010-01-29 14:58:22.000000000 +0100
+++ dse.s2      2010-01-29 14:58:26.000000000 +0100
@@ -18384,8 +18384,8 @@
        .quad   .LVL1531-.Ltext0
        .quad   .LVL1532-1-.Ltext0
        .value  0x2
-       .byte   0x77
-       .sleb128 32
+       .byte   0x73
+       .sleb128 24
        .quad   .LVL1536-.Ltext0
        .quad   .LVL1538-.Ltext0
        .value  0x1
@@ -18397,8 +18397,8 @@
        .quad   .LVL1576-.Ltext0
        .quad   .LVL1577-1-.Ltext0
        .value  0x2
-       .byte   0x77
-       .sleb128 32
+       .byte   0x73
+       .sleb128 24
        .quad   0x0
        .quad   0x0
Comment 4 Richard Biener 2010-01-29 14:04:45 UTC
Needs randomized va-space to trigger.  My guess:

/* Determine a total order between two distinct pointers.  Compare the
   pointers as integral types if size_t is wide enough, otherwise
   resort to bitwise memory compare.  The actual order does not
   matter, we just need to be consistent, so endianness is
   irrelevant.  */

static int
tie_break_pointers (const void *p1, const void *p2)
{
  gcc_assert (p1 != p2);

  if (sizeof (size_t) >= sizeof (void*))
    return (size_t)p1 < (size_t)p2 ? -1 : 1;
  else
    return memcmp (&p1, &p2, sizeof (p1));
}
Comment 5 Jakub Jelinek 2010-01-29 15:00:12 UTC
Created attachment 19751 [details]
gcc45-pr42896.patch

Try this.  If we ever hit the assertion, some more patching will be needed to break the ties.
Comment 6 Richard Biener 2010-01-29 15:04:21 UTC
After fixing the typo it ICEs with the testcase:

../../trunk/gcc/dse.c: In function 'check_mem_read_rtx':
../../trunk/gcc/dse.c:2300:1: internal compiler error: in tie_break_values, at var-tracking.c:1179
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

which is

  if (!loc1)
    {
      gcc_assert (loc2);
Comment 7 Jakub Jelinek 2010-01-29 15:21:17 UTC
:(, there apparently are VALUEs without locs so we can't always compare this way.
Both the problematic VALUEs are created through
e = new_cselib_val (hashval, mode, x);
(the only place which doesn't assign VALUE values sequentially, but uses a hash.
Both
(plus:DI (reg/f:DI 7 sp)
    (const_int 32 [0x20]))
and
(plus:DI (reg/v/f:DI 3 bx [orig:83 insn_info ] [83])
    (const_int 24 [0x18]))
hash to the same value (and while having two values with the same hashval would be rejected inside of the same bb, it is not rejected inside of different bbs).

So the values are indeed for something completely different and thus must not be considered equal.  On 64-bit hosts we could at no cost add some sequential UID to the VALUEs next to value, but on 32-bit hosts it would enlarge the struct.
Comment 8 Richard Biener 2010-01-29 16:26:18 UTC
Created attachment 19752 [details]
reduced testcase
Comment 9 Jakub Jelinek 2010-01-29 16:43:04 UTC
In theory we could reuse the next_containing_mem field for a counter, as it isn't used for anything once cselib_preserve_only_values is called (and I believe canon_value_cmp is only ever used after vt_initialize phase finishes, i.e. all VALUEs have gone through cselib_preserve_only_values.  remove_useless_values could have a bool argument which cselib_preserve_only_values would set, then it would just set an int in union with next_containing_mem to a counter (incremented after each cselib_preserve_only_values call starting at cselib_init).
The trouble is how to teach GC not to walk next_containing_mem / this int (it isn't needed to walk next_containing_mem anyway, as all the VALUEs must be in the hash table anyway).
Comment 10 rguenther@suse.de 2010-01-29 17:17:49 UTC
Subject: Re:  [4.5 Regression] Random debug generation
 differences, bootstrap fails

On Fri, 29 Jan 2010, jakub at gcc dot gnu dot org wrote:

> ------- Comment #9 from jakub at gcc dot gnu dot org  2010-01-29 16:43 -------
> In theory we could reuse the next_containing_mem field for a counter, as it
> isn't used for anything once cselib_preserve_only_values is called (and I
> believe canon_value_cmp is only ever used after vt_initialize phase finishes,
> i.e. all VALUEs have gone through cselib_preserve_only_values. 
> remove_useless_values could have a bool argument which
> cselib_preserve_only_values would set, then it would just set an int in union
> with next_containing_mem to a counter (incremented after each
> cselib_preserve_only_values call starting at cselib_init).
> The trouble is how to teach GC not to walk next_containing_mem / this int (it
> isn't needed to walk next_containing_mem anyway, as all the VALUEs must be in
> the hash table anyway).

Or we could simply record the basic-block and use its index for 
tie-breaking?

Richard.
Comment 11 Alexandre Oliva 2010-01-30 09:13:57 UTC
Mine, patch posted.
Comment 12 Richard Biener 2010-02-03 15:00:49 UTC
Subject: Bug 42896

Author: rguenth
Date: Wed Feb  3 15:00:33 2010
New Revision: 156468

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156468
Log:
2010-02-03  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/42896
	* cselib.h (struct cselib_val_struct): Add uid.  Rename value to
	hash.
	(cselib_reset_table): Renamed from...
	(cselib_reset_table_with_next_value): ... this.
	(cselib_get_next_uid): Renamed from...
	(cselib_get_next_unknown_value): ... this.
	* cselib.c (next_uid): Renamed from...
	(next_unknown_value): ... this.
	(cselib_clear_table): Adjust.
	(cselib_reset_table): Adjust.  Renamed from...
	(cselib_reset_table_with_next_value): ... this.
	(cselib_get_next_uid): Adjust.  Renamed from...
	(cselib_get_next_unknown_value): ... this.
	(get_value_hash): Use hash.
	(cselib_hash_rtx): Likewise.
	(new_cselib_val): Adjust.  Set and dump uid.
	(cselib_lookup_mem): Pass next_uid as hash.
	(cselib_subst_to_values): Likewise.
	(cselib_log_lookup): Dump uid.
	(cselib_lookup): Pass next_uid as hash.  Adjust.
	(cselib_process_insn): Adjust.
	(cselib_init): Initialize next_uid.
	(cselib_finish): Adjust.
	(dump_cselib_table): Likewise.
	* dse.c (canon_address): Dump value uid.
	* print-rtl.c (print_rtx): Print value uid.
	* var-tracking.c (VARIABLE_HASH_VAL): Dropped.
	(dvuid): New type.
	(dv_uid): New function, sort of renamed from...
	(dv_htab_hash): ... this, reimplemented in terms of it and...
	(dv_uid2hash): ... this.  New.
	(variable_htab_eq): Drop excess assertions.
	(tie_break_pointers): Removed.
	(canon_value_cmp): Compare uids.
	(variable_post_merge_New_vals): Print uids.
	(vt_add_function_parameters): Adjust.
	(vt_initialize): Reset table.  Adjust.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cselib.c
    trunk/gcc/cselib.h
    trunk/gcc/dse.c
    trunk/gcc/print-rtl.c
    trunk/gcc/var-tracking.c

Comment 13 Richard Biener 2010-02-03 15:40:40 UTC
Fixed.