diff --git a/llvm/test/Transforms/InstSimplify/minmax-intrin.ll b/llvm/test/Transforms/InstSimplify/minmax-intrin.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstSimplify/minmax-intrin.ll @@ -0,0 +1,140 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instsimplify -S | FileCheck %s + +declare i8 @llvm.umax.i8(i8, i8) +declare i8 @llvm.smax.i8(i8, i8) +declare i8 @llvm.umin.i8(i8, i8) +declare i8 @llvm.smin.i8(i8, i8) +declare i8 @llvm.sadd.sat.i8(i8, i8) +declare i8 @llvm.uadd.sat.i8(i8, i8) +declare i8 @llvm.ssub.sat.i8(i8, i8) +declare i8 @llvm.usub.sat.i8(i8, i8) +declare i8 @llvm.abs.i8(i8, i1) + +declare <2 x i8> @llvm.abs.v2i8(<2 x i8>, i1) +declare <2 x i8> @llvm.smax.v2i8(<2 x i8>, <2 x i8>) +declare <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8>, <2 x i8>) +declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>) +declare <2 x i8> @llvm.umax.v2i8(<2 x i8>, <2 x i8>) +declare <2 x i8> @llvm.umin.v2i8(<2 x i8>, <2 x i8>) + +define <2 x i8> @umax_uadd_sat(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @umax_uadd_sat( +; CHECK-NEXT: [[XX:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call <2 x i8> @llvm.umax.v2i8(<2 x i8> [[X]], <2 x i8> [[XX]]) +; CHECK-NEXT: ret <2 x i8> [[RET]] +; + %xx = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %x, <2 x i8> %y) + %ret = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %x, <2 x i8> %xx) + ret <2 x i8> %ret +} + +define i8 @umin_uadd_sat(i8 %x, i8 %y) { +; CHECK-LABEL: @umin_uadd_sat( +; CHECK-NEXT: [[XX:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umin.i8(i8 [[XX]], i8 [[X]]) +; CHECK-NEXT: ret i8 [[RET]] +; + %xx = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y) + %ret = call i8 @llvm.umin.i8(i8 %xx, i8 %x) + ret i8 %ret +} + +define i8 @umax_usub_sat(i8 %x, i8 %y) { +; CHECK-LABEL: @umax_usub_sat( +; CHECK-NEXT: [[XX:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 [[XX]]) +; CHECK-NEXT: ret i8 [[RET]] +; + %xx = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y) + %ret = call i8 @llvm.umax.i8(i8 %x, i8 %xx) + ret i8 %ret +} + +define <2 x i8> @umin_usub_sat(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @umin_usub_sat( +; CHECK-NEXT: [[XX:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X]], <2 x i8> [[XX]]) +; CHECK-NEXT: ret <2 x i8> [[RET]] +; + %xx = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %x, <2 x i8> %y) + %ret = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> %xx) + ret <2 x i8> %ret +} + +define <2 x i8> @umax_usub_sat_fail_mismatch(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { +; CHECK-LABEL: @umax_usub_sat_fail_mismatch( +; CHECK-NEXT: [[XX:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call <2 x i8> @llvm.umax.v2i8(<2 x i8> [[Z:%.*]], <2 x i8> [[XX]]) +; CHECK-NEXT: ret <2 x i8> [[RET]] +; + %xx = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %x, <2 x i8> %y) + %ret = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %z, <2 x i8> %xx) + ret <2 x i8> %ret +} + +define i8 @smin_usub_sat_fail(i8 %x, i8 %y) { +; CHECK-LABEL: @smin_usub_sat_fail( +; CHECK-NEXT: [[XX:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 [[XX]]) +; CHECK-NEXT: ret i8 [[RET]] +; + %xx = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y) + %ret = call i8 @llvm.smin.i8(i8 %x, i8 %xx) + ret i8 %ret +} + +define i8 @umax_absT(i8 %x) { +; CHECK-LABEL: @umax_absT( +; CHECK-NEXT: [[XX:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true) +; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umax.i8(i8 [[XX]], i8 [[X]]) +; CHECK-NEXT: ret i8 [[RET]] +; + %xx = call i8 @llvm.abs.i8(i8 %x, i1 true) + %ret = call i8 @llvm.umax.i8(i8 %xx, i8 %x) + ret i8 %ret +} + +define i8 @umax_absT_fail_mismatch(i8 %x, i8 %y) { +; CHECK-LABEL: @umax_absT_fail_mismatch( +; CHECK-NEXT: [[XX:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true) +; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[XX]]) +; CHECK-NEXT: ret i8 [[RET]] +; + %xx = call i8 @llvm.abs.i8(i8 %x, i1 true) + %ret = call i8 @llvm.umax.i8(i8 %y, i8 %xx) + ret i8 %ret +} + +define <2 x i8> @umin_absF(<2 x i8> %x) { +; CHECK-LABEL: @umin_absF( +; CHECK-NEXT: [[XX:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[X:%.*]], i1 false) +; CHECK-NEXT: [[RET:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X]], <2 x i8> [[XX]]) +; CHECK-NEXT: ret <2 x i8> [[RET]] +; + %xx = call <2 x i8> @llvm.abs.v2i8(<2 x i8> %x, i1 false) + %ret = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> %xx) + ret <2 x i8> %ret +} + +define i8 @smax_absT(i8 %x) { +; CHECK-LABEL: @smax_absT( +; CHECK-NEXT: [[XX:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true) +; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 [[XX]]) +; CHECK-NEXT: ret i8 [[RET]] +; + %xx = call i8 @llvm.abs.i8(i8 %x, i1 true) + %ret = call i8 @llvm.smax.i8(i8 %x, i8 %xx) + ret i8 %ret +} + +define i8 @smin_absF(i8 %x) { +; CHECK-LABEL: @smin_absF( +; CHECK-NEXT: [[XX:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false) +; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.smin.i8(i8 [[XX]], i8 [[X]]) +; CHECK-NEXT: ret i8 [[RET]] +; + %xx = call i8 @llvm.abs.i8(i8 %x, i1 false) + %ret = call i8 @llvm.smin.i8(i8 %xx, i8 %x) + ret i8 %ret +}