Commit 7190fac
Make late gc lower handle insertelement of alloca use. (#58637)
This was in DAECompiler.jl code found by @serenity4. He also mentioned
that writing up how one might go and fix a bug like this so i'll give a
quick writeup (this was a very simple bug so it might not be too
interesting)
The original crash which looked something like
> %19 = alloca [10 x i64], align 8
%155 = insertelement <4 x ptr> poison, ptr %19, i32 0
Unexpected instruction
> [898844] signal 6 (-6): Aborted
in expression starting at
/home/gbaraldi/DAECompiler.jl/test/reflection.jl:28
pthread_kill at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
gsignal at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
abort at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
RecursivelyVisit<llvm::IntrinsicInst,
LateLowerGCFrame::PlaceRootsAndUpdateCalls(llvm::ArrayRef<int>, int,
State&, std::map<llvm::Value*, std::pair<int, int>
>)::<lambda(llvm::AllocaInst*&)>::<lambda(llvm::Use&)> > at
/home/gbaraldi/julia4/src/llvm-late-gc-lowering.cpp:803
operator() at /home/gbaraldi/julia4/src/llvm-late-gc-lowering.cpp:2560
[inlined]
PlaceRootsAndUpdateCalls at
/home/gbaraldi/julia4/src/llvm-late-gc-lowering.cpp:2576
runOnFunction at
/home/gbaraldi/julia4/src/llvm-late-gc-lowering.cpp:2638
run at /home/gbaraldi/julia4/src/llvm-late-gc-lowering.cpp:2675
run at
/home/gbaraldi/julia4/usr/include/llvm/IR/PassManagerInternal.h:91
which means it was crashing inside of late-gc-lowering, so the first
thing I did was ran julia and the same test with LLVM_ASSERTIONS=1 and
FORCE_ASSERTIONS=1 to see if LLVM complained about a malformed module,
and both were fine. Next step was trying to get the failing code out for
inspection.
Easiest way is to do `export
JULIA_LLVM_ARGS="--print-before=LateLowerGCFrame --print-module-scope"`
and pipe the output to a file.
The file is huge, but since it's a crash in LLVM we know that the last
thing is what we want, and that gave me the IR I wanted.
To verify that this is failing I did `make -C src install-analysis-deps`
to install the LLVM machinery (opt...). That gets put in the `tools`
directory of a julia build. Then I checked if this crashed outside of
julia by doing
`./opt -load-pass-plugin=../lib/libjulia-codegen.dylib
--passes=LateLowerGCFrame -S test.ll -o tmp3.ll `. This is run from
inside the tools dir so your paths might vary (the -S is so LLVM doesn't
generate bitcode) and my code did crash, however it was over 500 lines
of IR which makes it harder to debug and to write a test.
Next step then is to minimize the crash by doing
[`llvm-reduce`](https://llvm.org/docs/CommandGuide/llvm-reduce.html)
over it (it's basically creduce but optimized for LLVM IR) which gave me
a 2 line reproducer (in this case apparently just having the
insertelement was enough for the pass to fail). One thing to be wary is
that llvm-reduce will usually make very weird code, so it might be
useful to modify the code slightly so it doesn't look odd (it will have
unreachable basic-blocks and such).
After the cleanup fixing the bug here wasn't interesting but this
doesn't apply generally. And also always transform your reduced IR into
a test to put in llvmpasses.
(cherry picked from commit 906d348)1 parent bf57afd commit 7190fac
File tree
2 files changed
+15
-1
lines changed- src
- test/llvmpasses
2 files changed
+15
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
778 | 778 | | |
779 | 779 | | |
780 | 780 | | |
781 | | - | |
| 781 | + | |
782 | 782 | | |
783 | 783 | | |
784 | 784 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
202 | 216 | | |
203 | 217 | | |
204 | 218 | | |
| |||
0 commit comments