[Bug jit/103562] Jitted code produces incorrect result when returning 3-member struct from internal function

dmalcolm at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Dec 10 18:13:05 GMT 2021


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

David Malcolm <dmalcolm at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED

--- Comment #5 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
Thanks for filing this bug, and for the investigation.

After a couple of hours debugging, I think I've found the discrepancy between
cc1 and libgccjit, and have a candidate fix.

When tree-inline.c:remap_gimple_stmt is called to remap the stmt:
   <retval> = *ptr_2(D);
cc1 returns:
   D.1989 = *ptr_2(D);
whereas libgccjit returns this (copy):
   <retval> = *ptr_2(D);

Putting a breakpoint on remap_gimple_op_r and singlestepping (in both cc1 and
libgccjit, side by side) shows the discrepancy happens in
tree-inline.c:remap_gimple_op_r here:

   1036   else if (auto_var_in_fn_p (*tp, fn))

For cc1:

   (gdb) p auto_var_in_fn_p (*tp, fn)
   $28 = true

whereas for libgccjit:

   (gdb) p auto_var_in_fn_p (*tp, fn)
   $19 = false

and so libgccjit erroneously skips the remapping of locals vars and labels.

This turns out to be because the RESULT_DECL has a non-NULL DECL_CONTEXT in
cc1, set here by the C frontend:

(gdb) bt
#0  finish_function (end_loc=248384) at ../../src/gcc/c/c-decl.c:10271
#1  0x00000000009db5f7 in c_parser_declaration_or_fndef (parser=0x7ffff7ffbbd0,
fndef_ok=true, static_assert_ok=true, empty_ok=true, nested=false, 
    start_attr_ok=true, objc_foreach_object_declaration=0x0,
omp_declare_simd_clauses=0x0, have_attrs=false, attrs=<tree 0x0>, 
    oacc_routine_data=0x0, fallthru_attr_p=0x0) at
../../src/gcc/c/c-parser.c:2563
#2  0x00000000009d9925 in c_parser_external_declaration (parser=0x7ffff7ffbbd0)
at ../../src/gcc/c/c-parser.c:1779
#3  0x00000000009d941d in c_parser_translation_unit (parser=0x7ffff7ffbbd0) at
../../src/gcc/c/c-parser.c:1652
#4  0x0000000000a21267 in c_parse_file () at ../../src/gcc/c/c-parser.c:23280
#5  0x0000000000abd0ab in c_common_parse_file () at
../../src/gcc/c-family/c-opts.c:1238
#6  0x00000000010cab1a in compile_file () at ../../src/gcc/toplev.c:452
#7  0x000000000093eb7a in do_compile (no_backend=false) at
../../src/gcc/toplev.c:2156
#8  toplev::main (this=0x7fffffffde1a, argc=<optimized out>, argv=<optimized
out>) at ../../src/gcc/toplev.c:2308
#9  0x000000000270339d in main (argc=24, argv=0x7fffffffdf28) at
../../src/gcc/main.c:39
(gdb) list
10266     /* Must mark the RESULT_DECL as being in this function.  */
10267   
10268     if (DECL_RESULT (fndecl) && DECL_RESULT (fndecl) != error_mark_node)
10269       DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;

whereas the RESULT_DECL has NULL for its DECL_CONTEXT.


On trying this patch:

--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -473,6 +473,7 @@ new_function (location *loc,
   DECL_ARTIFICIAL (resdecl) = 1;
   DECL_IGNORED_P (resdecl) = 1;
   DECL_RESULT (fndecl) = resdecl;
+  DECL_CONTEXT (resdecl) = fndecl;

   if (builtin_id)
     {

then remap_gimple_stmt in libgccjit correctly remaps the stmt to:

(gdb) call debug ($21)
D.88 = *ptr_2(D);

and I correctly get this output from the libgccjit testcase:

get_a(&s) is 1

i.e. the above patch seems to fix it.

I'm running some more thorough tests.


More information about the Gcc-bugs mailing list