diff --git a/llvm/test/Transforms/InstCombine/div-shift.ll b/llvm/test/Transforms/InstCombine/div-shift.ll index 6d285ab2f0993..a2399df69d9bd 100644 --- a/llvm/test/Transforms/InstCombine/div-shift.ll +++ b/llvm/test/Transforms/InstCombine/div-shift.ll @@ -1,6 +1,13 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s +declare void @use(i8) + +declare i8 @llvm.umin.i8(i8, i8) +declare i8 @llvm.umax.i8(i8, i8) +declare i8 @llvm.smin.i8(i8, i8) +declare i8 @llvm.smax.i8(i8, i8) + define i32 @t1(i16 zeroext %x, i32 %y) { ; CHECK-LABEL: @t1( ; CHECK-NEXT: entry: @@ -99,6 +106,100 @@ define i32 @t6(i32 %x, i32 %z) { ret i32 %y } +define i8 @udiv_umin(i8 %x, i8 %y, i8 %z) { +; CHECK-LABEL: @udiv_umin( +; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]] +; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]] +; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z2]]) +; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] +; CHECK-NEXT: ret i8 [[D]] +; + %y2 = shl i8 1, %y + %z2 = shl i8 1, %z + %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z2) + %d = udiv i8 %x, %m + ret i8 %d +} + +define i8 @udiv_umax(i8 %x, i8 %y, i8 %z) { +; CHECK-LABEL: @udiv_umax( +; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]] +; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]] +; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[Y2]], i8 [[Z2]]) +; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] +; CHECK-NEXT: ret i8 [[D]] +; + %y2 = shl i8 1, %y + %z2 = shl i8 1, %z + %m = call i8 @llvm.umax.i8(i8 %y2, i8 %z2) + %d = udiv i8 %x, %m + ret i8 %d +} + +; Negative test, cannot take exact log2 +define i8 @udiv_umin_(i8 %x, i8 %y, i8 %z) { +; CHECK-LABEL: @udiv_umin_( +; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]] +; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z:%.*]]) +; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] +; CHECK-NEXT: ret i8 [[D]] +; + %y2 = shl i8 1, %y + %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z) + %d = udiv i8 %x, %m + ret i8 %d +} + +; Negative test, extra use +define i8 @udiv_umin_extra_use(i8 %x, i8 %y, i8 %z) { +; CHECK-LABEL: @udiv_umin_extra_use( +; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]] +; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]] +; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z2]]) +; CHECK-NEXT: call void @use(i8 [[M]]) +; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] +; CHECK-NEXT: ret i8 [[D]] +; + %y2 = shl i8 1, %y + %z2 = shl i8 1, %z + %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z2) + call void @use(i8 %m) + %d = udiv i8 %x, %m + ret i8 %d +} + +; Negative test, signed min/max +define i8 @udiv_smin(i8 %x, i8 %y, i8 %z) { +; CHECK-LABEL: @udiv_smin( +; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]] +; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]] +; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smin.i8(i8 [[Y2]], i8 [[Z2]]) +; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] +; CHECK-NEXT: ret i8 [[D]] +; + %y2 = shl i8 1, %y + %z2 = shl i8 1, %z + %m = call i8 @llvm.smin.i8(i8 %y2, i8 %z2) + %d = udiv i8 %x, %m + ret i8 %d +} + +; Negative test, signed min/max +define i8 @udiv_smax(i8 %x, i8 %y, i8 %z) { +; CHECK-LABEL: @udiv_smax( +; CHECK-NEXT: [[Y2:%.*]] = shl i8 1, [[Y:%.*]] +; CHECK-NEXT: [[Z2:%.*]] = shl i8 1, [[Z:%.*]] +; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[Y2]], i8 [[Z2]]) +; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] +; CHECK-NEXT: ret i8 [[D]] +; + %y2 = shl i8 1, %y + %z2 = shl i8 1, %z + %m = call i8 @llvm.smax.i8(i8 %y2, i8 %z2) + %d = udiv i8 %x, %m + ret i8 %d +} + ; (X << C1) / X -> 1 << C1 optimizations define i32 @t7(i32 %x) {