diff --git a/llvm/test/Transforms/InstCombine/ashr-lshr.ll b/llvm/test/Transforms/InstCombine/ashr-lshr.ll index c2a4f35412670b..36752036383ebd 100644 --- a/llvm/test/Transforms/InstCombine/ashr-lshr.ll +++ b/llvm/test/Transforms/InstCombine/ashr-lshr.ll @@ -627,6 +627,17 @@ define i32 @lshr_mul_times_3_div_2_exact(i32 %x) { ret i32 %lshr } +define i32 @reduce_shift(i32 %x) { +; CHECK-LABEL: @reduce_shift( +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 12 +; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[MUL]], 4 +; CHECK-NEXT: ret i32 [[SHR]] +; + %mul = mul nsw i32 %x, 12 + %shr = ashr i32 %mul, 4 + ret i32 %shr +} + ; Negative test define i32 @lshr_mul_times_3_div_2_no_flags(i32 %0) { @@ -640,6 +651,17 @@ define i32 @lshr_mul_times_3_div_2_no_flags(i32 %0) { ret i32 %lshr } +define i32 @reduce_shift_no_nsw(i32 %x) { +; CHECK-LABEL: @reduce_shift_no_nsw( +; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 12 +; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[MUL]], 4 +; CHECK-NEXT: ret i32 [[SHR]] +; + %mul = mul nuw i32 %x, 12 + %shr = ashr i32 %mul, 4 + ret i32 %shr +} + ; Negative test define i32 @mul_times_3_div_2_multiuse_lshr(i32 %x) { @@ -863,3 +885,24 @@ define i32 @ashr_mul_times_5_div_4_exact_2(i32 %x) { } declare void @use(i32) +define i32 @reduce_shift_wrong_mul(i32 %x) { +; CHECK-LABEL: @reduce_shift_wrong_mul( +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 11 +; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[MUL]], 4 +; CHECK-NEXT: ret i32 [[SHR]] +; + %mul = mul nsw i32 %x, 11 + %shr = ashr i32 %mul, 4 + ret i32 %shr +} + +define i32 @reduce_shift_exact(i32 %x) { +; CHECK-LABEL: @reduce_shift_exact( +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 12 +; CHECK-NEXT: [[SHR:%.*]] = ashr exact i32 [[MUL]], 4 +; CHECK-NEXT: ret i32 [[SHR]] +; + %mul = mul nsw i32 %x, 12 + %shr = ashr exact i32 %mul, 4 + ret i32 %shr +} diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll index 01e07985ba6ab5..2c7c89ee1a4869 100644 --- a/llvm/test/Transforms/InstCombine/lshr.ll +++ b/llvm/test/Transforms/InstCombine/lshr.ll @@ -1523,3 +1523,51 @@ define <2 x i8> @bool_add_lshr_vec_wrong_shift_amt(<2 x i1> %a, <2 x i1> %b) { %lshr = lshr <2 x i8> %add, ret <2 x i8> %lshr } + +define i32 @reduce_shift(i32 %x) { +; CHECK-LABEL: @reduce_shift( +; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 12 +; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[MUL]], 4 +; CHECK-NEXT: ret i32 [[SHR]] +; + %mul = mul nuw i32 %x, 12 + %shr = lshr i32 %mul, 4 + ret i32 %shr +} + +; Negative test + +define i32 @reduce_shift_no_nuw(i32 %x) { +; CHECK-LABEL: @reduce_shift_no_nuw( +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 12 +; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[MUL]], 4 +; CHECK-NEXT: ret i32 [[SHR]] +; + %mul = mul nsw i32 %x, 12 + %shr = lshr i32 %mul, 4 + ret i32 %shr +} + +; Negative test + +define i32 @reduce_shift_wrong_mul(i32 %x) { +; CHECK-LABEL: @reduce_shift_wrong_mul( +; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 11 +; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[MUL]], 4 +; CHECK-NEXT: ret i32 [[SHR]] +; + %mul = mul nuw i32 %x, 11 + %shr = lshr i32 %mul, 4 + ret i32 %shr +} + +define i32 @reduce_shift_exact(i32 %x) { +; CHECK-LABEL: @reduce_shift_exact( +; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 12 +; CHECK-NEXT: [[SHR:%.*]] = lshr exact i32 [[MUL]], 4 +; CHECK-NEXT: ret i32 [[SHR]] +; + %mul = mul nuw i32 %x, 12 + %shr = lshr exact i32 %mul, 4 + ret i32 %shr +}