Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -6129,10 +6129,14 @@ // truncating it to the width of the bitmask is safe. Value *ShiftAmt = Builder.CreateZExtOrTrunc(Index, MapTy, "switch.cast"); - // Multiply the shift amount by the element width. + // Multiply the shift amount by the element width. NUW/NSW can always be + // set, because WouldFitInRegister guarantees Index * ShiftAmt is in + // BitMap's bit width. ShiftAmt = Builder.CreateMul( ShiftAmt, ConstantInt::get(MapTy, BitMapElementTy->getBitWidth()), - "switch.shiftamt"); + "switch.shiftamt", + /*HasNUW =*/true, + /*HasNSW =*/true); // Shift down. Value *DownShifted = Index: llvm/test/Transforms/SimplifyCFG/RISCV/switch_to_lookup_table-rv32.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/RISCV/switch_to_lookup_table-rv32.ll +++ llvm/test/Transforms/SimplifyCFG/RISCV/switch_to_lookup_table-rv32.ll @@ -112,7 +112,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_EPILOG:%.*]] ; CHECK: switch.lookup: -; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i32 [[X]], 8 +; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i32 [[X]], 8 ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 89655594, [[SWITCH_SHIFTAMT]] ; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x float], ptr @switch.table.h, i32 0, i32 [[X]] Index: llvm/test/Transforms/SimplifyCFG/RISCV/switch_to_lookup_table-rv64.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/RISCV/switch_to_lookup_table-rv64.ll +++ llvm/test/Transforms/SimplifyCFG/RISCV/switch_to_lookup_table-rv64.ll @@ -112,7 +112,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_EPILOG:%.*]] ; CHECK: switch.lookup: -; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i32 [[X]], 8 +; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i32 [[X]], 8 ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 89655594, [[SWITCH_SHIFTAMT]] ; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x float], ptr @switch.table.h, i32 0, i32 [[X]] Index: llvm/test/Transforms/SimplifyCFG/X86/CoveredLookupTable.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/X86/CoveredLookupTable.ll +++ llvm/test/Transforms/SimplifyCFG/X86/CoveredLookupTable.ll @@ -11,7 +11,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[INPUT:%.*]], -4 ; CHECK-NEXT: [[SWITCH_CAST:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i24 -; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i24 [[SWITCH_CAST]], 3 +; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i24 [[SWITCH_CAST]], 3 ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i24 7507338, [[SWITCH_SHIFTAMT]] ; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i24 [[SWITCH_DOWNSHIFT]] to i3 ; CHECK-NEXT: ret i3 [[SWITCH_MASKED]] Index: llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-large-types.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-large-types.ll +++ llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-large-types.ll @@ -25,7 +25,7 @@ ; INLINE-NEXT: start: ; INLINE-NEXT: [[TMP0:%.*]] = icmp ult i64 [[X:%.*]], 3 ; INLINE-NEXT: [[SWITCH_CAST:%.*]] = trunc i64 [[X]] to i24 -; INLINE-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i24 [[SWITCH_CAST]], 8 +; INLINE-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i24 [[SWITCH_CAST]], 8 ; INLINE-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i24 131331, [[SWITCH_SHIFTAMT]] ; INLINE-NEXT: [[SWITCH_MASKED:%.*]] = trunc i24 [[SWITCH_DOWNSHIFT]] to i8 ; INLINE-NEXT: [[COMMON_RET_OP:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_MASKED]], i8 10 @@ -69,7 +69,7 @@ ; INLINE-NEXT: start: ; INLINE-NEXT: [[TMP0:%.*]] = icmp ult i128 [[X:%.*]], 3 ; INLINE-NEXT: [[SWITCH_CAST:%.*]] = trunc i128 [[X]] to i24 -; INLINE-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i24 [[SWITCH_CAST]], 8 +; INLINE-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i24 [[SWITCH_CAST]], 8 ; INLINE-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i24 131331, [[SWITCH_SHIFTAMT]] ; INLINE-NEXT: [[SWITCH_MASKED:%.*]] = trunc i24 [[SWITCH_DOWNSHIFT]] to i8 ; INLINE-NEXT: [[COMMON_RET_OP:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_MASKED]], i8 10 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 @@ -124,7 +124,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_EPILOG:%.*]] ; CHECK: switch.lookup: -; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i32 [[X]], 8 +; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i32 [[X]], 8 ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 89655594, [[SWITCH_SHIFTAMT]] ; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x float], ptr @switch.table.h, i32 0, i32 [[X]] @@ -257,7 +257,7 @@ ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[LOR_END]] ; CHECK: switch.lookup: ; CHECK-NEXT: [[SWITCH_CAST:%.*]] = zext i8 [[SWITCH_TABLEIDX]] to i59 -; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i59 [[SWITCH_CAST]], 1 +; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i59 [[SWITCH_CAST]], 1 ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i59 -288230375765830623, [[SWITCH_SHIFTAMT]] ; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i59 [[SWITCH_DOWNSHIFT]] to i1 ; CHECK-NEXT: br label [[LOR_END]] @@ -351,7 +351,7 @@ ; CHECK-NEXT: bb: ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[TMP:%.*]], 9 ; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[TMP]] to i9 -; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i9 [[SWITCH_CAST]], 1 +; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i9 [[SWITCH_CAST]], 1 ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i9 3, [[SWITCH_SHIFTAMT]] ; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i9 [[SWITCH_DOWNSHIFT]] to i1 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_MASKED]], i1 undef @@ -1667,7 +1667,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 9 ; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[X]] to i9 -; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i9 [[SWITCH_CAST]], 1 +; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i9 [[SWITCH_CAST]], 1 ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i9 -234, [[SWITCH_SHIFTAMT]] ; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i9 [[SWITCH_DOWNSHIFT]] to i1 ; CHECK-NEXT: [[STOREMERGE:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_MASKED]], i1 false Index: llvm/test/Transforms/SimplifyCFG/rangereduce.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/rangereduce.ll +++ llvm/test/Transforms/SimplifyCFG/rangereduce.ll @@ -223,7 +223,7 @@ ; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP1]], [[TMP2]] ; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i8 [[TMP3]], 4 ; CHECK-NEXT: [[SWITCH_CAST:%.*]] = zext i8 [[TMP3]] to i32 -; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i32 [[SWITCH_CAST]], 8 +; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i32 [[SWITCH_CAST]], 8 ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 -943228976, [[SWITCH_SHIFTAMT]] ; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8 ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = select i1 [[TMP4]], i8 [[SWITCH_MASKED]], i8 -93