https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88317

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2018-12-04
                 CC|                            |rguenth at gcc dot gnu.org,
                   |                            |vmakarov at gcc dot gnu.org
            Version|unknown                     |9.0
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed.  Running via valgrind makes it succeed (eh).

So, the bitmap element in check_only_regs (global static regset) is corrupted,
it receives the broken value via setting a bit in scratch_operand_bitmap
(likewise global static regset):


Hardware watchpoint 5: *$17

Old value = (bitmap_element *) 0x0
New value = (bitmap_element *) 0x1000000000000
bitmap_set_bit (head=head@entry=0x23db920 <scratch_operand_bitmap>, 
    bit=<optimized out>) at /space/rguenther/src/svn/trunk2/gcc/bitmap.c:947
947       if (!head->tree_form)
#0  bitmap_set_bit (head=head@entry=0x23db920 <scratch_operand_bitmap>, 
    bit=<optimized out>) at /space/rguenther/src/svn/trunk2/gcc/bitmap.c:947
#1  0x0000000000beff37 in lra_register_new_scratch_op (
    insn=insn@entry=0x7ffff6632940, nop=nop@entry=0)
    at /space/rguenther/src/svn/trunk2/gcc/lra.c:2071
#2  0x0000000000bf0481 in remove_scratches ()
    at /space/rguenther/src/svn/trunk2/gcc/lra.c:2105
#3  lra (f=<optimized out>) at /space/rguenther/src/svn/trunk2/gcc/lra.c:2407
#4  0x0000000000ba3ada in do_reload ()
    at /space/rguenther/src/svn/trunk2/gcc/ira.c:5469
#5  (anonymous namespace)::pass_reload::execute (this=<optimized out>)
    at /space/rguenther/src/svn/trunk2/gcc/ira.c:5653
#6  0x0000000000cb46e2 in execute_one_pass (
    pass=pass@entry=<opt_pass* 0x2530630 "reload"(283)>)
    at /space/rguenther/src/svn/trunk2/gcc/passes.c:2483
#7  0x0000000000cb4f98 in execute_pass_list_1 (
    pass=<opt_pass* 0x2530630 "reload"(283)>)
    at /space/rguenther/src/svn/trunk2/gcc/passes.c:2569
#8  0x0000000000cb4faa in execute_pass_list_1 (
    pass=<opt_pass* 0x252f470 "*rest_of_compilation"(-1)>)
    at /space/rguenther/src/svn/trunk2/gcc/passes.c:2570
#9  0x0000000000cb4ff5 in execute_pass_list (fn=0x7ffff67b20b0, 
    pass=<optimized out>) at /space/rguenther/src/svn/trunk2/gcc/passes.c:2580

Program received signal SIGSEGV, Segmentation fault.
bitmap_list_link_element (element=0x32c6238, head=0x23de360 <check_only_regs>)
    at /space/rguenther/src/svn/trunk2/gcc/bitmap.c:212
212                ptr->prev != 0 && ptr->prev->indx > indx;
(gdb) p *head->first
$18 = {next = 0x32c6260, prev = 0x1000000000000, indx = 40341960, bits = {0, 
    576460752303423490}}
#0  bitmap_list_link_element (element=0x32c6238, 
    head=0x23de360 <check_only_regs>)
    at /space/rguenther/src/svn/trunk2/gcc/bitmap.c:212
#1  bitmap_set_bit (head=head@entry=0x23de360 <check_only_regs>, 
    bit=bit@entry=1) at /space/rguenther/src/svn/trunk2/gcc/bitmap.c:948
#2  0x0000000000bfa38e in split_reg (before_p=before_p@entry=true, 
    original_regno=original_regno@entry=1, insn=insn@entry=0x7ffff606ee00, 
    next_usage_insns=next_usage_insns@entry=0x0, to=to@entry=0x7ffff5f3a380)
    at /space/rguenther/src/svn/trunk2/gcc/lra-constraints.c:5656
#3  0x0000000000bfc2a4 in spill_hard_reg_in_range (regno=regno@entry=25575, 
    rclass=rclass@entry=DREG, from=from@entry=0x7ffff606ee00, 
    to=0x7ffff5f3a380)
    at /space/rguenther/src/svn/trunk2/gcc/lra-constraints.c:5764
#4  0x0000000000bf64b9 in lra_split_hard_reg_for ()
    at /space/rguenther/src/svn/trunk2/gcc/lra-assigns.c:1765
#5  0x0000000000bf08a7 in lra (f=<optimized out>)
    at /space/rguenther/src/svn/trunk2/gcc/lra.c:2533
#6  0x0000000000ba3ada in do_reload ()
    at /space/rguenther/src/svn/trunk2/gcc/ira.c:5469
#7  (anonymous namespace)::pass_reload::execute (this=<optimized out>)
    at /space/rguenther/src/svn/trunk2/gcc/ira.c:5653
#8  0x0000000000cb46e2 in execute_one_pass (
    pass=pass@entry=<opt_pass* 0x2530630 "reload"(283)>)
#9  0x0000000000cb4f98 in execute_pass_list_1 (
    pass=<opt_pass* 0x2530630 "reload"(283)>)
    at /space/rguenther/src/svn/trunk2/gcc/passes.c:2569
