You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
LLVM error while cross-compiling Servo for ARM #32049
The profile_csv3 branch compiles successfully on a Mac OS X 10.10 and on a 64-bit Ubuntu 14.04. However, while cross-compiling the profile_csv3 branch for ARM (following instructions here: https://github.com/servo/servo-nightly/blob/master/.travis.yml) using the arm-linux-gnueabihf toolchain on an Ubuntu (14.04/15.10) host, I get the following error:
rustc: /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:531: void {anonymous}::PromoteMem2Reg::run(): Assertion isAllocaPromotable(AI) && "Cannot promote non-promotable alloca!"' failed. Aborted (core dumped) Build failed, waiting for other jobs to finish... Could not compileimage`.
You can see this by compiling the image crate version 0.7. Note that it only reproduces targeting arm32 (as shown above), not aarch64 or any of our x86_64 linux/osx/windows targets.
cc @eddyb, whom we chatted with about this a bit in #servo
Could someone who already has this set up run cargo rustc --target=arm-unknown-linux-gnueabihf -- -C llvm-args=-print-before-all on the image crate, and gist the output? It would be very helpful.
7:10 PM <eddyb> larsberg: ugh, isAllocaPromotable is non-trivial and basically depends on all the uses of allocas
7:10 PM → @brson (opped) joined
7:11 PM <eddyb> it has to be SROA::rewritePartition, which has its own promotable checks
7:14 PM <eddyb> larsberg: can you get a LLVM debug build?
7:14 PM <eddyb> larsberg: I severely understimated the size of this code
7:14 PM <eddyb> a debugger would let you "call AI->dump()" and at least get to see which alloca it is
7:15 PM ↔ japaric (was japaric_) nipped out
7:16 PM <@larsberg> eddyb: Sure, though I might have to do it in a couple of days. I am frantically trying to hack around this so that I can get a one-off ARM32 build of Servo together for a team to do some energy profiling on a board for a paper they're trying to get out in the next few days :-)
7:16 PM <eddyb> :(
7:16 PM <eddyb> larsberg: this is the worst bug
Not sure what you meant by that. One more thing, the crates used here seem to be the official armv6 ones, whereas I'm using a natively built armv7 compiler so maybe there's some mixing of armv6/v7 code or tools which could be a no-no for C/C++ parts.
@petevine Np, just trying to speed this up, because it looks like a bad bug that could otherwise remain unfixed for a few more years (especially if it's IR a C compiler would never generate).
Since @sanxiyn didn't post it, here's their diff showing the alignment difference, made after passing both inputs through rustfilt.sh (otherwise the random symbol names introduce a lot of noise).
Although it's possible I misunderstood him, @eddyb suggested to me that this was an LLVM bug -- which I guess means we may need to consider trying to find a workaround?
@nikomatsakis Since this is tied to alignment, finding a LlVM target for arm where align_of::<i64>() != 8 could fix it. It's why i686 doesn't exhibit the same problem, at least AFAICT.
@alexcrichton's reduced test case reproduces on 2016-03-18 but not on 2016-03-20, and 2016-03-19 doesn't exist, which gives us this range.
EDIT: Great, that's #32080, which probably changed the resulting IR in subtle ways. EDIT2: Given that Servo has worked since, until recently, my suspect is #33872, which fixed a bug I introduced in #32080.
The solution involves a cast @dotdash thought could eventually cause issues, so it may be relevant.
I can confirm that #33872 is what broke Servo recently. I wonder if fixing that "the right" way (i.e. with memcpy) makes the LLVM bug go away.
I've looked at clang and the IR it generates varies between a store of the cast argument to an alloca of the real type (what we did before #33872) and a memcpy between two allocas ("the right" way), but it never does what we do since #33872 (storing the cast argument to an alloca of its type and casting the pointer to a pointer to the real type).
Always generating a memcpy (i.e. "the right" way) for a cast argument instead of doing the shady pointer casts seems to work around this LLVM bug.
I don't think it's even possible to get clang to generate the IR patterns which end up in the assertion.
Activity
rzambre commentedon Mar 4, 2016
I posted this issue. I had to delete my old account.
larsbergstrom commentedon Mar 9, 2016
You can see this by compiling the image crate version 0.7. Note that it only reproduces targeting arm32 (as shown above), not aarch64 or any of our x86_64 linux/osx/windows targets.
cc @eddyb, whom we chatted with about this a bit in #servo
eddyb commentedon Mar 9, 2016
Could someone who already has this set up run
cargo rustc --target=arm-unknown-linux-gnueabihf -- -C llvm-args=-print-before-allon the image crate, and gist the output? It would be very helpful.larsbergstrom commentedon Mar 10, 2016
The last 10k lines:
https://gist.github.com/anonymous/d0074c0c58021d06062d
larsbergstrom commentedon Mar 10, 2016
Full file will be available here shortly:
https://dl.dropboxusercontent.com/u/1620890/output.tgz
larsbergstrom commentedon Mar 10, 2016
sanxiyn commentedon Mar 10, 2016
Reduced this. (Originally .bc weighed over 5 MB.) Clone https://github.com/sanxiyn/image/tree/reduce and:
larsbergstrom commentedon Mar 10, 2016
@sanxiyn Awesome work - thanks for doing this! It would have taken me a lot longer, and I probably wouldn't have gotten it down so far.
alexcrichton commentedon Mar 11, 2016
Minimized further: https://gist.github.com/alexcrichton/f7b527d749f1784508b1
Not... sure what to learn from that
eddyb commentedon Mar 11, 2016
@alexcrichton The challenge is to get clang to trip the same assert, to prove it's a LLVM bug and have it reported upstream.
MagaTailor commentedon Mar 11, 2016
I understand it's a cross-compilation-only bug as it definitely doesn't reproduce natively.
eddyb commentedon Mar 11, 2016
@petevine Is there a way to check if it's a 64-bit -> 32-bit issue? That's the first thing that jumps to mind.
MagaTailor commentedon Mar 11, 2016
Not sure what you meant by that. One more thing, the crates used here seem to be the official armv6 ones, whereas I'm using a natively built armv7 compiler so maybe there's some mixing of
armv6/v7code or tools which could be a no-no forC/C++ parts.eddyb commentedon Mar 11, 2016
@petevine I mean, cross-compiling for
x86fromx64or forarm32fromaarch64- if it's a 32-64-bit issue, they should both trigger it.8 remaining items
MagaTailor commentedon Mar 12, 2016
Thanks and sorry for the false lead.
eddyb commentedon Mar 12, 2016
@petevine Np, just trying to speed this up, because it looks like a bad bug that could otherwise remain unfixed for a few more years (especially if it's IR a C compiler would never generate).
eddyb commentedon Mar 12, 2016
Since @sanxiyn didn't post it, here's their diff showing the alignment difference, made after passing both inputs through rustfilt.sh (otherwise the random symbol names introduce a lot of noise).
metajack commentedon Jun 2, 2016
What's the status here? We just hit this again: http://build.servo.org/builders/arm32/builds/1329/steps/compile/logs/stdio
nikomatsakis commentedon Jun 6, 2016
Although it's possible I misunderstood him, @eddyb suggested to me that this was an LLVM bug -- which I guess means we may need to consider trying to find a workaround?
MagaTailor commentedon Jun 7, 2016
The workaround in the other issue(s) is to not use
opt-level=3. Downgrading llvm to 3.6 helped too in one case, IIRC.eddyb commentedon Jun 7, 2016
@nikomatsakis Since this is tied to alignment, finding a LlVM target for
armwherealign_of::<i64>() != 8could fix it. It's whyi686doesn't exhibit the same problem, at least AFAICT.eddyb commentedon Jun 7, 2016
@alexcrichton's reduced test case reproduces on 2016-03-18 but not on 2016-03-20, and 2016-03-19 doesn't exist, which gives us this range.
EDIT: Great, that's #32080, which probably changed the resulting IR in subtle ways.
EDIT2: Given that Servo has worked since, until recently, my suspect is #33872, which fixed a bug I introduced in #32080.
The solution involves a cast @dotdash thought could eventually cause issues, so it may be relevant.
eddyb commentedon Jun 7, 2016
I can confirm that #33872 is what broke Servo recently. I wonder if fixing that "the right" way (i.e. with
memcpy) makes the LLVM bug go away.I've looked at clang and the IR it generates varies between a store of the cast argument to an
allocaof the real type (what we did before #33872) and amemcpybetween twoallocas ("the right" way), but it never does what we do since #33872 (storing the cast argument to anallocaof its type and casting the pointer to a pointer to the real type).EDIT: clang behavior: https://godbolt.org/g/EphFuK vs https://godbolt.org/g/5dikH9
eddyb commentedon Jun 7, 2016
Always generating a
memcpy(i.e. "the right" way) for a cast argument instead of doing the shady pointer casts seems to work around this LLVM bug.I don't think it's even possible to get clang to generate the IR patterns which end up in the assertion.