Bug 95314 - Sharing a local reference to a global variable in multiple functions results in location references block not in block tree
Summary: Sharing a local reference to a global variable in multiple functions results ...
Alias: None
Product: gcc
Classification: Unclassified
Component: jit (show other bugs)
Version: 10.1.0
: P3 normal
Target Milestone: ---
Assignee: David Malcolm
Depends on:
Reported: 2020-05-25 13:15 UTC by Antoni
Modified: 2020-05-27 18:36 UTC (History)
1 user (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2020-05-27 00:00:00

Non-reproducing attempt at a reproducer (764 bytes, text/plain)
2020-05-27 09:03 UTC, David Malcolm
Small example to reproduce the bug (874 bytes, text/x-csrc)
2020-05-27 12:35 UTC, Antoni

Note You need to log in before you can comment on or make changes to this bug.
Description Antoni 2020-05-25 13:15:26 UTC
If a create, in a function, a reference (with gcc_jit_lvalue_get_address) to a global and reuse this local reference in another function, it gives the following error:

libgccjit.so: error: location references block not in block tree
during IPA pass: *free_lang_data
libgccjit.so: error: verify_gimple failed
0x7f83924b35c9 verify_gimple_in_cfg(function*, bool)
0x7f839236a819 execute_function_todo
0x7f839236add7 do_per_function
0x7f839236b06b do_per_function
0x7f839236b06b execute_todo

I can try to make an example to reproduce this issue if needed.

Is that the expected behavior or should libgccjit gives a proper error?

(Recreating the reference in every function fix this issue.)

Comment 1 David Malcolm 2020-05-25 13:20:41 UTC
Thanks for reporting it; this sounds like a bug.

Please can you use attach a reproducer (e.g. using gcc_jit_context_dump_reproducer_to_file).

Looking at the backtrace, it looks like a bad interaction with inlining, FWIW.
Comment 2 Jakub Jelinek 2020-05-25 13:40:30 UTC
Generally, most of the trees (with some exceptions) aren't shareable and shouldn't be used by multiple different functions.  During gimplifications the function body is unshared, but not sure what the JIT FE does exactly.
Comment 3 David Malcolm 2020-05-25 14:17:46 UTC
Thanks Jakub, that sounds like the problem: I'm creating a tree per playback::rvalue (m_inner), and I need to unshare them.
Comment 4 Jakub Jelinek 2020-05-25 14:18:58 UTC
unshare_expr can handle that.
Comment 5 Antoni 2020-05-25 14:53:05 UTC
The reproducer generates a file where the function create_code only contains this:

  /* Replay of API calls for ctxt_0x7f8079128680.  */

So, no code is actually generated and thus, does not reproduce this issue.
Comment 6 David Malcolm 2020-05-25 15:57:31 UTC
Sorry about that; thanks for trying.  I think I can figure out a reproducer, and will try tomorrow.
Comment 7 David Malcolm 2020-05-27 09:03:34 UTC
Created attachment 48615 [details]
Non-reproducing attempt at a reproducer

I attempted to reproduce this, but was unsuccessful.  I'm attaching what I have so far (for gcc/testsuite/jit.dg), but annoyingly this runs successfully.
Comment 8 Antoni 2020-05-27 12:35:39 UTC
Created attachment 48617 [details]
Small example to reproduce the bug
Comment 9 Antoni 2020-05-27 12:36:02 UTC
Actually, it seems I was wrong on the conditions to reproduce this issue.
I managed to create a small example to reproduce the issue.
I attached it to the bug report.
Comment 10 David Malcolm 2020-05-27 12:54:18 UTC
Thanks; I'm seeing the crash with your reproducer.
Comment 11 CVS Commits 2020-05-27 18:30:18 UTC
The master branch has been updated by David Malcolm <dmalcolm@gcc.gnu.org>:


commit r11-668-gc98bd673ef93836f03491201f1c63929ea429cd6
Author: David Malcolm <dmalcolm@redhat.com>
Date:   Wed May 27 09:44:07 2020 -0400

    jit: use deep unsharing of trees [PR 95314]
    PR jit/95314 reports a internal error inside verify_gimple, which
    turned out to be due to reusing the result of
    gcc_jit_lvalue_get_address in several functions, leading to tree nodes
    shared between multiple function bodies.
    This patch fixes the issue by adopting the "Deep unsharing" strategy
    described in the comment in gimplify.c preceding mostly_copy_tree_r:
    to mark all of the jit "frontend"'s expression tree nodes with
    TREE_VISITED, and to set LANG_HOOKS_DEEP_UNSHARING, so that "they are
    unshared on the first reference within functions when the regular
    unsharing algorithm runs".
            PR jit/95314
            * dummy-frontend.c (LANG_HOOKS_DEEP_UNSHARING): Define to be true.
            * jit-playback.h (gcc::jit::playback::rvalue): Mark tree node with
            PR jit/95314
            * jit.dg/all-non-failing-tests.h: Add test-pr95314-rvalue-reuse.c.
            * jit.dg/test-pr95314-rvalue-reuse.c: New test.
Comment 12 David Malcolm 2020-05-27 18:36:40 UTC
Should be fixed by the above commit.