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

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
With a x86_64-linux -> powerpc64-linux cross I can reproduce the hang on
./cc1 -quiet -O2 -m32 pr83985.c -nostdinc -mcpu=e300c3 -mtune=e300c3
but with x86_64-linux -> powerpc-linux cross it ICEs instead:
during RTL pass: sched2
pr83985.c: In function ‘jm’:
pr83985.c:23:1: internal compiler error: in df_lr_verify_solution_end, at
df-problems.c:1171
 }
 ^
0xa1321f df_lr_verify_solution_end
        ../../gcc/df-problems.c:1171
0xa0ce69 df_analyze_problem(dataflow*, bitmap_head*, int*, int)
        ../../gcc/df-core.c:1183
0x1c39be5 fast_dce
        ../../gcc/dce.c:1136
0x1c39c7d rest_of_handle_fast_dce
        ../../gcc/dce.c:1161
0x1c39d1e run_fast_df_dce()
        ../../gcc/dce.c:1209
0xa12c1c df_lr_finalize
        ../../gcc/df-problems.c:1017
0xa0ce46 df_analyze_problem(dataflow*, bitmap_head*, int*, int)
        ../../gcc/df-core.c:1179
0xa0cfde df_analyze_1
        ../../gcc/df-core.c:1227
0xa0d2ce df_analyze()
        ../../gcc/df-core.c:1289
1167            if ((!bitmap_equal_p (&problem_data->in[bb->index], DF_LR_IN
(bb)))
1168                || (!bitmap_equal_p (&problem_data->out[bb->index],
DF_LR_OUT (bb))))
1169              {
1170                /*df_dump (stderr);*/
1171                gcc_unreachable ();
1172              }

(gdb) p debug_bitmap (&problem_data->in[bb->index])

first = 0x2bcae78 current = 0x2bcae78 indx = 0
        0x2bcae78 next = (nil) prev = (nil) indx = 0
                bits = { 1 30 31 }
$5 = void
(gdb) p debug_bitmap (&df_lr_get_bb_info (6)->in)

first = 0x2bca770 current = 0x2bca770 indx = 0
        0x2bca770 next = (nil) prev = (nil) indx = 0
                bits = { 0 1 30 31 }
$6 = void
(gdb) p debug_bitmap (&problem_data->out[bb->index])

first = 0x2bca018 current = 0x2bca018 indx = 0
        0x2bca018 next = (nil) prev = (nil) indx = 0
                bits = { 1 3 4 30 31 75 }
$7 = void
(gdb) p debug_bitmap (&df_lr_get_bb_info (6)->out)

first = 0x2bca810 current = 0x2bca810 indx = 0
        0x2bca810 next = (nil) prev = (nil) indx = 0
                bits = { 0 1 3 4 30 31 75 }
$8 = void
so in both bitmaps reg 0 is different.

Looking at the dumps for anything related to reg 0, I see in *.dse2:
(insn/f 172 123 173 5 (set (reg:SI 0 0)
        (reg:SI 65 lr)) -1
     (expr_list:REG_DEAD (reg:SI 65 lr)
        (expr_list:REG_CFA_REGISTER (nil)
            (nil))))
(insn/f 173 172 138 5 (set (mem/c:SI (plus:SI (reg/f:SI 1 1)
                (const_int 36 [0x24])) [3  S4 A8])
        (reg:SI 0 0)) -1
     (expr_list:REG_DEAD (reg:SI 0 0)
        (expr_list:REG_CFA_OFFSET (set (mem/c:SI (plus:SI (reg/f:SI 1 1)
                        (const_int 36 [0x24])) [3  S4 A8])
                (reg:SI 65 lr))
            (nil))))
and
(insn/f 174 124 175 7 (set (reg:SI 0 0)
        (reg:SI 65 lr)) -1
     (expr_list:REG_DEAD (reg:SI 65 lr)
        (expr_list:REG_CFA_REGISTER (nil)
            (nil))))
(insn/f 175 174 140 7 (set (mem/c:SI (plus:SI (reg/f:SI 1 1)
                (const_int 36 [0x24])) [3  S4 A8])
        (reg:SI 0 0)) -1
     (expr_list:REG_DEAD (reg:SI 0 0)
        (expr_list:REG_CFA_OFFSET (set (mem/c:SI (plus:SI (reg/f:SI 1 1)
                        (const_int 36 [0x24])) [3  S4 A8])
                (reg:SI 65 lr))
            (nil))))
and
(insn 178 177 179 17 (set (reg:SI 0 0)
        (mem/c:SI (plus:SI (reg/f:SI 1 1)
                (const_int 36 [0x24])) [3  S4 A8])) -1
     (nil))
(insn/f 179 178 187 17 (set (reg:SI 65 lr)
        (reg:SI 0 0)) -1
     (expr_list:REG_DEAD (reg:SI 0 0)
        (expr_list:REG_UNUSED (reg:SI 65 lr)
            (expr_list:REG_CFA_RESTORE (reg:SI 65 lr)
                (nil)))))
and
(insn 181 180 182 18 (set (reg:SI 0 0)
        (mem/c:SI (plus:SI (reg/f:SI 1 1)
                (const_int 36 [0x24])) [3  S4 A8])) -1
     (nil))
(insn/f 182 181 83 18 (set (reg:SI 65 lr)
        (reg:SI 0 0)) -1
     (expr_list:REG_DEAD (reg:SI 0 0)
        (expr_list:REG_UNUSED (reg:SI 65 lr)
            (expr_list:REG_CFA_RESTORE (reg:SI 65 lr)
                (nil)))))
During jump2 the first two sequences are merged, which is fine, but also insn
179 and 181 are removed, extending the lifetime of the reg 0.  The REG_DEAD
remains on the insn 175 though (172/173 insns are gone) and the df out etc.
bitmaps aren't updated either until the sched2 pass when it calls df_analyze.

insn 178 and 181 are removed by:
#0  remove_insn (uncast_insn=0x7fffefe182c0) at ../../gcc/emit-rtl.c:4330
#1  0x000000000099b7bc in delete_insn (insn=0x7fffefe182c0) at
../../gcc/cfgrtl.c:170
#2  0x000000000099c097 in delete_insn_and_edges (insn=0x7fffefe182c0) at
../../gcc/cfgrtl.c:231
#3  0x0000000001c386d1 in delete_unmarked_insns () at ../../gcc/dce.c:618
#4  0x0000000001c39c1f in fast_dce (word_level=false) at ../../gcc/dce.c:1147
#5  0x0000000001c39c7e in rest_of_handle_fast_dce () at ../../gcc/dce.c:1161
#6  0x0000000001c39d46 in run_fast_dce () at ../../gcc/dce.c:1223
during jump2.

df_analyze is then called by
#0  df_analyze () at ../../gcc/df-core.c:1250
#1  0x0000000001b670e9 in try_optimize_cfg (mode=2) at
../../gcc/cfgcleanup.c:3001
#2  0x0000000001b675fc in cleanup_cfg (mode=2) at ../../gcc/cfgcleanup.c:3181
#3  0x0000000001b6786d in (anonymous namespace)::pass_jump2::execute
(this=0x2a18540) at ../../gcc/cfgcleanup.c:3310
#4  0x0000000000ed8f71 in execute_one_pass (pass=<opt_pass* 0x2a18540
"jump2"(294)>) at ../../gcc/passes.c:2497
#5  0x0000000000ed92c2 in execute_pass_list_1 (pass=<opt_pass* 0x2a18540
"jump2"(294)>) at ../../gcc/passes.c:2586
but doesn't notice that the live range of reg 0 has been so extended.

Reply via email to