Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -6369,6 +6369,17 @@ } } + // try unsigned if the case value is signed overflow + if (MinCaseVal->isMinSignedValue() && MaxCaseVal->isMaxValue(true)) { + for (auto Case : SI->cases()) { + ConstantInt *CaseVal = Case.getCaseValue(); + if (CaseVal->getValue().ult(MinCaseVal->getValue())) + MinCaseVal = CaseVal; + if (CaseVal->getValue().ugt(MaxCaseVal->getValue())) + MaxCaseVal = CaseVal; + } + } + // Keep track of the result types. for (PHINode *PHI : PHIs) { ResultTypes[PHI] = ResultLists[PHI][0].second->getType(); Index: llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll +++ llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll @@ -1538,14 +1538,11 @@ define i32 @covered_switch_with_bit_tests(i3) { ; CHECK-LABEL: @covered_switch_with_bit_tests( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[TMP0:%.*]], -4 -; CHECK-NEXT: [[SWITCH_MASKINDEX:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i8 -; CHECK-NEXT: [[SWITCH_SHIFTED:%.*]] = lshr i8 -61, [[SWITCH_MASKINDEX]] -; CHECK-NEXT: [[SWITCH_LOBIT:%.*]] = trunc i8 [[SWITCH_SHIFTED]] to i1 -; CHECK-NEXT: br i1 [[SWITCH_LOBIT]], label [[SWITCH_LOOKUP:%.*]], label [[L6:%.*]] +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[TMP0:%.*]], 2 +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i3 [[SWITCH_TABLEIDX]], -4 +; CHECK-NEXT: br i1 [[TMP1]], label [[SWITCH_LOOKUP:%.*]], label [[L6:%.*]] ; CHECK: switch.lookup: -; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i4 -; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @switch.table.covered_switch_with_bit_tests, i32 0, i4 [[SWITCH_TABLEIDX_ZEXT]] +; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.covered_switch_with_bit_tests, i32 0, i3 [[SWITCH_TABLEIDX]] ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4 ; CHECK-NEXT: br label [[L6]] ; CHECK: l6: @@ -1696,11 +1693,10 @@ ; CHECK-LABEL: @signed_overflow1( ; CHECK-NEXT: start: ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i2 -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], -2 -; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i3 -; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.signed_overflow1, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]] -; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4 -; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] +; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i2 [[TRUNC]] to i32 +; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i32 [[SWITCH_IDX_CAST]], 1111 +; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[SWITCH_IDX_MULT]], 1111 +; CHECK-NEXT: ret i32 [[SWITCH_OFFSET]] ; start: %trunc = trunc i8 %n to i2 @@ -1732,20 +1728,11 @@ ; CHECK-LABEL: @signed_overflow2( ; CHECK-NEXT: start: ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i2 -; CHECK-NEXT: switch i2 [[TRUNC]], label [[BB1:%.*]] [ -; CHECK-NEXT: i2 1, label [[BB6:%.*]] -; CHECK-NEXT: i2 -2, label [[BB4:%.*]] -; CHECK-NEXT: i2 -1, label [[BB5:%.*]] -; CHECK-NEXT: ] -; CHECK: bb1: -; CHECK-NEXT: unreachable -; CHECK: bb4: -; CHECK-NEXT: br label [[BB6]] -; CHECK: bb5: -; CHECK-NEXT: br label [[BB6]] -; CHECK: bb6: -; CHECK-NEXT: [[DOTSROA_0_0:%.*]] = phi i32 [ 4444, [[BB5]] ], [ 3333, [[BB4]] ], [ 2222, [[START:%.*]] ] -; CHECK-NEXT: ret i32 [[DOTSROA_0_0]] +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], 1 +; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i32 +; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i32 [[SWITCH_IDX_CAST]], 1111 +; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[SWITCH_IDX_MULT]], 2222 +; CHECK-NEXT: ret i32 [[SWITCH_OFFSET]] ; start: %trunc = trunc i8 %n to i2 @@ -1776,11 +1763,10 @@ ; CHECK-LABEL: @signed_overflow_negative( ; CHECK-NEXT: start: ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[N:%.*]] to i2 -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TRUNC]], -2 -; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i32 -; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i32 [[SWITCH_IDX_CAST]], 1111 -; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[SWITCH_IDX_MULT]], 1111 -; CHECK-NEXT: ret i32 [[SWITCH_OFFSET]] +; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[TRUNC]] to i3 +; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.signed_overflow_negative, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]] +; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]], align 4 +; CHECK-NEXT: ret i32 [[SWITCH_LOAD]] ; start: %trunc = trunc i8 %n to i2