[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