Skip to content

switch idiom recognition that fires on integers doesn't fire on pointers #130681

@Kmeakin

Description

@Kmeakin

src1 gets optimized into tgt1, but src2 doesn't get optimized into tgt2:

uint64_t src1(uint64_t i) {
    switch (i) {
        case 0:
            return 0;
        case 1:
            return 1;
        case 2:
            return 2;
        default:
            __builtin_unreachable();
    }
}

uint64_t tgt1(uint64_t i) {
    if (i > 2) {
        __builtin_unreachable();
    }
    return i;
}

char* src2(uint32_t i, char* p) {
    switch (i) {
        case 0:
            return &p[0];
        case 1:
            return &p[1];
        case 2:
            return &p[2];
        default:
            __builtin_unreachable();
    }
}

char* tgt2(uint32_t i, char* p) {
    if (i > 2) {
        __builtin_unreachable();
    }
    return &p[i];
}

Motivation

Trying to optimize enum-to-string code by reducing number of globals that have to be loaded:

pub enum Foo {
    A,
    B,
    C,
}

pub fn src(foo: Foo) -> &'static str {
    match foo {
        Foo::A => "A",
        Foo::B => "B",
        Foo::C => "C",
    }
}

pub fn tgt(foo: Foo) -> &'static str {
    const ABC: &str = "ABC";

    match foo {
        Foo::A => &ABC[0..1],
        Foo::B => &ABC[1..2],
        Foo::C => &ABC[2..3],
    }
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions