Code change:
xref: In the of , one of the tests crashed with on s390x, while it passed on every other architecture. The reporter in Red Hat bugzilla found that it happens equally with system LLVM 11 or 10. The crate's also has , but they didn't see any improvement after turning that off. The distro builds run tests in release mode (to avoid recompiling from the main build) with flags in : The tests pass if we don't set , which suggests to me that some relevant (mis)optimization is only triggered with the full unit. The tests are also fine with Fedora's rust-1.45.2, only crashing on rust-1.46.0. I also reproduced the crash on rustup's stable 1.46.0, and I used to narrow down to passing, while crashes. That's ..., which is just (cc I don't know if would affect that, or if it's just triggering something new in LLVM. Here's the reporter's backtrace:
cc , another miscompilation on a tier 2 architecture that appeared after a similar optimization. If the root cause is the same, we should have a better chance of diagnosing it now, since it occurs in a crate's test case instead of while compiling Firefox. cc as well.
Assigning as discussed as part of the and removing .
Is supposed to avoid 's changes? That was mentioned in zulip , but I still get the crash with that option on nightly-2020-07-06.
No. That person was mistaken. Drop elaboration runs unconditionally as part of "".
Updating for cross-reference: I tried in , but it didn't help.
As a sanity check, was there any difference in the generated MIR for ? I tested the flag locally and it worked, but we should make sure. If there's no trivial error with the flag, I'm not sure what's going on. I guess we could with the more precise version of but the less precise version of (that was the status quo before ). I would be surprised if we had a miscompilation when using the precise version of both () or the imprecise version of both ( with or a release prior to ) but not with one precise and one imprecise (a release between and ).
Here are the test's after : They were compiled on Fedora Rawhide (34), in case anyone wants to find libraries to actually run the test executables.
Here's for reference: From : The error we get during the test case is , , "No such file or directory", which prints fine. With , the assembly after printing is: I believe that 2 is comparing the tag, where only needs dropping. When I step through, that branch is taken to skip ahead. Otherwise, you can see that it would load (offset 8 from before) for the into , then proceed to dereference that pointer. With , the assembly after printing is: Looks similar with 2, but I don't really speak SystemZ to guess what and are doing. But in the debugger I see that this branch is not taken, and then it loads a garbage pointer into (always seems to be ). The load of is where we .
Found the instruction reference... is Load Logical Immediate (low high) is Add (64), Condition code set So it seems to be clobbering the condition. I'm guessing the revised enum drops just exposed an existing codegen bug.
Nice! Since I didn't want you to have all the fun, here is the LLVM IR for the relevant section. The first basic block is the comparison with the enum discriminant of and the second is the first piece of drop glue. The structure looks to be the exact same, but there are additional annotations in the one with the miscompilation. I think these are correct in a vacuum, but I don't have enough LLVM knowledge to say for sure. I certainly don't have enough to hypothesize why they caused the instruction scheduler to forget all about the need to preserve flags/condition codes. 2020-07-05: 2020-07-06:
gets special treatment -- -- did something about your patch affect that visibility? I'm guessing, maybe before it was dropped indirectly through ( pending ), but with the more precise drops it may be dropped by value? ( does get .) Or if it used a raw before (like ), that doesn't get any annotations. Of course the trait uses , but I don't know what it looks like when an implicit MIR is elaborated.
In the MIR for the "precise" version, we move the error variant into a local, then drop the local. In the MIR for the imprecise version, we check the drop flag for the variant, then drop that projection. As you alluded to, perhaps there's some difference in how we were emitting LLVM IR for drops of locals vs drops of projections? I'm not an expert on codegen. However, given that this miscompilation is present on the latest master even without "precise" drop elaboration, we must have eliminated this difference at some point. Indeed, the declarations persist even with precise drop elaboration disabled on a recent : <details<summary<b -Zprecise-enum-drop-elaboration=no</b</summary</detailsOne thing occurs to me now that didn't last night: These lines seem to be checking the vtable for the boxed trait object in : However, trait object vtables can definitely alias globally. I don't see how this kind of error would cause the miscompilation we're seeing, but as I said I don't have much LLVM expertise. Regardless, it seems like something we should fix?
The actual vtable should be shared read-only, which is fine for LLVM .
Let's see what LLVM devs say:
It looks like an LLVM patch was accepted:
I'll backport that patch after the LLVM 11.0.0 final rebase lands -- . (I thought about doing that together, but figured it would be better to separate concerns.)

Related discussion:
text: <del> Subproject commit 3c5d47c81d78e9316e971c9870e8bc7c2c449d24 </del> <ins> Subproject commit 77a0125981b293260c9aec6355dff46ec707ab59 </ins>