[llvm] c4fc2cb - [instcombine] umin(x, 1) == zext(x != 0)
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 30 10:20:14 PDT 2021
Author: Philip Reames
Date: 2021-06-30T10:20:01-07:00
New Revision: c4fc2cb5b2d98125e9035d9498640c7d6f17c8da
URL: https://github.com/llvm/llvm-project/commit/c4fc2cb5b2d98125e9035d9498640c7d6f17c8da
DIFF: https://github.com/llvm/llvm-project/commit/c4fc2cb5b2d98125e9035d9498640c7d6f17c8da.diff
LOG: [instcombine] umin(x, 1) == zext(x != 0)
We already implemented this for the select form, but the intrinsic form was missing. Note that this doesn't change poison behavior as 1 is non-poison, and the optimized form is still poison exactly when x is.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 552de8b072e39..5060b45ad6b7f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -956,8 +956,17 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
break;
}
- case Intrinsic::umax:
case Intrinsic::umin: {
+ Value *I0 = II->getArgOperand(0), *I1 = II->getArgOperand(1);
+ // umin(x, 1) == zext(x != 0)
+ if (match(I1, m_One())) {
+ Value *Zero = Constant::getNullValue(I0->getType());
+ Value *Cmp = Builder.CreateICmpNE(I0, Zero);
+ return CastInst::Create(Instruction::ZExt, Cmp, II->getType());
+ }
+ LLVM_FALLTHROUGH;
+ }
+ case Intrinsic::umax: {
Value *I0 = II->getArgOperand(0), *I1 = II->getArgOperand(1);
Value *X, *Y;
if (match(I0, m_ZExt(m_Value(X))) && match(I1, m_ZExt(m_Value(Y))) &&
diff --git a/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll b/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
index 3b2279a92bf7c..0dd429cb589ef 100644
--- a/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
@@ -817,3 +817,44 @@ define i8 @clamp_two_vals_smin_smax_edge(i8 %x) {
%r = call i8 @llvm.smax.i8(i8 %m, i8 127)
ret i8 %r
}
+
+
+define i8 @umin_non_zero_idiom1(i8 %a) {
+; CHECK-LABEL: @umin_non_zero_idiom1(
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[A:%.*]], 0
+; CHECK-NEXT: [[RES:%.*]] = zext i1 [[TMP1]] to i8
+; CHECK-NEXT: ret i8 [[RES]]
+;
+ %res = call i8 @llvm.umin.i8(i8 %a, i8 1)
+ ret i8 %res
+}
+
+define i8 @umin_non_zero_idiom2(i8 %a) {
+; CHECK-LABEL: @umin_non_zero_idiom2(
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[A:%.*]], 0
+; CHECK-NEXT: [[RES:%.*]] = zext i1 [[TMP1]] to i8
+; CHECK-NEXT: ret i8 [[RES]]
+;
+ %res = call i8 @llvm.umin.i8(i8 1, i8 %a)
+ ret i8 %res
+}
+
+define <3 x i8> @umin_non_zero_idiom3(<3 x i8> %a) {
+; CHECK-LABEL: @umin_non_zero_idiom3(
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <3 x i8> [[A:%.*]], zeroinitializer
+; CHECK-NEXT: [[RES:%.*]] = zext <3 x i1> [[TMP1]] to <3 x i8>
+; CHECK-NEXT: ret <3 x i8> [[RES]]
+;
+ %res = call <3 x i8> @llvm.umin.v3i8(<3 x i8> %a, <3 x i8> <i8 1, i8 1, i8 1>)
+ ret <3 x i8> %res
+}
+
+define <3 x i8> @umin_non_zero_idiom4(<3 x i8> %a) {
+; CHECK-LABEL: @umin_non_zero_idiom4(
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <3 x i8> [[A:%.*]], zeroinitializer
+; CHECK-NEXT: [[RES:%.*]] = zext <3 x i1> [[TMP1]] to <3 x i8>
+; CHECK-NEXT: ret <3 x i8> [[RES]]
+;
+ %res = call <3 x i8> @llvm.umin.v3i8(<3 x i8> %a, <3 x i8> <i8 1, i8 undef, i8 undef>)
+ ret <3 x i8> %res
+}
More information about the llvm-commits
mailing list