Skip to content

Missed optimization: layout optimized enums produce slow derived code #55030

Open
@oli-obk

Description

@oli-obk

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 }

https://play.rust-lang.org/?gist=9d1ff0355fbfabbc0c47f15e78e94687&version=nightly&mode=debug&edition=2015

to

pub enum Bar {
    X, Y, Z
}
enum Foo {
    A,
    B,
    Other(Bar),
}

https://play.rust-lang.org/?gist=faf6db37cdc627b1c5f8d582ad5c6779&version=nightly&mode=release&edition=2015

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

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationC-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions