Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad PhiC node placement/usage corrupts gc-preserve use #34247

Closed
KristofferC opened this issue Jan 3, 2020 · 4 comments · Fixed by #34379
Closed

Bad PhiC node placement/usage corrupts gc-preserve use #34247

KristofferC opened this issue Jan 3, 2020 · 4 comments · Fixed by #34379
Assignees
Milestone

Comments

@KristofferC
Copy link
Member

Report: https://github.com/maleadt/BasePkgEvalReports/blob/0bb12607c245153c8e7215788e580d43d7d2d51a/pkgeval-9bd498d_vs_2e6715c/logs/Strided/1.4.0-DEV-082f446f52.log

julia: /workspace/srcdir/src/codegen.cpp:4342: jl_cgval_t emit_expr(jl_codectx_t&, jl_value_t*, ssize_t): Assertion `token.V->getType()->isTokenTy()' failed.

signal (6): Aborted
in expression starting at /home/pkgeval/.julia/packages/Strided/qA9SM/test/runtests.jl:228
gsignal at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
abort at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x7f452283e399)
__assert_fail at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
emit_expr at /workspace/srcdir/src/codegen.cpp:4342
emit_ssaval_assign at /workspace/srcdir/src/codegen.cpp:3836
emit_stmtpos at /workspace/srcdir/src/codegen.cpp:4029 [inlined]
emit_function at /workspace/srcdir/src/codegen.cpp:6649
jl_compile_linfo at /workspace/srcdir/src/codegen.cpp:1257
jl_compile_method_internal at /workspace/srcdir/src/gf.c:1889
_jl_invoke at /workspace/srcdir/src/gf.c:2153 [inlined]
jl_invoke at /workspace/srcdir/src/gf.c:2165
jl_toplevel_eval_flex at /workspace/srcdir/src/toplevel.c:808
jl_parse_eval_all at /workspace/srcdir/src/ast.c:872
jl_load at /workspace/srcdir/src/toplevel.c:872
include at ./client.jl:439
_jl_invoke at /workspace/srcdir/src/gf.c:2144 [inlined]
jl_apply_generic at /workspace/srcdir/src/gf.c:2322
jl_apply at /workspace/srcdir/src/julia.h:1692 [inlined]
do_call at /workspace/srcdir/src/interpreter.c:369
eval_value at /workspace/srcdir/src/interpreter.c:458
eval_stmt_value at /workspace/srcdir/src/interpreter.c:409 [inlined]
eval_body at /workspace/srcdir/src/interpreter.c:817
jl_interpret_toplevel_thunk at /workspace/srcdir/src/interpreter.c:911
jl_toplevel_eval_flex at /workspace/srcdir/src/toplevel.c:814
jl_toplevel_eval_flex at /workspace/srcdir/src/toplevel.c:764
jl_toplevel_eval_in at /workspace/srcdir/src/toplevel.c:843
eval at ./boot.jl:331
_jl_invoke at /workspace/srcdir/src/gf.c:2144 [inlined]
jl_apply_generic at /workspace/srcdir/src/gf.c:2322
exec_options at ./client.jl:264
_start at ./client.jl:484
jfptr__start_2076.clone_1 at /opt/julia/lib/julia/sys.so (unknown line)
_jl_invoke at /workspace/srcdir/src/gf.c:2144 [inlined]
jl_apply_generic at /workspace/srcdir/src/gf.c:2322
jl_apply at /workspace/srcdir/ui/../src/julia.h:1692 [inlined]
true_main at /workspace/srcdir/ui/repl.c:96
main at /workspace/srcdir/ui/repl.c:217
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x4015e4)
Allocations: 585069033 (Pool: 584874239; Big: 194794); GC: 445
@KristofferC KristofferC added this to the 1.4 milestone Jan 3, 2020
@vtjnash
Copy link
Member

vtjnash commented Jan 3, 2020

How coincidental: this is a duplicate of #34229 that I opened the day before.

julia> function f(a)
         GC.@preserve a try
         catch
         end
       end
f (generic function with 1 method)

julia> f("")
julia: /data/vtjnash/julia/src/codegen.cpp:4358: jl_cgval_t emit_expr(jl_codectx_t&, jl_value_t*, ssize_t): Assertion `token.V->getType()->isTokenTy()' failed.

@vtjnash vtjnash changed the title AssertionError when testing Strided.jl Bad PhiC node placement/usage corrupts gc-preserve use Jan 3, 2020
@Keno
Copy link
Member

Keno commented Jan 11, 2020

I'm thinking the way to fix this would be to allow ssa uses across try/catch regions, coupled with an LLVM pass that either manually spills all state to the stack or outlines the body of the try/catch block.

@vtjnash
Copy link
Member

vtjnash commented Jan 11, 2020

Hm, yeah, I think yuyichao was exploring something like that in #24573, but I don't know how feasible that is. In theory, the C standard says that LLVM is supposed to be OK with any variable that isn't modified in the try block being correct afterwards, and we seemed to be mostly OK for some years with assuming that. I still hope that someday we could move to using the lower-cost and more correct invoke instruction handling though.

@maleadt
Copy link
Member

maleadt commented Jan 14, 2020

FWIW, bisected to cd92f60 (the upgrade to LLVM 8.0.1).

