-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Unreachable code optimization failure when matching on Rust enum #77812
Comments
This is weird; LLVM has plenty enough information to be able to do this from what's emitted. The IR it currently produces: https://rust.godbolt.org/z/GWacEc define void @_ZN7example4test17h9c70bf34953e7145E() unnamed_addr #0 !dbg !6 {
start:
%_2.i = alloca %"std::fmt::Arguments", align 8
%0 = load i8, i8* getelementptr inbounds (<{ [1 x i8] }>, <{ [1 x i8] }>* @GLOBAL, i64 0, i32 0, i64 0), align 1, !dbg !10, !range !11
%_10.i.i.not = icmp eq i8 %0, 0, !dbg !12
br i1 %_10.i.i.not, label %bb8, label %bb3, !dbg !22
bb3: ; preds = %start
%_6 = zext i8 %0 to i64, !dbg !23
switch i64 %_6, label %bb5 [
i64 0, label %bb4
i64 1, label %bb6
i64 2, label %bb7
], !dbg !23 That clearly has sufficient information to know that Curiosity: why is rustc insisting on |
It gets even weirder if you put |
This looks like the same problem as #73031. LLVM can't see through the rustc extends to Although this can be fixed in LLVM, it may be worthwhile to try making the discr type the same as the memory repr, i.e. do this rust/compiler/rustc_middle/src/ty/layout.rs Lines 74 to 78 in 8cc82ee
rust/compiler/rustc_middle/src/ty/mod.rs Lines 2290 to 2292 in 8cc82ee
isize . (I think this would be backwards compatible, you can still as -cast to any integer type, I'm not sure if the underlying discriminant type is exposed anywhere.)
|
So is the fix here to codegen it using |
|
FYI, #74215 has some discussion about the trade-offs of changing I've also found that a not insignificant amount of hashing in the compiler is being done on discriminant values, so there is a potential compile time improvement in doing this too, though I don't think that should be a primary motivation for the change. |
Hmm, there's nothing that would force that type and the HIR->MIR desugaring to use the same internal construct value, though, right? Like we could change the MIR That way LLVM would just see a switch on the loaded value, not an extended one. (So this might still happen if the |
The case is eliminated with LLVM 12 by IPSCCP, probably as a result of https://reviews.llvm.org/D84270: https://llvm.godbolt.org/z/nbfnzc I would have expected CVP to handle this already before, but it doesn't due to https://github.com/llvm/llvm-project/blob/7beee561e23db56c7e24462a9870a3ba58a9b2b3/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp#L333-L336. |
The CVP issue is addressed by llvm/llvm-project@afbb6d9. Assigning this to myself to re-check this after the LLVM 12 upgrade. |
AFAICT, the issue has been successfully obliterated by #81451 🎉 |
Add codegen tests for some issues closed by LLVM 12 Namely rust-lang#73031, rust-lang#75546, and rust-lang#77812
In this example:
the
unreachable()
branch is not removed. Adding any#[repr(n)]
but not#[repr(C)]
toVariant
or making reachable branches call only one of external functions allows the optimization.There's no such issue with a similar C example using clang so it's likely something on Rust side.
Example links:
Rust https://rust.godbolt.org/z/9oh6sP
C https://godbolt.org/z/Tnbfx6
The text was updated successfully, but these errors were encountered: