1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00

[SimplifyCFG] SwitchToLookupTable(): don't increase ret count

The very next SimplifyCFG pass invocation will tail-merge these two ret's
anyways, there is not much point in creating more work for ourselves.
This commit is contained in:
Roman Lebedev 2021-07-26 23:28:33 +03:00
parent 5b8d8bfd1b
commit cc27d61007
6 changed files with 64 additions and 81 deletions

View File

@ -5926,7 +5926,6 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
Updates.push_back({DominatorTree::Delete, BB, SI->getDefaultDest()}); Updates.push_back({DominatorTree::Delete, BB, SI->getDefaultDest()});
} }
bool ReturnedEarly = false;
for (PHINode *PHI : PHIs) { for (PHINode *PHI : PHIs) {
const ResultListTy &ResultList = ResultLists[PHI]; const ResultListTy &ResultList = ResultLists[PHI];
@ -5938,15 +5937,6 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
Value *Result = Table.BuildLookup(TableIndex, Builder); Value *Result = Table.BuildLookup(TableIndex, Builder);
// If the result is used to return immediately from the function, we want to
// do that right here.
if (PHI->hasOneUse() && isa<ReturnInst>(*PHI->user_begin()) &&
PHI->user_back() == CommonDest->getFirstNonPHIOrDbg()) {
Builder.CreateRet(Result);
ReturnedEarly = true;
break;
}
// Do a small peephole optimization: re-use the switch table compare if // Do a small peephole optimization: re-use the switch table compare if
// possible. // possible.
if (!TableHasHoles && HasDefaultResults && RangeCheckBranch) { if (!TableHasHoles && HasDefaultResults && RangeCheckBranch) {
@ -5960,11 +5950,9 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
PHI->addIncoming(Result, LookupBB); PHI->addIncoming(Result, LookupBB);
} }
if (!ReturnedEarly) { Builder.CreateBr(CommonDest);
Builder.CreateBr(CommonDest); if (DTU)
if (DTU) Updates.push_back({DominatorTree::Insert, LookupBB, CommonDest});
Updates.push_back({DominatorTree::Insert, LookupBB, CommonDest});
}
// Remove the switch. // Remove the switch.
SmallPtrSet<BasicBlock *, 8> RemovedSuccessors; SmallPtrSet<BasicBlock *, 8> RemovedSuccessors;

View File

@ -11,15 +11,15 @@ define i32 @f(i32 %c) {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = add i32 [[C:%.*]], -42 ; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = add i32 [[C:%.*]], -42
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[COMMON_RET:%.*]] ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; CHECK: common.ret:
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[SWITCH_LOAD:%.*]], [[SWITCH_LOOKUP]] ], [ 15, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
; CHECK: switch.lookup: ; CHECK: switch.lookup:
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[SWITCH_TABLEIDX]] to i64 ; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[SWITCH_TABLEIDX]] to i64
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], [7 x i32]* @switch.table.f, i64 0, i64 [[TMP1]] ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], [7 x i32]* @switch.table.f, i64 0, i64 [[TMP1]]
; CHECK-NEXT: [[SWITCH_LOAD]] = load i32, i32* [[SWITCH_GEP]], align 4 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4
; CHECK-NEXT: br label [[COMMON_RET]] ; CHECK-NEXT: br label [[RETURN]]
; CHECK: return:
; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 15, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i32 [[R]]
; ;
entry: entry:
switch i32 %c, label %sw.default [ switch i32 %c, label %sw.default [

View File

@ -11,14 +11,14 @@ define i32 @foo(i32 %x) #0 section ".tcm_text" {
; ENABLE-LABEL: @foo( ; ENABLE-LABEL: @foo(
; ENABLE-NEXT: entry: ; ENABLE-NEXT: entry:
; ENABLE-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 6 ; ENABLE-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 6
; ENABLE-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[COMMON_RET:%.*]] ; ENABLE-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; ENABLE: common.ret:
; ENABLE-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[SWITCH_LOAD:%.*]], [[SWITCH_LOOKUP]] ], [ 19, [[ENTRY:%.*]] ]
; ENABLE-NEXT: ret i32 [[COMMON_RET_OP]]
; ENABLE: switch.lookup: ; ENABLE: switch.lookup:
; ENABLE-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [6 x i32], [6 x i32]* @switch.table.foo, i32 0, i32 [[X]] ; ENABLE-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [6 x i32], [6 x i32]* @switch.table.foo, i32 0, i32 [[X]]
; ENABLE-NEXT: [[SWITCH_LOAD]] = load i32, i32* [[SWITCH_GEP]], align 4 ; ENABLE-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4
; ENABLE-NEXT: br label [[COMMON_RET]] ; ENABLE-NEXT: br label [[RETURN]]
; ENABLE: return:
; ENABLE-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 19, [[ENTRY:%.*]] ]
; ENABLE-NEXT: ret i32 [[RETVAL_0]]
; ;
; DISABLE-LABEL: @foo( ; DISABLE-LABEL: @foo(
; DISABLE-NEXT: entry: ; DISABLE-NEXT: entry:

View File

@ -52,9 +52,10 @@ define i32 @bar(i32 %c) {
; CHECK: switch.lookup: ; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.bar, i32 0, i32 [[SWITCH_TABLEIDX]] ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.bar, i32 0, i32 [[SWITCH_TABLEIDX]]
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] ; CHECK-NEXT: br label [[RETURN]]
; CHECK: return: ; CHECK: return:
; CHECK-NEXT: ret i32 15 ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 15, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i32 [[RETVAL_0]]
; ;
entry: entry:
switch i32 %c, label %sw.default [ switch i32 %c, label %sw.default [

View File

@ -42,9 +42,10 @@ define i32 @f(i32 %c) {
; CHECK: switch.lookup: ; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], [7 x i32]* @switch.table.f, i32 0, i32 [[SWITCH_TABLEIDX]] ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], [7 x i32]* @switch.table.f, i32 0, i32 [[SWITCH_TABLEIDX]]
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] ; CHECK-NEXT: br label [[RETURN]]
; CHECK: return: ; CHECK: return:
; CHECK-NEXT: ret i32 15 ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 15, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i32 [[RETVAL_0]]
; ;
entry: entry:
switch i32 %c, label %sw.default [ switch i32 %c, label %sw.default [
@ -81,9 +82,10 @@ define i8 @char(i32 %c) {
; CHECK: switch.lookup: ; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i8], [9 x i8]* @switch.table.char, i32 0, i32 [[SWITCH_TABLEIDX]] ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i8], [9 x i8]* @switch.table.char, i32 0, i32 [[SWITCH_TABLEIDX]]
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8, i8* [[SWITCH_GEP]], align 1 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8, i8* [[SWITCH_GEP]], align 1
; CHECK-NEXT: ret i8 [[SWITCH_LOAD]] ; CHECK-NEXT: br label [[RETURN]]
; CHECK: return: ; CHECK: return:
; CHECK-NEXT: ret i8 15 ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i8 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 15, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i8 [[RETVAL_0]]
; ;
entry: entry:
switch i32 %c, label %sw.default [ switch i32 %c, label %sw.default [
@ -172,9 +174,10 @@ define i8* @foostring(i32 %x) {
; CHECK: switch.lookup: ; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* @switch.table.foostring, i32 0, i32 [[X]] ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* @switch.table.foostring, i32 0, i32 [[X]]
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8*, i8** [[SWITCH_GEP]], align 8 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8*, i8** [[SWITCH_GEP]], align 8
; CHECK-NEXT: ret i8* [[SWITCH_LOAD]] ; CHECK-NEXT: br label [[RETURN]]
; CHECK: return: ; CHECK: return:
; CHECK-NEXT: ret i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str4, i64 0, i64 0) ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i8* [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ getelementptr inbounds ([6 x i8], [6 x i8]* @.str4, i64 0, i64 0), [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i8* [[RETVAL_0]]
; ;
entry: entry:
switch i32 %x, label %sw.default [ switch i32 %x, label %sw.default [
@ -210,9 +213,13 @@ define i32 @earlyreturncrash(i32 %x) {
; CHECK: switch.lookup: ; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.earlyreturncrash, i32 0, i32 [[X]] ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.earlyreturncrash, i32 0, i32 [[X]]
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] ; CHECK-NEXT: [[SWITCH_GEP1:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.earlyreturncrash.1, i32 0, i32 [[X]]
; CHECK-NEXT: [[SWITCH_LOAD2:%.*]] = load i32, i32* [[SWITCH_GEP1]], align 4
; CHECK-NEXT: br label [[SW_EPILOG]]
; CHECK: sw.epilog: ; CHECK: sw.epilog:
; CHECK-NEXT: ret i32 7 ; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 7, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[B_0:%.*]] = phi i32 [ [[SWITCH_LOAD2]], [[SWITCH_LOOKUP]] ], [ 10, [[ENTRY]] ]
; CHECK-NEXT: ret i32 [[A_0]]
; ;
entry: entry:
switch i32 %x, label %sw.default [ switch i32 %x, label %sw.default [
@ -343,15 +350,12 @@ define i1 @undef(i32 %tmp) {
; CHECK-LABEL: @undef( ; CHECK-LABEL: @undef(
; CHECK-NEXT: bb: ; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[TMP:%.*]], 9 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[TMP:%.*]], 9
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[BB3:%.*]]
; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[TMP]] to i9 ; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[TMP]] to i9
; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i9 [[SWITCH_CAST]], 1 ; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i9 [[SWITCH_CAST]], 1
; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i9 3, [[SWITCH_SHIFTAMT]] ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i9 3, [[SWITCH_SHIFTAMT]]
; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i9 [[SWITCH_DOWNSHIFT]] to i1 ; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i9 [[SWITCH_DOWNSHIFT]] to i1
; CHECK-NEXT: ret i1 [[SWITCH_MASKED]] ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_MASKED]], i1 undef
; CHECK: bb3: ; CHECK-NEXT: ret i1 [[TMP4]]
; CHECK-NEXT: ret i1 undef
; ;
bb: bb:
switch i32 %tmp, label %bb3 [ switch i32 %tmp, label %bb3 [
@ -384,9 +388,10 @@ define i32 @large(i32 %x) {
; CHECK: switch.lookup: ; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [199 x i32], [199 x i32]* @switch.table.large, i32 0, i32 [[SWITCH_TABLEIDX]] ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [199 x i32], [199 x i32]* @switch.table.large, i32 0, i32 [[SWITCH_TABLEIDX]]
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] ; CHECK-NEXT: br label [[RETURN]]
; CHECK: return: ; CHECK: return:
; CHECK-NEXT: ret i32 0 ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ]
; CHECK-NEXT: ret i32 [[RETVAL_0]]
; ;
entry: entry:
%cmp = icmp slt i32 %x, 0 %cmp = icmp slt i32 %x, 0
@ -814,9 +819,10 @@ define i32 @cprop(i32 %x, i32 %y) {
; CHECK: switch.lookup: ; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], [7 x i32]* @switch.table.cprop, i32 0, i32 [[SWITCH_TABLEIDX]] ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], [7 x i32]* @switch.table.cprop, i32 0, i32 [[SWITCH_TABLEIDX]]
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] ; CHECK-NEXT: br label [[RETURN]]
; CHECK: return: ; CHECK: return:
; CHECK-NEXT: ret i32 123 ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 123, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i32 [[RETVAL_0]]
; ;
entry: entry:
switch i32 %x, label %sw.default [ switch i32 %x, label %sw.default [
@ -863,9 +869,10 @@ define i32 @unreachable_case(i32 %x) {
; CHECK: switch.lookup: ; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i32], [9 x i32]* @switch.table.unreachable_case, i32 0, i32 [[X]] ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i32], [9 x i32]* @switch.table.unreachable_case, i32 0, i32 [[X]]
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] ; CHECK-NEXT: br label [[RETURN]]
; CHECK: return: ; CHECK: return:
; CHECK-NEXT: ret i32 2 ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 2, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i32 [[RETVAL_0]]
; ;
entry: entry:
switch i32 %x, label %sw.default [ switch i32 %x, label %sw.default [
@ -1080,9 +1087,10 @@ define i32 @threecases(i32 %c) {
; CHECK: switch.lookup: ; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i32], [3 x i32]* @switch.table.threecases, i32 0, i32 [[C]] ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i32], [3 x i32]* @switch.table.threecases, i32 0, i32 [[C]]
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4 ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] ; CHECK-NEXT: br label [[RETURN]]
; CHECK: return: ; CHECK: return:
; CHECK-NEXT: ret i32 3 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 3, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i32 [[X]]
; ;
entry: entry:
switch i32 %c, label %sw.default [ switch i32 %c, label %sw.default [
@ -1214,14 +1222,11 @@ define i8 @linearmap1(i32 %c) {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10 ; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 ; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8
; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i8 [[SWITCH_IDX_CAST]], -5 ; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i8 [[SWITCH_IDX_CAST]], -5
; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i8 [[SWITCH_IDX_MULT]], 18 ; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i8 [[SWITCH_IDX_MULT]], 18
; CHECK-NEXT: ret i8 [[SWITCH_OFFSET]] ; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_OFFSET]], i8 3
; CHECK: return: ; CHECK-NEXT: ret i8 [[X]]
; CHECK-NEXT: ret i8 3
; ;
entry: entry:
switch i32 %c, label %sw.default [ switch i32 %c, label %sw.default [
@ -1245,13 +1250,10 @@ define i32 @linearmap2(i8 %c) {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i8 [[C:%.*]], -13 ; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i8 [[C:%.*]], -13
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[SWITCH_TABLEIDX]], 4 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[SWITCH_TABLEIDX]], 4
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i8 [[SWITCH_TABLEIDX]] to i32 ; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i8 [[SWITCH_TABLEIDX]] to i32
; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[SWITCH_IDX_CAST]], 18 ; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[SWITCH_IDX_CAST]], 18
; CHECK-NEXT: ret i32 [[SWITCH_OFFSET]] ; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 3
; CHECK: return: ; CHECK-NEXT: ret i32 [[X]]
; CHECK-NEXT: ret i32 3
; ;
entry: entry:
switch i8 %c, label %sw.default [ switch i8 %c, label %sw.default [
@ -1275,13 +1277,10 @@ define i8 @linearmap3(i32 %c) {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10 ; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 ; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8
; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i8 [[SWITCH_IDX_CAST]], 100 ; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i8 [[SWITCH_IDX_CAST]], 100
; CHECK-NEXT: ret i8 [[SWITCH_IDX_MULT]] ; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_IDX_MULT]], i8 3
; CHECK: return: ; CHECK-NEXT: ret i8 [[X]]
; CHECK-NEXT: ret i8 3
; ;
entry: entry:
switch i32 %c, label %sw.default [ switch i32 %c, label %sw.default [
@ -1305,12 +1304,9 @@ define i8 @linearmap4(i32 %c) {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], -2 ; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], -2
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
; CHECK: switch.lookup:
; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 ; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8
; CHECK-NEXT: ret i8 [[SWITCH_IDX_CAST]] ; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_IDX_CAST]], i8 3
; CHECK: return: ; CHECK-NEXT: ret i8 [[X]]
; CHECK-NEXT: ret i8 3
; ;
entry: entry:
switch i32 %c, label %sw.default [ switch i32 %c, label %sw.default [

View File

@ -232,20 +232,18 @@ three:
define i8 @test7(i8 %a) optsize { define i8 @test7(i8 %a) optsize {
; CHECK-LABEL: @test7( ; CHECK-LABEL: @test7(
; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[A:%.*]], -36 ; CHECK-NEXT: common.ret:
; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], 2 ; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[A:%.*]], -36
; CHECK-NEXT: [[TMP3:%.*]] = shl i8 [[TMP1]], 6 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[TMP0]], 2
; CHECK-NEXT: [[TMP4:%.*]] = or i8 [[TMP2]], [[TMP3]] ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP0]], 6
; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i8 [[TMP4]], 4 ; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP1]], [[TMP2]]
; CHECK-NEXT: br i1 [[TMP5]], label [[SWITCH_LOOKUP:%.*]], label [[COMMON_RET:%.*]] ; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i8 [[TMP3]], 4
; CHECK: switch.lookup: ; CHECK-NEXT: [[SWITCH_CAST:%.*]] = zext i8 [[TMP3]] to i32
; CHECK-NEXT: [[SWITCH_CAST:%.*]] = zext i8 [[TMP4]] to i32
; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i32 [[SWITCH_CAST]], 8 ; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i32 [[SWITCH_CAST]], 8
; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 -943228976, [[SWITCH_SHIFTAMT]] ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 -943228976, [[SWITCH_SHIFTAMT]]
; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8 ; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8
; CHECK-NEXT: ret i8 [[SWITCH_MASKED]] ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = select i1 [[TMP4]], i8 [[SWITCH_MASKED]], i8 -93
; CHECK: common.ret: ; CHECK-NEXT: ret i8 [[COMMON_RET_OP]]
; CHECK-NEXT: ret i8 -93
; ;
switch i8 %a, label %def [ switch i8 %a, label %def [
i8 220, label %one i8 220, label %one