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.