Much of the jit testsuite currently segfaults on i686, after two in-process iterations. In odd-numbered iterations, gcc_jit_context_compile generates correct code, but on even-numbered iterations, the generated code trashes the %ebx register, leading to SIGSEGV back at the call site when setting up iteration 3.
The root cause is due to missing state cleanup when repeatedly invoking the compiler in-process. The issue manifests in emit-rtl.c:init_emit_regs, at this initialization: if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); else pic_offset_table_rtx = NULL_RTX; On 32-bit i386 fPIC the definition PIC_OFFSET_TABLE_REGNUM itself depends on pic_offset_table_rtx, and hence the above initialization code cycles between switching pic_offset_table_rtx from NULL to non-NULL (on odd-numbered iterations), then switching it back from non-NULL to NULL (on even-numbered iterations). In the latter case, this leads to generated code that's supposedly "fPIC", but erroneously doesn't bother saving %ebx. The simple fix is to set pic_offset_table_rtx to NULL_RTX before testing PIC_OFFSET_TABLE_REGNUM (and thus making the else clause redundant). A more involved fix might be for the JIT to only initialize RTL once, but doing so seems higher risk. Tested with "make check-jit" on i686; with this, all testcases pass (with the usual 5 in-process iterations). Bootstrap®rtest in progress. OK for trunk if it passes? gcc/ChangeLog: PR 64722 * emit-rtl.c (init_emit_regs): Set pic_offset_table_rtx to NULL_RTX before testing PIC_OFFSET_TABLE_REGNUM, since the latter may be affected by the former (e.g. on i686). --- gcc/emit-rtl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index df85366..483eacb 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -5872,10 +5872,9 @@ init_emit_regs (void) = gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM); #endif + pic_offset_table_rtx = NULL_RTX; if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); - else - pic_offset_table_rtx = NULL_RTX; for (i = 0; i < (int) MAX_MACHINE_MODE; i++) { -- 1.8.5.3