This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR 64722: fix corruption of %ebx on 32-bit i386 with libgccjit
- From: David Malcolm <dmalcolm at redhat dot com>
- To: jit at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Cc: David Malcolm <dmalcolm at redhat dot com>
- Date: Thu, 22 Jan 2015 12:34:37 -0500
- Subject: [PATCH] PR 64722: fix corruption of %ebx on 32-bit i386 with libgccjit
- Authentication-results: sourceware.org; auth=none
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