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
Compiler crash in ponyc 0.28.0 with LLVM 7+ for certain projects #3140
Comments
Removing the make parameters here does not solve the issue. |
ponyc in the Dockerfile is built using the release llvm from releases.llvm.org. |
This might be related to #3126 ? |
Probably not. They crash on different compilation steps ( |
This is probably a LLVM 7.0.1 bug? |
To get the rest of the stack dump info about this, we'd need to reproduce with LLVM compiled in debug mode instead of release mode. |
@EpicEric Is your project avaiable so I could try this with vendored LLVM 7.0.1 to see if I have the problem? |
Here's my repository: https://github.com/EpicEric/pcs3866-languages-and-compilers Using |
This issue happens on the new Alpine image
|
This is what
Which makes sense, since the Dockerfile was updated in this commit. Here is my
|
I get this crash using the vendored LLVM 7.0.1 so this isn't the ABI issue that 7.1.0 addresses. This is definitely a "real bug". |
Release version stack trace from MacOS where it also happens:
|
A bit more info is available if we don't strip debug info:
|
I don't have any previous experience diagnosing LLVM optimization bugs. I do know that line 1400 in genopt.cc: Interestingly, the only thing I can see being added to
but turning that off doesn't prevent the crash. If anyone can elucidate more on what is going on here, I'd appreciate it. |
Turning on the "VerifyOutput" option gives us an interesting result for this case:
|
FYI, "does not dominate all uses" basically translates to "this variable gets used in some branch where it has not actually been assigned". |
So the error message is saying that we generated code to allocate a thing, and somewhere else we generated code to use that allocated pointer, but that was in an execution branch where it was not actually ever assigned. |
@SeanTAllen - So there's basically two possibilities:
|
@jemc I do not get the VerifyOutput error when running |
@jemc turning off all our pony_specific passes does not fix the issue either. |
With "VerifyOutput" on.
that is around line 1428 of genopt.cc then we do not get an error of any sort and successfully compile the program. |
At |
Not populating the module pass manager ALSO fixes the issue.
Perhaps an interaction between module pass and link time pass? Turning either one of them (doesn't matter which) off, "solves" the issue. |
Running the module pass after the link pass also "solves" the issue:
Note, that is the ONLY change needed to genopt.cc to get the example code compiling. |
In the LLVM 7 MPM code that we are executing there is:
If that isn't run then with everything else as is, we are fine and there's no crash. It's getting late here so I'm putting this down for now. I'll pick this up later and try to figure out what is being run in LPM that is interacting poorly with the above MPM pass. |
Pushing conversation on this to next week. |
@SeanTAllen pinging this issue. Is there any plan on discussing this issue during sync up meeting? |
@mshockwave we decided a couple of weeks back that in general, we are:
once we are doing releases using a vendored LLVM, any patches like this will be applied at build time. We need to create an issue for working on applying patches as part of the make process. We are generally hoping that LLVM 9 support is finished soon and hopefully, this particular issue doesn't exist anymore. That said, @kulibali is working on switching us over to using cmake for all builds so any work on patching should probably be done after that (as it would perhaps need to be repeated), best to discuss that with @kulibali. @kulibali has currently paused the cmake work because I've been doing a lot of work around messing with CI and build process as part of the move to vendored. @mshockwave would you be interested in lending a hand in either of these ways:
|
@mshockwave you should definitely ping that patch on review, and maybe point out that it breaks Pony (which may make people wake up). That patch has not landed in LLVM 9.0, so you're still going to have to manually apply this patch after the upgrade to 9.0. |
Just want to double check: "vendored" here means using the upstream LLVM source code tree, right? I'm generally happy to see all these changes happen. Both the cmake part and the adoption of vendored LLVM + patching.
Yes, I'm happy to help that.
Sure, I believe it would be an interesting topic |
@lenary Yes I will ping on the Phabricator and connecting it with ponyc. At the same time, I'm contacting LLVM Weekly to see if they can put a heads-up regarding that review in the issue next week. |
@mshockwave that sounds like a sensible idea regarding llvm weekly. I think "vendoring" means pony ships with their own pony-specific copy of LLVM, like rust currently does, rather than relying on the version of an LLVM somewhere else in the system. |
Vendoring means using the LLVM that we have pulled in as a git-submodule. |
Any help with LLVM 9 (#3320) would be welcome, as I don't have a lot of time to work on it. |
FYI: Good news my patch regarding MemCpyOpt fix just got accepted. It will be in the next LLVM release. |
Awesome. |
@mshockwave would you be interested in helping to get us up to date with LLVM support? |
@SeanTAllen yes I am interested. I will cooperate with @kulibali on issue #3320 |
@mshockwave you are awesome. thanks. |
…e Values Summary: When MemCpyOpt is handling aggregate type values, if an instruction (let's call it P) between the targeting load (L) and store (S) clobbers the source pointer of L, it will try to hoist S before P. This process will also hoist S's data dependency instructions. However, the current implementation has a bug that if one of S's dependency instructions is //also// a user of P, MemCpyOpt will not prevent it from being hoisted above P and cause a use-before-define error. For example, in the newly added test file (i.e. `aggregate-type-crash.ll`), it will try to hoist both `store %my_struct %1, %my_struct* %3` and its dependent, `%3 = bitcast i8* %2 to %my_struct*`, above `%2 = call i8* @my_malloc(%my_struct* %0)`. Creating the following BB: ``` entry: %1 = bitcast i8* %4 to %my_struct* %2 = bitcast %my_struct* %1 to i8* %3 = bitcast %my_struct* %0 to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %2, i8* align 4 %3, i64 8, i1 false) %4 = call i8* @my_malloc(%my_struct* %0) ret void ``` Where there is a use-before-define error between `%1` and `%4`. Update: The compiler for the Pony Programming Language [also encounter the same bug](ponylang/ponyc#3140) Patch by Min-Yih Hsu (myhsu) Reviewers: eugenis, pcc, dblaikie, dneilson, t.p.northover, lattner Reviewed By: eugenis Subscribers: lenary, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66060 llvm-svn: 375403
…e Values Summary: When MemCpyOpt is handling aggregate type values, if an instruction (let's call it P) between the targeting load (L) and store (S) clobbers the source pointer of L, it will try to hoist S before P. This process will also hoist S's data dependency instructions. However, the current implementation has a bug that if one of S's dependency instructions is //also// a user of P, MemCpyOpt will not prevent it from being hoisted above P and cause a use-before-define error. For example, in the newly added test file (i.e. `aggregate-type-crash.ll`), it will try to hoist both `store %my_struct %1, %my_struct* %3` and its dependent, `%3 = bitcast i8* %2 to %my_struct*`, above `%2 = call i8* @my_malloc(%my_struct* %0)`. Creating the following BB: ``` entry: %1 = bitcast i8* %4 to %my_struct* %2 = bitcast %my_struct* %1 to i8* %3 = bitcast %my_struct* %0 to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %2, i8* align 4 %3, i64 8, i1 false) %4 = call i8* @my_malloc(%my_struct* %0) ret void ``` Where there is a use-before-define error between `%1` and `%4`. Update: The compiler for the Pony Programming Language [also encounter the same bug](ponylang/ponyc#3140) Patch by Min-Yih Hsu (myhsu) Reviewers: eugenis, pcc, dblaikie, dneilson, t.p.northover, lattner Reviewed By: eugenis Subscribers: lenary, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66060 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@375403 91177308-0d34-0410-b5e6-96231b3b80d8
…e Values Summary: When MemCpyOpt is handling aggregate type values, if an instruction (let's call it P) between the targeting load (L) and store (S) clobbers the source pointer of L, it will try to hoist S before P. This process will also hoist S's data dependency instructions. However, the current implementation has a bug that if one of S's dependency instructions is //also// a user of P, MemCpyOpt will not prevent it from being hoisted above P and cause a use-before-define error. For example, in the newly added test file (i.e. `aggregate-type-crash.ll`), it will try to hoist both `store %my_struct %1, %my_struct* %3` and its dependent, `%3 = bitcast i8* %2 to %my_struct*`, above `%2 = call i8* @my_malloc(%my_struct* %0)`. Creating the following BB: ``` entry: %1 = bitcast i8* %4 to %my_struct* %2 = bitcast %my_struct* %1 to i8* %3 = bitcast %my_struct* %0 to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %2, i8* align 4 %3, i64 8, i1 false) %4 = call i8* @my_malloc(%my_struct* %0) ret void ``` Where there is a use-before-define error between `%1` and `%4`. Update: The compiler for the Pony Programming Language [also encounter the same bug](ponylang/ponyc#3140) Patch by Min-Yih Hsu (myhsu) Reviewers: eugenis, pcc, dblaikie, dneilson, t.p.northover, lattner Reviewed By: eugenis Subscribers: lenary, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66060 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@375403 91177308-0d34-0410-b5e6-96231b3b80d8
I have added this patch to the list of changes to be backported to LLVM 9.0.1: PR43974. |
------------------------------------------------------------------------ r375403 | lenary | 2019-10-21 03:00:34 -0700 (Mon, 21 Oct 2019) | 30 lines [MemCpyOpt] Fixing Incorrect Code Motion while Handling Aggregate Type Values Summary: When MemCpyOpt is handling aggregate type values, if an instruction (let's call it P) between the targeting load (L) and store (S) clobbers the source pointer of L, it will try to hoist S before P. This process will also hoist S's data dependency instructions. However, the current implementation has a bug that if one of S's dependency instructions is //also// a user of P, MemCpyOpt will not prevent it from being hoisted above P and cause a use-before-define error. For example, in the newly added test file (i.e. `aggregate-type-crash.ll`), it will try to hoist both `store %my_struct %1, %my_struct* %3` and its dependent, `%3 = bitcast i8* %2 to %my_struct*`, above `%2 = call i8* @my_malloc(%my_struct* %0)`. Creating the following BB: ``` entry: %1 = bitcast i8* %4 to %my_struct* %2 = bitcast %my_struct* %1 to i8* %3 = bitcast %my_struct* %0 to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %2, i8* align 4 %3, i64 8, i1 false) %4 = call i8* @my_malloc(%my_struct* %0) ret void ``` Where there is a use-before-define error between `%1` and `%4`. Update: The compiler for the Pony Programming Language [also encounter the same bug](ponylang/ponyc#3140) Patch by Min-Yih Hsu (myhsu) Reviewers: eugenis, pcc, dblaikie, dneilson, t.p.northover, lattner Reviewed By: eugenis Subscribers: lenary, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66060 ------------------------------------------------------------------------
Update: the fix has been merged into the 9.0.1 branch. I'm still not sure the timeline of the 9.0.1 release. |
Awesome. Thanks for the update @lenary. |
…e Values Summary: When MemCpyOpt is handling aggregate type values, if an instruction (let's call it P) between the targeting load (L) and store (S) clobbers the source pointer of L, it will try to hoist S before P. This process will also hoist S's data dependency instructions. However, the current implementation has a bug that if one of S's dependency instructions is //also// a user of P, MemCpyOpt will not prevent it from being hoisted above P and cause a use-before-define error. For example, in the newly added test file (i.e. `aggregate-type-crash.ll`), it will try to hoist both `store %my_struct %1, %my_struct* %3` and its dependent, `%3 = bitcast i8* %2 to %my_struct*`, above `%2 = call i8* @my_malloc(%my_struct* %0)`. Creating the following BB: ``` entry: %1 = bitcast i8* %4 to %my_struct* %2 = bitcast %my_struct* %1 to i8* %3 = bitcast %my_struct* %0 to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %2, i8* align 4 %3, i64 8, i1 false) %4 = call i8* @my_malloc(%my_struct* %0) ret void ``` Where there is a use-before-define error between `%1` and `%4`. Update: The compiler for the Pony Programming Language [also encounter the same bug](ponylang/ponyc#3140) Patch by Min-Yih Hsu (myhsu) Reviewers: eugenis, pcc, dblaikie, dneilson, t.p.northover, lattner Reviewed By: eugenis Subscribers: lenary, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66060 llvm-svn: 375403
@EpicEric this is fixed for me on master when using a ponyc compiler built using the vendored LLVM. can you confirm?
is how I am building said ponyc compiler. |
Confirming that current |
------------------------------------------------------------------------ r375403 | lenary | 2019-10-21 03:00:34 -0700 (Mon, 21 Oct 2019) | 30 lines [MemCpyOpt] Fixing Incorrect Code Motion while Handling Aggregate Type Values Summary: When MemCpyOpt is handling aggregate type values, if an instruction (let's call it P) between the targeting load (L) and store (S) clobbers the source pointer of L, it will try to hoist S before P. This process will also hoist S's data dependency instructions. However, the current implementation has a bug that if one of S's dependency instructions is //also// a user of P, MemCpyOpt will not prevent it from being hoisted above P and cause a use-before-define error. For example, in the newly added test file (i.e. `aggregate-type-crash.ll`), it will try to hoist both `store %my_struct %1, %my_struct* %3` and its dependent, `%3 = bitcast i8* %2 to %my_struct*`, above `%2 = call i8* @my_malloc(%my_struct* %0)`. Creating the following BB: ``` entry: %1 = bitcast i8* %4 to %my_struct* %2 = bitcast %my_struct* %1 to i8* %3 = bitcast %my_struct* %0 to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %2, i8* align 4 %3, i64 8, i1 false) %4 = call i8* @my_malloc(%my_struct* %0) ret void ``` Where there is a use-before-define error between `%1` and `%4`. Update: The compiler for the Pony Programming Language [also encounter the same bug](ponylang/ponyc#3140) Patch by Min-Yih Hsu (myhsu) Reviewers: eugenis, pcc, dblaikie, dneilson, t.p.northover, lattner Reviewed By: eugenis Subscribers: lenary, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66060 ------------------------------------------------------------------------
------------------------------------------------------------------------ r375403 | lenary | 2019-10-21 03:00:34 -0700 (Mon, 21 Oct 2019) | 30 lines [MemCpyOpt] Fixing Incorrect Code Motion while Handling Aggregate Type Values Summary: When MemCpyOpt is handling aggregate type values, if an instruction (let's call it P) between the targeting load (L) and store (S) clobbers the source pointer of L, it will try to hoist S before P. This process will also hoist S's data dependency instructions. However, the current implementation has a bug that if one of S's dependency instructions is //also// a user of P, MemCpyOpt will not prevent it from being hoisted above P and cause a use-before-define error. For example, in the newly added test file (i.e. `aggregate-type-crash.ll`), it will try to hoist both `store %my_struct %1, %my_struct* %3` and its dependent, `%3 = bitcast i8* %2 to %my_struct*`, above `%2 = call i8* @my_malloc(%my_struct* %0)`. Creating the following BB: ``` entry: %1 = bitcast i8* %4 to %my_struct* %2 = bitcast %my_struct* %1 to i8* %3 = bitcast %my_struct* %0 to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %2, i8* align 4 %3, i64 8, i1 false) %4 = call i8* @my_malloc(%my_struct* %0) ret void ``` Where there is a use-before-define error between `%1` and `%4`. Update: The compiler for the Pony Programming Language [also encounter the same bug](ponylang/ponyc#3140) Patch by Min-Yih Hsu (myhsu) Reviewers: eugenis, pcc, dblaikie, dneilson, t.p.northover, lattner Reviewed By: eugenis Subscribers: lenary, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66060 ------------------------------------------------------------------------
Originally reported while working on #3138.
A few Pony projects I tested crash ponyc 0.28.0 on the
Writing ./foo.o
step when running in Docker. For example, pony-kafka or one of my personal projects. Some projects (for example, pony-stable) compile just fine.For example, with pony-kafka I get the following logs and the error code 139:
This doesn't happen for the
0.27.0
Docker tag, when using the distribution release of Pony outside of the container, or when usingponyc --debug
. For these cases, it will compile (or just fail normally with error code 255 when trying to link the required libraries).I have yet to test the distribution release of Pony inside the container.
The text was updated successfully, but these errors were encountered: