Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -6126,10 +6126,13 @@ // Derive the result value from the input value. Value *Result = Builder.CreateIntCast(Index, LinearMultiplier->getType(), false, "switch.idx.cast"); + // TODO: find when is (not) nuw/nsw if (!LinearMultiplier->isOne()) - Result = Builder.CreateMul(Result, LinearMultiplier, "switch.idx.mult"); + Result = Builder.CreateMul(Result, LinearMultiplier, "switch.idx.mult", + true, true); if (!LinearOffset->isZero()) - Result = Builder.CreateAdd(Result, LinearOffset, "switch.offset"); + Result = + Builder.CreateAdd(Result, LinearOffset, "switch.offset", true, true); return Result; } case BitMapKind: { @@ -6142,9 +6145,10 @@ Value *ShiftAmt = Builder.CreateZExtOrTrunc(Index, MapTy, "switch.cast"); // Multiply the shift amount by the element width. + // TODO: find when is(not) nuw/nsw ShiftAmt = Builder.CreateMul( ShiftAmt, ConstantInt::get(MapTy, BitMapElementTy->getBitWidth()), - "switch.shiftamt"); + "switch.shiftamt", true, true); // Shift down. Value *DownShifted = @@ -6497,8 +6501,9 @@ TableIndex = SI->getCondition(); } else { TableIndexOffset = MinCaseVal; - TableIndex = - Builder.CreateSub(SI->getCondition(), TableIndexOffset, "switch.tableidx"); + // TODO: find when is (not) nuw/nsw + TableIndex = Builder.CreateSub(SI->getCondition(), TableIndexOffset, + "switch.tableidx", true, true); } // Compute the maximum table size representable by the integer type we are Index: llvm/test/CodeGen/Thumb2/LowOverheadLoops/mve-float-loops.ll =================================================================== --- llvm/test/CodeGen/Thumb2/LowOverheadLoops/mve-float-loops.ll +++ llvm/test/CodeGen/Thumb2/LowOverheadLoops/mve-float-loops.ll @@ -4,7 +4,7 @@ define arm_aapcs_vfpcc void @float_float_mul(ptr nocapture readonly %a, ptr nocapture readonly %b, ptr nocapture %c, i32 %N) { ; CHECK-LABEL: float_float_mul: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: push {r4, r5, r6, r7, lr} +; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, lr} ; CHECK-NEXT: cmp r3, #0 ; CHECK-NEXT: beq .LBB0_10 ; CHECK-NEXT: @ %bb.1: @ %for.body.preheader @@ -32,23 +32,24 @@ ; CHECK-NEXT: beq .LBB0_11 ; CHECK-NEXT: .LBB0_4: @ %for.body.preheader22 ; CHECK-NEXT: mvn.w r7, r12 -; CHECK-NEXT: adds r4, r7, r3 -; CHECK-NEXT: and r7, r3, #3 -; CHECK-NEXT: wls lr, r7, .LBB0_7 +; CHECK-NEXT: add.w r8, r7, r3 +; CHECK-NEXT: and r5, r3, #3 +; CHECK-NEXT: wls lr, r5, .LBB0_7 ; CHECK-NEXT: @ %bb.5: @ %for.body.prol.preheader +; CHECK-NEXT: add.w r4, r12, r5 ; CHECK-NEXT: add.w r5, r0, r12, lsl #2 ; CHECK-NEXT: add.w r6, r1, r12, lsl #2 ; CHECK-NEXT: add.w r7, r2, r12, lsl #2 +; CHECK-NEXT: mov r12, r4 ; CHECK-NEXT: .LBB0_6: @ %for.body.prol ; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: vldmia r6!, {s0} -; CHECK-NEXT: add.w r12, r12, #1 ; CHECK-NEXT: vldmia r5!, {s2} ; CHECK-NEXT: vmul.f32 s0, s2, s0 ; CHECK-NEXT: vstmia r7!, {s0} ; CHECK-NEXT: le lr, .LBB0_6 ; CHECK-NEXT: .LBB0_7: @ %for.body.prol.loopexit -; CHECK-NEXT: cmp r4, #3 +; CHECK-NEXT: cmp.w r8, #3 ; CHECK-NEXT: blo .LBB0_10 ; CHECK-NEXT: @ %bb.8: @ %for.body.preheader1 ; CHECK-NEXT: sub.w r3, r3, r12 @@ -80,7 +81,7 @@ ; CHECK-NEXT: vstr s0, [r5, #12] ; CHECK-NEXT: bne .LBB0_9 ; CHECK-NEXT: .LBB0_10: @ %for.cond.cleanup -; CHECK-NEXT: pop {r4, r5, r6, r7, pc} +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, pc} ; CHECK-NEXT: .LBB0_11: @ %vector.ph ; CHECK-NEXT: bic r12, r3, #3 ; CHECK-NEXT: movs r6, #1 @@ -214,7 +215,7 @@ define arm_aapcs_vfpcc void @float_float_add(ptr nocapture readonly %a, ptr nocapture readonly %b, ptr nocapture %c, i32 %N) { ; CHECK-LABEL: float_float_add: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: push {r4, r5, r6, r7, lr} +; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, lr} ; CHECK-NEXT: cmp r3, #0 ; CHECK-NEXT: beq .LBB1_10 ; CHECK-NEXT: @ %bb.1: @ %for.body.preheader @@ -242,23 +243,24 @@ ; CHECK-NEXT: beq .LBB1_11 ; CHECK-NEXT: .LBB1_4: @ %for.body.preheader22 ; CHECK-NEXT: mvn.w r7, r12 -; CHECK-NEXT: adds r4, r7, r3 -; CHECK-NEXT: and r7, r3, #3 -; CHECK-NEXT: wls lr, r7, .LBB1_7 +; CHECK-NEXT: add.w r8, r7, r3 +; CHECK-NEXT: and r5, r3, #3 +; CHECK-NEXT: wls lr, r5, .LBB1_7 ; CHECK-NEXT: @ %bb.5: @ %for.body.prol.preheader +; CHECK-NEXT: add.w r4, r12, r5 ; CHECK-NEXT: add.w r5, r0, r12, lsl #2 ; CHECK-NEXT: add.w r6, r1, r12, lsl #2 ; CHECK-NEXT: add.w r7, r2, r12, lsl #2 +; CHECK-NEXT: mov r12, r4 ; CHECK-NEXT: .LBB1_6: @ %for.body.prol ; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: vldmia r6!, {s0} -; CHECK-NEXT: add.w r12, r12, #1 ; CHECK-NEXT: vldmia r5!, {s2} ; CHECK-NEXT: vadd.f32 s0, s2, s0 ; CHECK-NEXT: vstmia r7!, {s0} ; CHECK-NEXT: le lr, .LBB1_6 ; CHECK-NEXT: .LBB1_7: @ %for.body.prol.loopexit -; CHECK-NEXT: cmp r4, #3 +; CHECK-NEXT: cmp.w r8, #3 ; CHECK-NEXT: blo .LBB1_10 ; CHECK-NEXT: @ %bb.8: @ %for.body.preheader1 ; CHECK-NEXT: sub.w r3, r3, r12 @@ -290,7 +292,7 @@ ; CHECK-NEXT: vstr s0, [r5, #12] ; CHECK-NEXT: bne .LBB1_9 ; CHECK-NEXT: .LBB1_10: @ %for.cond.cleanup -; CHECK-NEXT: pop {r4, r5, r6, r7, pc} +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, pc} ; CHECK-NEXT: .LBB1_11: @ %vector.ph ; CHECK-NEXT: bic r12, r3, #3 ; CHECK-NEXT: movs r6, #1 @@ -424,7 +426,7 @@ define arm_aapcs_vfpcc void @float_float_sub(ptr nocapture readonly %a, ptr nocapture readonly %b, ptr nocapture %c, i32 %N) { ; CHECK-LABEL: float_float_sub: ; CHECK: @ %bb.0: @ %entry -; CHECK-NEXT: push {r4, r5, r6, r7, lr} +; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, lr} ; CHECK-NEXT: cmp r3, #0 ; CHECK-NEXT: beq .LBB2_10 ; CHECK-NEXT: @ %bb.1: @ %for.body.preheader @@ -452,23 +454,24 @@ ; CHECK-NEXT: beq .LBB2_11 ; CHECK-NEXT: .LBB2_4: @ %for.body.preheader22 ; CHECK-NEXT: mvn.w r7, r12 -; CHECK-NEXT: adds r4, r7, r3 -; CHECK-NEXT: and r7, r3, #3 -; CHECK-NEXT: wls lr, r7, .LBB2_7 +; CHECK-NEXT: add.w r8, r7, r3 +; CHECK-NEXT: and r5, r3, #3 +; CHECK-NEXT: wls lr, r5, .LBB2_7 ; CHECK-NEXT: @ %bb.5: @ %for.body.prol.preheader +; CHECK-NEXT: add.w r4, r12, r5 ; CHECK-NEXT: add.w r5, r0, r12, lsl #2 ; CHECK-NEXT: add.w r6, r1, r12, lsl #2 ; CHECK-NEXT: add.w r7, r2, r12, lsl #2 +; CHECK-NEXT: mov r12, r4 ; CHECK-NEXT: .LBB2_6: @ %for.body.prol ; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: vldmia r6!, {s0} -; CHECK-NEXT: add.w r12, r12, #1 ; CHECK-NEXT: vldmia r5!, {s2} ; CHECK-NEXT: vsub.f32 s0, s2, s0 ; CHECK-NEXT: vstmia r7!, {s0} ; CHECK-NEXT: le lr, .LBB2_6 ; CHECK-NEXT: .LBB2_7: @ %for.body.prol.loopexit -; CHECK-NEXT: cmp r4, #3 +; CHECK-NEXT: cmp.w r8, #3 ; CHECK-NEXT: blo .LBB2_10 ; CHECK-NEXT: @ %bb.8: @ %for.body.preheader1 ; CHECK-NEXT: sub.w r3, r3, r12 @@ -500,7 +503,7 @@ ; CHECK-NEXT: vstr s0, [r5, #12] ; CHECK-NEXT: bne .LBB2_9 ; CHECK-NEXT: .LBB2_10: @ %for.cond.cleanup -; CHECK-NEXT: pop {r4, r5, r6, r7, pc} +; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, pc} ; CHECK-NEXT: .LBB2_11: @ %vector.ph ; CHECK-NEXT: bic r12, r3, #3 ; CHECK-NEXT: movs r6, #1 @@ -672,16 +675,17 @@ ; CHECK-NEXT: .LBB3_7: @ %for.body.preheader16 ; CHECK-NEXT: mvn.w r7, r12 ; CHECK-NEXT: add.w r8, r7, r3 -; CHECK-NEXT: and r7, r3, #3 -; CHECK-NEXT: wls lr, r7, .LBB3_10 +; CHECK-NEXT: and r5, r3, #3 +; CHECK-NEXT: wls lr, r5, .LBB3_10 ; CHECK-NEXT: @ %bb.8: @ %for.body.prol.preheader +; CHECK-NEXT: add.w r4, r12, r5 ; CHECK-NEXT: add.w r5, r0, r12, lsl #2 ; CHECK-NEXT: add.w r6, r1, r12, lsl #2 ; CHECK-NEXT: add.w r7, r2, r12, lsl #2 +; CHECK-NEXT: mov r12, r4 ; CHECK-NEXT: .LBB3_9: @ %for.body.prol ; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ldr r4, [r6], #4 -; CHECK-NEXT: add.w r12, r12, #1 ; CHECK-NEXT: vldmia r5!, {s2} ; CHECK-NEXT: vmov s0, r4 ; CHECK-NEXT: vcvt.f32.s32 s0, s0 Index: llvm/test/Transforms/PhaseOrdering/X86/merge-functions.ll =================================================================== --- llvm/test/Transforms/PhaseOrdering/X86/merge-functions.ll +++ llvm/test/Transforms/PhaseOrdering/X86/merge-functions.ll @@ -10,7 +10,7 @@ define i1 @test1(i32 %c) { ; CHECK-LABEL: @test1( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = add i32 [[C:%.*]], -100 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = add nsw i32 [[C:%.*]], -100 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 20 ; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i20 ; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i20 -490991, [[SWITCH_CAST]] Index: llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-late.ll =================================================================== --- llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-late.ll +++ llvm/test/Transforms/PhaseOrdering/X86/simplifycfg-late.ll @@ -9,7 +9,7 @@ define i32 @f(i32 %c) { ; CHECK-LABEL: @f( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = add i32 [[C:%.*]], -42 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = add nsw i32 [[C:%.*]], -42 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] ; CHECK: switch.lookup: 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 @@ -24,7 +24,7 @@ define i32 @f(i32 %c) { ; CHECK-LABEL: @f( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[C:%.*]], 42 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] ; CHECK: switch.lookup: @@ -64,7 +64,7 @@ define i8 @char(i32 %c) { ; CHECK-LABEL: @char( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[C:%.*]], 42 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 9 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] ; CHECK: switch.lookup: @@ -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 @@ -24,7 +24,7 @@ define i32 @f(i32 %c) { ; CHECK-LABEL: @f( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[C:%.*]], 42 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] ; CHECK: switch.lookup: @@ -64,7 +64,7 @@ define i8 @char(i32 %c) { ; CHECK-LABEL: @char( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[C:%.*]], 42 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 9 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] ; CHECK: switch.lookup: @@ -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 @@ -9,9 +9,9 @@ define i3 @coveredswitch_test(i3 %input) { ; CHECK-LABEL: @coveredswitch_test( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[INPUT:%.*]], -4 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw 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/disable-lookup-table.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/X86/disable-lookup-table.ll +++ llvm/test/Transforms/SimplifyCFG/X86/disable-lookup-table.ll @@ -46,7 +46,7 @@ define i32 @bar(i32 %c) { ; CHECK-LABEL: @bar( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[C:%.*]], 42 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] ; CHECK: switch.lookup: Index: llvm/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll +++ llvm/test/Transforms/SimplifyCFG/X86/switch-covered-bug.ll @@ -9,7 +9,7 @@ define i64 @test(i3 %arg) { ; CHECK-LABEL: @test( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[ARG:%.*]], -4 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i3 [[ARG:%.*]], -4 ; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i4 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i64], ptr @switch.table.test, i32 0, i4 [[SWITCH_TABLEIDX_ZEXT]] ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i64, ptr [[SWITCH_GEP]], align 8 Index: llvm/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll +++ llvm/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll @@ -9,7 +9,7 @@ define i64 @_TFO6reduce1E5toRawfS0_FT_Si(i2) { ; CHECK-LABEL: @_TFO6reduce1E5toRawfS0_FT_Si( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TMP0:%.*]], -2 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i2 [[TMP0:%.*]], -2 ; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i3 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i64], ptr @switch.table._TFO6reduce1E5toRawfS0_FT_Si, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]] ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i64, ptr [[SWITCH_GEP]], align 8 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 @@ -36,7 +36,7 @@ define i32 @f(i32 %c) { ; CHECK-LABEL: @f( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[C:%.*]], 42 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] ; CHECK: switch.lookup: @@ -76,7 +76,7 @@ define i8 @char(i32 %c) { ; CHECK-LABEL: @char( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[C:%.*]], 42 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 9 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] ; CHECK: switch.lookup: @@ -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]] @@ -252,12 +252,12 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[C:%.*]], 33 ; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[SWITCH_EARLY_TEST:%.*]] ; CHECK: switch.early.test: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i8 [[C]], 34 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i8 [[C]], 34 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[SWITCH_TABLEIDX]], 59 ; 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 @@ -382,7 +382,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X]], -10 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 [[MUL]], i32 [[X]] -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[SPEC_SELECT]], 1 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[SPEC_SELECT]], 1 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 199 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] ; CHECK: switch.lookup: @@ -813,7 +813,7 @@ define i32 @cprop(i32 %x, i32 %y) { ; CHECK-LABEL: @cprop( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[X:%.*]], 1 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[X:%.*]], 1 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7 ; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]] ; CHECK: switch.lookup: @@ -1220,11 +1220,11 @@ define i8 @linearmap1(i32 %c) { ; CHECK-LABEL: @linearmap1( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[C:%.*]], 10 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 ; 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_OFFSET:%.*]] = add i8 [[SWITCH_IDX_MULT]], 18 +; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul nuw nsw i8 [[SWITCH_IDX_CAST]], -5 +; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nuw nsw i8 [[SWITCH_IDX_MULT]], 18 ; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_OFFSET]], i8 3 ; CHECK-NEXT: ret i8 [[X]] ; @@ -1248,10 +1248,10 @@ define i32 @linearmap2(i8 %c) { ; CHECK-LABEL: @linearmap2( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i8 [[C:%.*]], -13 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i8 [[C:%.*]], -13 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[SWITCH_TABLEIDX]], 4 ; 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 nuw nsw i32 [[SWITCH_IDX_CAST]], 18 ; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 3 ; CHECK-NEXT: ret i32 [[X]] ; @@ -1275,10 +1275,10 @@ define i8 @linearmap3(i32 %c) { ; CHECK-LABEL: @linearmap3( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[C:%.*]], 10 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 ; 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 nuw nsw i8 [[SWITCH_IDX_CAST]], 100 ; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_IDX_MULT]], i8 3 ; CHECK-NEXT: ret i8 [[X]] ; @@ -1302,7 +1302,7 @@ define i8 @linearmap4(i32 %c) { ; CHECK-LABEL: @linearmap4( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], -2 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[C:%.*]], -2 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4 ; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8 ; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_IDX_CAST]], i8 3 @@ -1330,7 +1330,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 ; CHECK-NEXT: [[INVERTED_CMP:%.*]] = xor i1 [[TMP0]], true -; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[X]], 10 +; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nuw nsw i32 [[X]], 10 ; CHECK-NEXT: [[R_0:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 0 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[R_0]], 0 ; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[INVERTED_CMP]], i32 100, i32 [[R_0]] @@ -1398,7 +1398,7 @@ ; CHECK-LABEL: @no_reuse_cmp( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 -; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[X]], 10 +; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nuw nsw i32 [[X]], 10 ; CHECK-NEXT: [[R_0:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 12 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[R_0]], 0 ; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[CMP]], i32 [[R_0]], i32 100 @@ -1434,7 +1434,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[EC:%.*]] = icmp ne i32 [[Y:%.*]], 0 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 -; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[X]], 10 +; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nuw nsw i32 [[X]], 10 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 0 ; CHECK-NEXT: [[R_0:%.*]] = select i1 [[EC]], i32 [[SPEC_SELECT]], i32 100 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[R_0]], 0 @@ -1538,7 +1538,7 @@ 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_TABLEIDX:%.*]] = sub nuw nsw 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 @@ -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 @@ -1696,7 +1696,7 @@ ; 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:%.*]] = sub nuw nsw i2 [[TRUNC]], -2 ; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i3 ; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], ptr @switch.table.signed_overflow1, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]] ; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4 @@ -1776,10 +1776,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_TABLEIDX:%.*]] = sub nuw nsw 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: [[SWITCH_IDX_MULT:%.*]] = mul nuw nsw i32 [[SWITCH_IDX_CAST]], 1111 +; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nuw nsw i32 [[SWITCH_IDX_MULT]], 1111 ; CHECK-NEXT: ret i32 [[SWITCH_OFFSET]] ; start: Index: llvm/test/Transforms/SimplifyCFG/rangereduce.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/rangereduce.ll +++ llvm/test/Transforms/SimplifyCFG/rangereduce.ll @@ -78,7 +78,7 @@ ; Optimization shouldn't trigger; no holes present define i32 @test3(i32 %a) { ; CHECK-LABEL: @test3( -; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[A:%.*]], 97 +; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub nuw nsw i32 [[A:%.*]], 97 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 3 ; CHECK-NEXT: br i1 [[TMP1]], label [[SWITCH_LOOKUP:%.*]], label [[COMMON_RET:%.*]] ; CHECK: switch.lookup: @@ -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