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

            Bug ID: 95636
           Summary: ICE in sched2: internal compiler error: in
                    create_block_for_bookkeeping, at sel-sched.c:4549
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: qianchao9 at huawei dot com
  Target Milestone: ---

There exists a ICE on AArch64 when using GCC11.

Compiling this with -fsel-sched-pipelining -fselective-scheduling2
-fvar-tracking-assignments -Os:

typedef long unsigned int size_t;
extern volatile int  chk_calls;
volatile char *s2 = "defg";
volatile size_t l1 = 1;
long buf1[64];
char *buf2 = (char *) (buf1 + 32);

void
__attribute__((noinline))
test3 (void)
{
  struct A { char buf1[10]; char buf2[10]; } a;
  char *r; 
  char buf3[20];
  int i;
  r = buf3;
  for (i = 0; i < 2; ++i)
    {
      if (i == l1 + 1)
 r = &a.buf1[1];
      else if (i == l1)
 r = &a.buf2[7];
      else if (i == l1 + 1)
 r = &buf3[5];
      else if (i == l1 + 2)
 r = &a.buf1[9];
    }
  __builtin___memcpy_chk (r, s2, l1, __builtin_object_size (r, 0));
  if (chk_calls != 5){
    abort ();
  }
}

gives:

during RTL pass: sched2
testcase.c:32:1: internal compiler error: in create_block_for_bookkeeping, at
sel-sched.c:4549
   32 | }
      | ^
0xd4e55b create_block_for_bookkeeping
        ../../gcc/sel-sched.c:4549
0xd4e55b find_place_for_bookkeeping
        ../../gcc/sel-sched.c:4686
0xd4e55b generate_bookkeeping_insn
        ../../gcc/sel-sched.c:4786
0xd4e55b move_op_at_first_insn
        ../../gcc/sel-sched.c:6063
0xd4eca7 code_motion_path_driver
        ../../gcc/sel-sched.c:6657
0xd4f123 code_motion_process_successors
        ../../gcc/sel-sched.c:6342
0xd4f123 code_motion_path_driver
        ../../gcc/sel-sched.c:6608
0xd4f123 code_motion_process_successors
        ../../gcc/sel-sched.c:6342
0xd4f123 code_motion_path_driver
        ../../gcc/sel-sched.c:6608
0xd4f123 code_motion_process_successors
        ../../gcc/sel-sched.c:6342
0xd4f123 code_motion_path_driver
        ../../gcc/sel-sched.c:6608
0xd4fd4b move_op
        ../../gcc/sel-sched.c:6702
0xd4fd4b move_exprs_to_boundary
        ../../gcc/sel-sched.c:5223
0xd4fd4b schedule_expr_on_boundary
        ../../gcc/sel-sched.c:5436
0xd53af7 fill_insns
        ../../gcc/sel-sched.c:5578
0xd55713 schedule_on_fences
        ../../gcc/sel-sched.c:7353
0xd55713 sel_sched_region_2
        ../../gcc/sel-sched.c:7491
0xd56743 sel_sched_region_1
        ../../gcc/sel-sched.c:7533
0xd57bf7 sel_sched_region(int)
        ../../gcc/sel-sched.c:7634
0xd5855f run_selective_scheduling()
        ../../gcc/sel-sched.c:7720


during sched2 pass, we get bb:

(code_label 181 191 180 15 11 (nil) [2 uses])
(note 180 181 194 15 [bb 15] NOTE_INSN_BASIC_BLOCK)
(debug_insn 194 180 193 15 (var_location:SI i (plus:SI (reg:SI 1 x1 [orig:103
ivtmp.11 ] [103])
        (const_int 1 [0x1]))) -1
     (nil))

gcc/cfgrtl.c (rtl_split_block) tries to splits that bb to 

(code_label 181 191 180 15 11 (nil) [2 uses])
(note 180 181 205 15 [bb 15] NOTE_INSN_BASIC_BLOCK)

and new_bb:

(note 205 180 194 20 [bb 20] NOTE_INSN_BASIC_BLOCK)
(debug_insn 194 205 204 20 (var_location:SI i (plus:SI (reg:SI 1 x1 [orig:103
ivtmp.11 ] [103])
        (const_int 1 [0x1]))) -1
     (nil))
(note 204 194 193 20 NOTE_INSN_DELETED)

Although new_bb contained only debug insns, we will swap the block numbers of
new_bb and single_succ(new_bb). So NOTE_INSN_DELETED note emited by
gcc/cfgrtl.c (rtl_split_block) is unnecessary here.

the following fixes the latent bug - we delete new_bb's NOTE_INSN_DELETED note

diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 80687fb5359..6dece11bf0c 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -9158,7 +9158,12 @@ sched_split_block_1 (basic_block first_bb, rtx after)
   /* sched_split_block emits note if *check == BB_END.  Probably it
      is better to rip that note off.  */

-  return e->dest;
+  basic_block new_bb = e->dest;
+  rtx_insn *last_insn = BB_END (e->dest);
+  if (NOTE_P (last_insn) && NOTE_KIND (last_insn) == NOTE_INSN_DELETED)
+    delete_insn (last_insn);
+
+  return new_bb;
 }


Bootstrap and tested on aarch64 platform. No new regression witnessed. 

Any suggestions?

Reply via email to