[llvm-bugs] [Bug 52482] New: Last case of switch generated as a comparison

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Nov 11 15:09:42 PST 2021


https://bugs.llvm.org/show_bug.cgi?id=52482

            Bug ID: 52482
           Summary: Last case of switch generated as a comparison
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Scalar Optimizations
          Assignee: unassignedbugs at nondot.org
          Reporter: llvm at rifkin.dev
                CC: llvm-bugs at lists.llvm.org

Switch conversion fires on the following code:

void a(), b(), c(), d(), e();
void foo(int x) {
    switch(x) {
        case 0: a(); break;
        case 1: b(); break;
        case 2: c(); break;
        case 3: d(); break;
        case 4: e(); break;
        default: __builtin_unreachable();
    }
}
void bar(int x) {
    if      (x == 0) a();
    else if (x == 1) b();
    else if (x == 2) c();
    else if (x == 3) d();
    else if (x == 4) e();
    else __builtin_unreachable();
}

But bar ends up being implemented with a switch, something like:

void bar(int x) {
    if((unsigned)x > 3) {
        e();
    } else {
        switch(x) {
            case 0: a(); break;
            case 1: b(); break;
            case 2: c(); break;
            case 3: d(); break;
            default: __builtin_unreachable();
        }
    }
}

Case 4 is in its own branch rather than in the switch.

This appears to be due to SimplifyCFG transforming the last if-else in bar to

if(x == c) {
    e();
} else {
    __builtin_unreachable();
}
// into:
__builtin_assume(x == c);
e();

Then the if-else chain as a whole ends up being transformed to:

void bar(int x) {
    switch(x) {
        case 0: a(); break;
        case 1: b(); break;
        case 2: c(); break;
        case 3: d(); break;
        default:
            __builtin_assume(x == 4);
            e();
    }
}

https://godbolt.org/z/qrYb1hnh7

I'm not sure how GCC deals with this (it does transform bar() correctly), I'm
interested what the best way to address this in LLVM will be.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20211111/40c97f2e/attachment.html>


More information about the llvm-bugs mailing list