Skip to content

Enum valid_range calculations should be able to generate wraparound WrappingRanges for unsigned discriminants #144388

@scottmcm

Description

@scottmcm

Today, this enum

#[repr(u16)]
enum UnsignedAroundZero {
    A = 65535,
    B = 0,
    C = 1,
}

Gets this repr https://rust.godbolt.org/z/recPh37x4

layout_of(UnsignedAroundZero) = Layout {
    size: Size(2 bytes),
    align: AbiAlign {
        abi: Align(2 bytes),
    },
    backend_repr: Scalar(
        Initialized {
            value: Int(
                I16,
               false,
            ),
            valid_range: 0..=65535,    //    <-------
        },
    ),}

But that's the whole range, which is wasteful.

Because the valid_range is a WrappingRange, that type should instead get

            valid_range: (..=1) | (65535..),

That would mean that instead of

#[unsafe(no_mangle)]
pub fn demo(x: UnsignedAroundZero) {}

just giving https://rust.godbolt.org/z/zvfM5Pz3h

define void @demo(i16 noundef %x)

it would get

define void @demo(i16 noundef range(i16 -1, 2) %x)

and correspondingly LLVM could better optimize computations involving it.

Metadata

Metadata

Assignees

Labels

A-layoutArea: Memory layout of typesC-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchT-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