Keno added a commit that referenced this issue Jan 14, 2020
This fixes #34247 by changing the way gc preserve is lowered.
Instead of lowering it in a macro, lower it in the frontend.
This allows us to use an SSA value directly for the return token
of the gc begin expression. This bypasses the slot-renaming pass
of the compiler, thus preventing the compiler from trying to save
and restore the token. Of course, this kind of code would generally
not be legal (because it uses an SSA value outside of the regular
domination relation), but since this is a julia restriction, not
an LLVM restriction, we can simply exempt gc_begin tokens from this
particular validation. This works fine at the LLVM level also, because
it doesn't have this particular restriction. It also doesn't have
the same correctness problems as doing the same for non-token values,
as the tokens get lowered away by the try/catch lowering before reaching
the LLVM backend.
Keno added a commit that referenced this issue Jan 15, 2020
This fixes #34247 by changing the way gc preserve is lowered.
Instead of lowering it in a macro, lower it in the frontend.
This allows us to use an SSA value directly for the return token
of the gc begin expression. This bypasses the slot-renaming pass
of the compiler, thus preventing the compiler from trying to save
and restore the token. Of course, this kind of code would generally
not be legal (because it uses an SSA value outside of the regular
domination relation), but since this is a julia restriction, not
an LLVM restriction, we can simply exempt gc_begin tokens from this
particular validation. This works fine at the LLVM level also, because
it doesn't have this particular restriction. It also doesn't have
the same correctness problems as doing the same for non-token values,
as the tokens get lowered away by the try/catch lowering before reaching
the LLVM backend.
KristofferC pushed a commit that referenced this issue Jan 15, 2020
This fixes #34247 by changing the way gc preserve is lowered.
Instead of lowering it in a macro, lower it in the frontend.
This allows us to use an SSA value directly for the return token
of the gc begin expression. This bypasses the slot-renaming pass
of the compiler, thus preventing the compiler from trying to save
and restore the token. Of course, this kind of code would generally
not be legal (because it uses an SSA value outside of the regular
domination relation), but since this is a julia restriction, not
an LLVM restriction, we can simply exempt gc_begin tokens from this
particular validation. This works fine at the LLVM level also, because
it doesn't have this particular restriction. It also doesn't have
the same correctness problems as doing the same for non-token values,
as the tokens get lowered away by the try/catch lowering before reaching
the LLVM backend.

(cherry picked from commit 07a16d6)
KristofferC pushed a commit that referenced this issue Jan 15, 2020
This fixes #34247 by changing the way gc preserve is lowered.
Instead of lowering it in a macro, lower it in the frontend.
This allows us to use an SSA value directly for the return token
of the gc begin expression. This bypasses the slot-renaming pass
of the compiler, thus preventing the compiler from trying to save
and restore the token. Of course, this kind of code would generally
not be legal (because it uses an SSA value outside of the regular
domination relation), but since this is a julia restriction, not
an LLVM restriction, we can simply exempt gc_begin tokens from this
particular validation. This works fine at the LLVM level also, because
it doesn't have this particular restriction. It also doesn't have
the same correctness problems as doing the same for non-token values,
as the tokens get lowered away by the try/catch lowering before reaching
the LLVM backend.

(cherry picked from commit 07a16d6)
KristofferC pushed a commit that referenced this issue Jan 17, 2020
This fixes #34247 by changing the way gc preserve is lowered.
Instead of lowering it in a macro, lower it in the frontend.
This allows us to use an SSA value directly for the return token
of the gc begin expression. This bypasses the slot-renaming pass
of the compiler, thus preventing the compiler from trying to save
and restore the token. Of course, this kind of code would generally
not be legal (because it uses an SSA value outside of the regular
domination relation), but since this is a julia restriction, not
an LLVM restriction, we can simply exempt gc_begin tokens from this
particular validation. This works fine at the LLVM level also, because
it doesn't have this particular restriction. It also doesn't have
the same correctness problems as doing the same for non-token values,
as the tokens get lowered away by the try/catch lowering before reaching
the LLVM backend.

(cherry picked from commit 07a16d6)
KristofferC pushed a commit that referenced this issue Apr 11, 2020
This fixes #34247 by changing the way gc preserve is lowered.
Instead of lowering it in a macro, lower it in the frontend.
This allows us to use an SSA value directly for the return token
of the gc begin expression. This bypasses the slot-renaming pass
of the compiler, thus preventing the compiler from trying to save
and restore the token. Of course, this kind of code would generally
not be legal (because it uses an SSA value outside of the regular
domination relation), but since this is a julia restriction, not
an LLVM restriction, we can simply exempt gc_begin tokens from this
particular validation. This works fine at the LLVM level also, because
it doesn't have this particular restriction. It also doesn't have
the same correctness problems as doing the same for non-token values,
as the tokens get lowered away by the try/catch lowering before reaching
the LLVM backend.
BioTurboNick pushed a commit to BioTurboNick/julia that referenced this issue Apr 13, 2020
This fixes JuliaLang#34247 by changing the way gc preserve is lowered.
Instead of lowering it in a macro, lower it in the frontend.
This allows us to use an SSA value directly for the return token
of the gc begin expression. This bypasses the slot-renaming pass
of the compiler, thus preventing the compiler from trying to save
and restore the token. Of course, this kind of code would generally
not be legal (because it uses an SSA value outside of the regular
domination relation), but since this is a julia restriction, not
an LLVM restriction, we can simply exempt gc_begin tokens from this
particular validation. This works fine at the LLVM level also, because
it doesn't have this particular restriction. It also doesn't have
the same correctness problems as doing the same for non-token values,
as the tokens get lowered away by the try/catch lowering before reaching
the LLVM backend.

(cherry picked from commit 07a16d6)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants