| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 | |
| ; RUN: opt %s -S -passes=inline -inline-threshold=16 -min-jump-table-entries=4 | FileCheck %s -check-prefix=LOOKUPTABLE | |
| ; RUN: opt %s -S -passes=inline -inline-threshold=11 -min-jump-table-entries=5 | FileCheck %s -check-prefix=SWITCH | |
| ; REQUIRES: x86-registered-target | |
| target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" | |
| target triple = "x86_64-unknown-linux-gnu" | |
| ; The `bar1` should not be inlined since there is a default branch. | |
| define i64 @foo1(i64 %a) { | |
| ; LOOKUPTABLE-LABEL: define i64 @foo1( | |
| ; LOOKUPTABLE-SAME: i64 [[A:%.*]]) { | |
| ; LOOKUPTABLE-NEXT: [[B:%.*]] = call i64 @bar1(i64 [[A]]) | |
| ; LOOKUPTABLE-NEXT: ret i64 [[B]] | |
| ; | |
| ; SWITCH-LABEL: define i64 @foo1( | |
| ; SWITCH-SAME: i64 [[A:%.*]]) { | |
| ; SWITCH-NEXT: [[B:%.*]] = call i64 @bar1(i64 [[A]]) | |
| ; SWITCH-NEXT: ret i64 [[B]] | |
| ; | |
| %b = call i64 @bar1(i64 %a) | |
| ret i64 %b | |
| } | |
| ; Since the default branch is undefined behavior, | |
| ; we can inline `bar2`: https://github.com/llvm/llvm-project/issues/90929 | |
| define i64 @foo2(i64 %a) { | |
| ; LOOKUPTABLE-LABEL: define i64 @foo2( | |
| ; LOOKUPTABLE-SAME: i64 [[A:%.*]]) { | |
| ; LOOKUPTABLE-NEXT: switch i64 [[A]], label [[UNREACHABLEDEFAULT_I:%.*]] [ | |
| ; LOOKUPTABLE-NEXT: i64 0, label [[BRANCH_0_I:%.*]] | |
| ; LOOKUPTABLE-NEXT: i64 2, label [[BRANCH_2_I:%.*]] | |
| ; LOOKUPTABLE-NEXT: i64 4, label [[BRANCH_4_I:%.*]] | |
| ; LOOKUPTABLE-NEXT: i64 6, label [[BRANCH_6_I:%.*]] | |
| ; LOOKUPTABLE-NEXT: ] | |
| ; LOOKUPTABLE: branch_0.i: | |
| ; LOOKUPTABLE-NEXT: br label [[BAR2_EXIT:%.*]] | |
| ; LOOKUPTABLE: branch_2.i: | |
| ; LOOKUPTABLE-NEXT: br label [[BAR2_EXIT]] | |
| ; LOOKUPTABLE: branch_4.i: | |
| ; LOOKUPTABLE-NEXT: br label [[BAR2_EXIT]] | |
| ; LOOKUPTABLE: branch_6.i: | |
| ; LOOKUPTABLE-NEXT: br label [[BAR2_EXIT]] | |
| ; LOOKUPTABLE: unreachabledefault.i: | |
| ; LOOKUPTABLE-NEXT: unreachable | |
| ; LOOKUPTABLE: bar2.exit: | |
| ; LOOKUPTABLE-NEXT: [[B_I:%.*]] = phi i64 [ 5, [[BRANCH_0_I]] ], [ 9, [[BRANCH_2_I]] ], [ 2, [[BRANCH_4_I]] ], [ 7, [[BRANCH_6_I]] ] | |
| ; LOOKUPTABLE-NEXT: ret i64 [[B_I]] | |
| ; | |
| ; SWITCH-LABEL: define i64 @foo2( | |
| ; SWITCH-SAME: i64 [[A:%.*]]) { | |
| ; SWITCH-NEXT: [[B_I:%.*]] = call i64 @bar2(i64 [[A]]) | |
| ; SWITCH-NEXT: ret i64 [[B_I]] | |
| ; | |
| %b = call i64 @bar2(i64 %a) | |
| ret i64 %b | |
| } | |
| define i64 @bar1(i64 %a) { | |
| ; LOOKUPTABLE-LABEL: define i64 @bar1( | |
| ; LOOKUPTABLE-SAME: i64 [[A:%.*]]) { | |
| ; LOOKUPTABLE-NEXT: switch i64 [[A]], label [[DEFAULT_BRANCH:%.*]] [ | |
| ; LOOKUPTABLE-NEXT: i64 0, label [[BRANCH_0:%.*]] | |
| ; LOOKUPTABLE-NEXT: i64 2, label [[BRANCH_2:%.*]] | |
| ; LOOKUPTABLE-NEXT: i64 4, label [[BRANCH_4:%.*]] | |
| ; LOOKUPTABLE-NEXT: i64 6, label [[BRANCH_6:%.*]] | |
| ; LOOKUPTABLE-NEXT: ] | |
| ; LOOKUPTABLE: branch_0: | |
| ; LOOKUPTABLE-NEXT: br label [[EXIT:%.*]] | |
| ; LOOKUPTABLE: branch_2: | |
| ; LOOKUPTABLE-NEXT: br label [[EXIT]] | |
| ; LOOKUPTABLE: branch_4: | |
| ; LOOKUPTABLE-NEXT: br label [[EXIT]] | |
| ; LOOKUPTABLE: branch_6: | |
| ; LOOKUPTABLE-NEXT: br label [[EXIT]] | |
| ; LOOKUPTABLE: default_branch: | |
| ; LOOKUPTABLE-NEXT: br label [[EXIT]] | |
| ; LOOKUPTABLE: exit: | |
| ; LOOKUPTABLE-NEXT: [[B:%.*]] = phi i64 [ 5, [[BRANCH_0]] ], [ 9, [[BRANCH_2]] ], [ 2, [[BRANCH_4]] ], [ 7, [[BRANCH_6]] ], [ 3, [[DEFAULT_BRANCH]] ] | |
| ; LOOKUPTABLE-NEXT: ret i64 [[B]] | |
| ; | |
| ; SWITCH-LABEL: define i64 @bar1( | |
| ; SWITCH-SAME: i64 [[A:%.*]]) { | |
| ; SWITCH-NEXT: switch i64 [[A]], label [[DEFAULT_BRANCH:%.*]] [ | |
| ; SWITCH-NEXT: i64 0, label [[BRANCH_0:%.*]] | |
| ; SWITCH-NEXT: i64 2, label [[BRANCH_2:%.*]] | |
| ; SWITCH-NEXT: i64 4, label [[BRANCH_4:%.*]] | |
| ; SWITCH-NEXT: i64 6, label [[BRANCH_6:%.*]] | |
| ; SWITCH-NEXT: ] | |
| ; SWITCH: branch_0: | |
| ; SWITCH-NEXT: br label [[EXIT:%.*]] | |
| ; SWITCH: branch_2: | |
| ; SWITCH-NEXT: br label [[EXIT]] | |
| ; SWITCH: branch_4: | |
| ; SWITCH-NEXT: br label [[EXIT]] | |
| ; SWITCH: branch_6: | |
| ; SWITCH-NEXT: br label [[EXIT]] | |
| ; SWITCH: default_branch: | |
| ; SWITCH-NEXT: br label [[EXIT]] | |
| ; SWITCH: exit: | |
| ; SWITCH-NEXT: [[B:%.*]] = phi i64 [ 5, [[BRANCH_0]] ], [ 9, [[BRANCH_2]] ], [ 2, [[BRANCH_4]] ], [ 7, [[BRANCH_6]] ], [ 3, [[DEFAULT_BRANCH]] ] | |
| ; SWITCH-NEXT: ret i64 [[B]] | |
| ; | |
| switch i64 %a, label %default_branch [ | |
| i64 0, label %branch_0 | |
| i64 2, label %branch_2 | |
| i64 4, label %branch_4 | |
| i64 6, label %branch_6 | |
| ] | |
| branch_0: | |
| br label %exit | |
| branch_2: | |
| br label %exit | |
| branch_4: | |
| br label %exit | |
| branch_6: | |
| br label %exit | |
| default_branch: | |
| br label %exit | |
| exit: | |
| %b = phi i64 [ 5, %branch_0 ], [ 9, %branch_2 ], [ 2, %branch_4 ], [ 7, %branch_6 ], [ 3, %default_branch ] | |
| ret i64 %b | |
| } | |
| define i64 @bar2(i64 %a) { | |
| ; LOOKUPTABLE-LABEL: define i64 @bar2( | |
| ; LOOKUPTABLE-SAME: i64 [[A:%.*]]) { | |
| ; LOOKUPTABLE-NEXT: switch i64 [[A]], label [[UNREACHABLEDEFAULT:%.*]] [ | |
| ; LOOKUPTABLE-NEXT: i64 0, label [[BRANCH_0:%.*]] | |
| ; LOOKUPTABLE-NEXT: i64 2, label [[BRANCH_2:%.*]] | |
| ; LOOKUPTABLE-NEXT: i64 4, label [[BRANCH_4:%.*]] | |
| ; LOOKUPTABLE-NEXT: i64 6, label [[BRANCH_6:%.*]] | |
| ; LOOKUPTABLE-NEXT: ] | |
| ; LOOKUPTABLE: branch_0: | |
| ; LOOKUPTABLE-NEXT: br label [[EXIT:%.*]] | |
| ; LOOKUPTABLE: branch_2: | |
| ; LOOKUPTABLE-NEXT: br label [[EXIT]] | |
| ; LOOKUPTABLE: branch_4: | |
| ; LOOKUPTABLE-NEXT: br label [[EXIT]] | |
| ; LOOKUPTABLE: branch_6: | |
| ; LOOKUPTABLE-NEXT: br label [[EXIT]] | |
| ; LOOKUPTABLE: unreachabledefault: | |
| ; LOOKUPTABLE-NEXT: unreachable | |
| ; LOOKUPTABLE: exit: | |
| ; LOOKUPTABLE-NEXT: [[B:%.*]] = phi i64 [ 5, [[BRANCH_0]] ], [ 9, [[BRANCH_2]] ], [ 2, [[BRANCH_4]] ], [ 7, [[BRANCH_6]] ] | |
| ; LOOKUPTABLE-NEXT: ret i64 [[B]] | |
| ; | |
| ; SWITCH-LABEL: define i64 @bar2( | |
| ; SWITCH-SAME: i64 [[A:%.*]]) { | |
| ; SWITCH-NEXT: switch i64 [[A]], label [[UNREACHABLEDEFAULT:%.*]] [ | |
| ; SWITCH-NEXT: i64 0, label [[BRANCH_0:%.*]] | |
| ; SWITCH-NEXT: i64 2, label [[BRANCH_2:%.*]] | |
| ; SWITCH-NEXT: i64 4, label [[BRANCH_4:%.*]] | |
| ; SWITCH-NEXT: i64 6, label [[BRANCH_6:%.*]] | |
| ; SWITCH-NEXT: ] | |
| ; SWITCH: branch_0: | |
| ; SWITCH-NEXT: br label [[EXIT:%.*]] | |
| ; SWITCH: branch_2: | |
| ; SWITCH-NEXT: br label [[EXIT]] | |
| ; SWITCH: branch_4: | |
| ; SWITCH-NEXT: br label [[EXIT]] | |
| ; SWITCH: branch_6: | |
| ; SWITCH-NEXT: br label [[EXIT]] | |
| ; SWITCH: unreachabledefault: | |
| ; SWITCH-NEXT: unreachable | |
| ; SWITCH: exit: | |
| ; SWITCH-NEXT: [[B:%.*]] = phi i64 [ 5, [[BRANCH_0]] ], [ 9, [[BRANCH_2]] ], [ 2, [[BRANCH_4]] ], [ 7, [[BRANCH_6]] ] | |
| ; SWITCH-NEXT: ret i64 [[B]] | |
| ; | |
| switch i64 %a, label %unreachabledefault [ | |
| i64 0, label %branch_0 | |
| i64 2, label %branch_2 | |
| i64 4, label %branch_4 | |
| i64 6, label %branch_6 | |
| ] | |
| branch_0: | |
| br label %exit | |
| branch_2: | |
| br label %exit | |
| branch_4: | |
| br label %exit | |
| branch_6: | |
| br label %exit | |
| unreachabledefault: | |
| unreachable | |
| exit: | |
| %b = phi i64 [ 5, %branch_0 ], [ 9, %branch_2 ], [ 2, %branch_4 ], [ 7, %branch_6 ] | |
| ret i64 %b | |
| } |