#10 0x0000000000cb4faa in execute_pass_list_1 (
    pass=<opt_pass* 0x252f470 "*rest_of_compilation"(-1)>)
    at /space/rguenther/src/svn/trunk2/gcc/passes.c:2570
#11 0x0000000000cb4ff5 in execute_pass_list (fn=0x7ffff67b20b0, 
    pass=<optimized out>) at /space/rguenther/src/svn/trunk2/gcc/passes.c:2580

the odd thing is that the bitmaps do not share an element but the "shared"
elements even overlap partially.

Breakpoint 6, bitmap_obstack_release (bit_obstack=0x23289a0 <reg_obstack>)
    at /space/rguenther/src/svn/trunk2/gcc/bitmap.c:732
732       if (!bit_obstack)
(gdb) p check_only_regs
$33 = {indx = 0, tree_form = false, first = 0x2679728, current = 0x2679728, 
  obstack = 0x23289a0 <reg_obstack>}
(gdb) p check_only_regs->first
$34 = (bitmap_element *) 0x2679728
(gdb) p *check_only_regs->first
$35 = {next = 0x0, prev = 0x0, indx = 0, bits = {4, 576460752303423488}}

so check_only_regs is _not_ cleared when we release its obstack!

This happens through lra_split_hard_reg_for calling into
spill_hard_reg_in_range:

#0  0x0000000000881f19 in bitmap_list_link_element (element=0x2679728, 
    head=0x23de360 <check_only_regs>)
    at /space/rguenther/src/svn/trunk2/gcc/bitmap.c:204
#1  bitmap_set_bit (head=head@entry=0x23de360 <check_only_regs>, 
    bit=bit@entry=123) at /space/rguenther/src/svn/trunk2/gcc/bitmap.c:948
#2  0x0000000000bfa380 in split_reg (before_p=before_p@entry=true, 
    original_regno=original_regno@entry=2, insn=insn@entry=0x7ffff6487000, 
    next_usage_insns=next_usage_insns@entry=0x0, to=to@entry=0x7ffff6678740)
    at /space/rguenther/src/svn/trunk2/gcc/lra-constraints.c:5655
#3  0x0000000000bfc2a4 in spill_hard_reg_in_range (regno=regno@entry=121, 
    rclass=rclass@entry=CREG, from=from@entry=0x7ffff6487000, 
    to=0x7ffff6678740)
    at /space/rguenther/src/svn/trunk2/gcc/lra-constraints.c:5764
#4  0x0000000000bf64b9 in lra_split_hard_reg_for ()
    at /space/rguenther/src/svn/trunk2/gcc/lra-assigns.c:1765
#5  0x0000000000bf08a7 in lra (f=<optimized out>)
    at /space/rguenther/src/svn/trunk2/gcc/lra.c:2533
#6  0x0000000000ba3ada in do_reload ()
    at /space/rguenther/src/svn/trunk2/gcc/ira.c:5469

which is the problem.  Only bitmap alterations through lra_inheritance ()
are properly protected.

I believe we want to replace bitmap_initialize (&...); ... bitmap_clear (&...);
patterns with clearing that poisons the obstack member so we do not run
into this kind of problem silently.

Vlad - can you look into the above?  There's also lra_split_regs set
(and maybe others) which will have similar problems.  The following should
make it easier to debug:

diff --git a/gcc/bitmap.h b/gcc/bitmap.h
index 9a180daa745..98f7b50b18b 100644
--- a/gcc/bitmap.h
+++ b/gcc/bitmap.h
@@ -441,6 +441,15 @@ bitmap_initialize (bitmap head, bitmap_obstack *obstack
CXX
_MEM_STAT_INFO)
     bitmap_register (head PASS_MEM_STAT);
 }

+/* Release a bitmap header.  */
+
+static inline void
+bitmap_release (bitmap head)
+{
+  bitmap_clear (head);
+  head->obstack = (bitmap_obstack *)0xdeadbeef;
+}
+
 /* Allocate and free bitmaps from obstack, malloc and gc'd memory.  */
 extern bitmap bitmap_alloc (bitmap_obstack *obstack CXX_MEM_STAT_INFO);
 #define BITMAP_ALLOC bitmap_alloc
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 04a90723aab..8bf33d4771e 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -6647,11 +6647,11 @@ lra_inheritance (void)
           inherit_in_ebb.  */
        update_ebb_live_info (BB_HEAD (start_bb), BB_END (bb));
     }
-  bitmap_clear (&ebb_global_regs);
-  bitmap_clear (&temp_bitmap);
-  bitmap_clear (&live_regs);
-  bitmap_clear (&invalid_invariant_regs);
-  bitmap_clear (&check_only_regs);
+  bitmap_release (&ebb_global_regs);
+  bitmap_release (&temp_bitmap);
+  bitmap_release (&live_regs);
+  bitmap_release (&invalid_invariant_regs);
+  bitmap_release (&check_only_regs);
   free (usage_insns);

   timevar_pop (TV_LRA_INHERITANCE);


The call to spill_hard_reg_in_range has been introduced with r258602.  Note
that if the call happens before the first call to lra_inheritance then
the bitmap will appear to be GC managed...

Reply via email to