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

--- Comment #3 from Vineet Gupta <vineetg at gcc dot gnu.org> ---
However the first part of prev fix alone can't pass a glibc build - hitting
bunch of ICE.

Following reduced test (w/ my patch applied) actually segfaults 

build: -O2 -c -march=rv64gcv_zvl256b_zba_zbb_zbs_zicond -fexceptions

void a();
typedef struct {
  void *b;
} c;
void d(int **);
c e;
void f() {                      
    int *g __attribute__((cleanup(d)h);
    if (e.b )           
    {
       int i;
       __atomic_compare_exchange_n(&i, f, 1, 0, 2, 0);
       a();
    }
}

So we end up a bunch of BBs with calls and ensuing code_labels.

Entering mode_sw we have 11 BBs (max index 10), a new FRM read is created in
stack below:

  df_worklist_dataflow_doublequeue: n_basic_blocks 11 n_edges 12 count 11 (   
1)

  [uid 23] frm mode needed : Call 
  scanning new insn with uid = 64.
  changing bb of uid 65 from 6 to 11
    unscanned insn

  riscv_frm_mode_needed
    riscv_frm_emit_after_bb_end
      commit_edge_insertions  

However it seems to also create a new BB:

  commit_one_edge_insertion
    split_edge
       rtl_split_edge
         create_basic_block
          ...
            df_insn_change_bb

Which runs afoul of generic mode_sw whose bitmap vectors are sized for 11 BBs
and haven't been adjusted for this new one.

      for (i = 0; i < no_mode; i++)
        {
          int m = targetm.mode_switching.priority (entity_map[j], i);

          FOR_EACH_BB_FN (bb, cfun)
            {
              if (!bitmap_bit_p (transp_all, bb->index))    <-- bb->index 11 
                clear_mode_bit (transp[bb->index], j, m);  <-- segfault here

So I don't know if the general direction of fix is wrong or that we need to
make some adj to generic mode switch as well.

Reply via email to