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

--- Comment #10 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
Notes to self on how I debugged this:
I added the following to harness.h:
  gcc_jit_context_set_bool_option (
    ctxt,
    GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING,
    1);
  gcc_jit_context_set_bool_option (
    ctxt,
    GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
    1);
thus populating each iteration's tempdir with logfiles (and turned off
optimizations).

Rename the tempdirs to iteration-1 and iteration-2 for the sake of sanity.

Diffing the logfiles:
  (for f in $(ls /tmp/iteration-1); do
      diff -up /tmp/iteration-1/$f /tmp/iteration-2/$f;
   done) | less
showed the first significant difference appears
in fake.c.234r.pro_and_epilogue:
--- /tmp/iteration-1/fake.c.234r.pro_and_epilogue       2015-01-22
03:31:55.243746546 -0500
+++ /tmp/iteration-2/fake.c.234r.pro_and_epilogue       2015-01-22
03:31:55.315744888 -0500
@@ -28,11 +26,11 @@ Dataflow summary:
 ;;  hardware regs used          7 [sp]
 ;;  regular block artificial uses       6 [bp] 7 [sp]
 ;;  eh block artificial uses    6 [bp] 7 [sp] 16 [argp] 20 [frame]
-;;  entry block defs    0 [ax] 1 [dx] 2 [cx] 3 [bx] 6 [bp] 7 [sp] 20 [frame]
+;;  entry block defs    0 [ax] 1 [dx] 2 [cx] 6 [bp] 7 [sp] 20 [frame]

i.e. "3 [bx]" no longer appears in entry block defs in iteration 2.

and it's in this dump that the RTL diverged; previous pass dumps show use a
use of bx in the call_insn, but this dump shows the save/restore
of ebx in iteration 1's code, and *not* in iteration 2's.

I put a breakpoint on emit_insn to find where the save insns are emitted:
Breakpoint 12, emit_insn (x=0xf653e900) at ../../src/gcc/emit-rtl.c:4922
4922    {
(gdb) call debug(x)
(set (mem:SI (pre_dec:SI (reg/f:SI 7 sp)) [0  S4 A8])
    (reg:SI 3 bx))
(gdb) bt
#0  emit_insn (x=0xf653e900) at ../../src/gcc/emit-rtl.c:4922
#1  0xf74d2744 in ix86_emit_save_regs () at
../../src/gcc/config/i386/i386.c:10282
#2  ix86_expand_prologue () at ../../src/gcc/config/i386/i386.c:11398
#3  0xf75bd6fa in gen_prologue () at ../../src/gcc/config/i386/i386.md:12187
#4  0xf7027836 in thread_prologue_and_epilogue_insns () at
../../src/gcc/function.c:5929
#5  0xf70280a5 in rest_of_handle_thread_prologue_and_epilogue () at
../../src/gcc/function.c:6499
#6  (anonymous namespace)::pass_thread_prologue_and_epilogue::execute
(this=0x8074610) at ../../src/gcc/function.c:6537
#7  0xf71a6ac5 in execute_one_pass (pass=0x8074610) at
../../src/gcc/passes.c:2326
#8  0xf71a6f57 in execute_pass_list_1 (pass=0x8074610) at
../../src/gcc/passes.c:2378
#9  0xf71a6f6a in execute_pass_list_1 (pass=0x8074450) at
../../src/gcc/passes.c:2379
#10 0xf71a6f6a in execute_pass_list_1 (pass=0x8073910, pass@entry=0x80717d0) at
../../src/gcc/passes.c:2379
#11 0xf71a6fc3 in execute_pass_list (fn=0xf6527064, pass=0x80717d0) at
../../src/gcc/passes.c:2389
#12 0xf6f338e0 in cgraph_node::expand (this=0xf65261c8) at
../../src/gcc/cgraphunit.c:1804
#13 0xf6f34517 in output_in_order (no_reorder=no_reorder@entry=false) at
../../src/gcc/cgraphunit.c:2042
#14 0xf6f3491d in symbol_table::compile (this=0xf6527000) at
../../src/gcc/cgraphunit.c:2287
#15 0xf6f362d9 in symbol_table::finalize_compilation_unit (this=0xf6527000) at
../../src/gcc/cgraphunit.c:2370
#16 0xf6eadcad in jit_langhook_write_globals () at
../../src/gcc/jit/dummy-frontend.c:231
#17 0xf725c098 in compile_file () at ../../src/gcc/toplev.c:606
#18 0xf6eaa4ac in do_compile () at ../../src/gcc/toplev.c:2048
#19 toplev::main (this=0xffffd4c7, argc=12, argv=0x804e918) at
../../src/gcc/toplev.c:2145
#20 0xf6ec7c43 in gcc::jit::playback::context::compile (this=0xffffd52c) at
../../src/gcc/jit/jit-playback.c:1721
#21 0xf6ec03c1 in gcc::jit::recording::context::compile (this=0x804d008) at
../../src/gcc/jit/jit-recording.c:1175
#22 0xf6eb5d7c in gcc_jit_context_compile (ctxt=0x804d008) at
../../src/gcc/jit/libgccjit.c:2201
#23 0x08049bd0 in test_jit (argv0=0xffffd7ea
"/root/gcc-git-jit/build-jit/gcc/testsuite/jit/test-hello-world.c.exe", 
    user_data=0x0) at /root/gcc-git-jit/src/gcc/testsuite/jit.dg/harness.h:352
#24 0x08049cc8 in main (argc=1, argv=0xffffd6b4) at
/root/gcc-git-jit/src/gcc/testsuite/jit.dg/harness.h:397

This revealed that ix86_emit_save_regs is only being called on
iteration 1, not on iteration 2.

Debugging ix86_expand_prologue showed differences in "frame":
                      iter 1   iter 2
nregs               = 1        0
reg_save_offset     = 8        12
sse_reg_save_offset = 12       8

In particular, nregs = 1 on iter1, but is 0 on iter2

nregs is computed in ix86_nsaved_regs (void)
  which loops over regno for real non-SSE registers calling:
    ix86_save_reg (unsigned int regno, bool maybe_eh_return)

within ix86_expand_prologue:
On iteration 1:
(gdb) p this_target_hard_regs->x_call_used_regs[3]
$42 = 0 '\000'
(gdb) p this_target_hard_regs->x_fixed_regs[3]
$43 = 0 '\000'
(gdb) p regs_ever_live[3]
$44 = true

On iteration 2:
(gdb) p this_target_hard_regs->x_call_used_regs[3]
$46 = 1 '\001'
(gdb) p this_target_hard_regs->x_fixed_regs[3]
$47 = 1 '\001'
(gdb) p regs_ever_live[3]
$48 = true

which led to investigating this code in ix86_conditional_register_usage:
4394  j = PIC_OFFSET_TABLE_REGNUM;
4395  if (j != INVALID_REGNUM)
4396    fixed_regs[j] = call_used_regs[j] = 1;
and line 4396 is bizarrely only called on the 2nd iteration, not the 1st,
which led me to investigate "PIC_OFFSET_TABLE_REGNUM", and discover what
appears to be the root cause, as described in comment #1.

Reply via email to