Open
Description
Changing
const FOO_A: u32 = 0xFFFF_FFFF;
const FOO_B: u32 = 0xFFFF_FFFE;
const BAR_X: u32 = 0;
const BAR_Y: u32 = 1;
const BAR_Z: u32 = 2;
struct Foo { u: u32 }
to
pub enum Bar {
X, Y, Z
}
enum Foo {
A,
B,
Other(Bar),
}
While this will result in pretty much the same layout as before, any derived code on Foo
will now generate less optimal code. Apparently llvm can't manage to clean that up.
The llvm IR for the first playground link is
define zeroext i1 @_ZN10playground3foo17h7604dbf314c89374E(i32, i32) unnamed_addr #0 {
start:
%2 = icmp eq i32 %0, %1
ret i1 %2
}
while the one for the second link is
define zeroext i1 @_ZN10playground3foo17ha662001f5519a11dE(i32, i32) unnamed_addr #0 {
start:
%2 = add nsw i32 %0, -3
%3 = icmp ult i32 %2, 2
%narrow.i = select i1 %3, i32 %2, i32 2
%4 = add nsw i32 %1, -3
%5 = icmp ult i32 %4, 2
%narrow8.i = select i1 %5, i32 %4, i32 2
%6 = icmp eq i32 %narrow.i, %narrow8.i
br i1 %6, label %bb6.i, label %"_ZN56_$LT$playground..Foo$u20$as$u20$core..cmp..PartialEq$GT$2eq17h647dd5d9c0e8f1fcE.exit"
bb6.i: ; preds = %start
%7 = icmp eq i32 %0, %1
%not.or.cond.i = or i1 %3, %5
%spec.select.i = or i1 %7, %not.or.cond.i
br label %"_ZN56_$LT$playground..Foo$u20$as$u20$core..cmp..PartialEq$GT$2eq17h647dd5d9c0e8f1fcE.exit"
"_ZN56_$LT$playground..Foo$u20$as$u20$core..cmp..PartialEq$GT$2eq17h647dd5d9c0e8f1fcE.exit": ; preds = %start, %bb6.i
%8 = phi i1 [ %spec.select.i, %bb6.i ], [ false, %start ]
ret i1 %8
}
We can't improve the derives, because the derives on Foo
can't see the definition of Bar
.
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generationCategory: An issue highlighting optimization opportunities or PRs implementing suchIssue: Problems and improvements with respect to performance of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.