[llvm-bugs] [Bug 52396] New: Folding common switch code

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Nov 3 18:58:13 PDT 2021


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

            Bug ID: 52396
           Summary: Folding common switch code
           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

LLVM optimizes common switch cases but clang is not producing the best codegen
for the following example:

void foo(int x) {
    switch(x) {
        case 2: func(x); break;
        case 3: func(x); break;
        case 4: func(x); break;
        case 5: func(x); break;
        case 6: func(x); break;
        default: __builtin_unreachable();
    }
}

void bar(int x) {
    switch(x) {
        case 1: func(x); break;
        case 4: func(x); break;
        case 7: func(x); break;
        case 3: func(x); break;
        case 9: func(x); break;
        default: __builtin_unreachable();
    }
}

foo(int):                                # @foo(int)
        jmp     func2(int)                       # TAILCALL

bar(int):                                # @bar(int)
        add     edi, -1
        movsxd  rax, edi
        mov     edi, dword ptr [4*rax + .Lswitch.table.bar(int)]
        jmp     func2(int)                       # TAILCALL
.Lswitch.table.bar(int):
        .long   1                               # 0x1
        .long   1                               # 0x1
        .long   3                               # 0x3
        .long   4                               # 0x4
        .long   1                               # 0x1
        .long   1                               # 0x1
        .long   7                               # 0x7
        .long   1                               # 0x1
        .long   9                               # 0x9

https://godbolt.org/z/Ya34bneoT

It appears LLVM propagates the constant x early in the optimization, pulls out
the common calls to func(), then later eliminates the switches during
SimplifyCFG. LLVM optimizes foo based off the switch case values being
sequential, with non-sequential values it doesn't undo the constant
propagation:

*** IR Dump After InstCombinePass on _Z3bari ***
; Function Attrs: mustprogress uwtable
define dso_local void @_Z3bari(i32 %0) local_unnamed_addr #0 {
  switch i32 %0, label %6 [
    i32 1, label %7
    i32 4, label %2
    i32 7, label %3
    i32 3, label %4
    i32 9, label %5
  ]
2:                                                ; preds = %1
  br label %7
3:                                                ; preds = %1
  br label %7
4:                                                ; preds = %1
  br label %7
5:                                                ; preds = %1
  br label %7
6:                                                ; preds = %1
  unreachable
7:                                                ; preds = %1, %5, %4, %3, %2
  %8 = phi i32 [ 9, %5 ], [ 3, %4 ], [ 7, %3 ], [ 4, %2 ], [ 1, %1 ]
  tail call void @_Z4funci(i32 %8)
  ret void
}
*** IR Dump After SimplifyCFGPass on _Z3bari ***
; Function Attrs: mustprogress uwtable
define dso_local void @_Z3bari(i32 %0) local_unnamed_addr #0 {
  %2 = sub i32 %0, 1
  %3 = trunc i32 %2 to i16
  %4 = lshr i16 333, %3
  %5 = trunc i16 %4 to i1
  call void @llvm.assume(i1 %5)
  %6 = getelementptr inbounds [9 x i32], [9 x i32]* @switch.table._Z3bari, i32
0, i32 %2
  %7 = load i32, i32* %6, align 4
  tail call void @_Z4funci(i32 %7)
  ret void
}

-- 
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/20211104/2f58ca3c/attachment-0001.html>


More information about the llvm-bugs mailing list