[PATCH] D104038: [InstCombine] Check if zext src and trunc dst have same types

Datta Nagraj via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 10 08:05:43 PDT 2021


datta.nagraj created this revision.
Herald added a subscriber: hiraditya.
datta.nagraj requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Apply the opt only if zext src and trunc dst have same type and
do it only for datatypes of width more than 5, as for width less
than 6, this opt fails:

https://alive2.llvm.org/ce/z/5ThC64

The opt to be applied when width is less than 6 is shown here:

https://alive2.llvm.org/ce/z/ZtZm4w


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D104038

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
  llvm/test/Transforms/InstCombine/zext-ctlz-trunc-to-ctlz-add.ll


Index: llvm/test/Transforms/InstCombine/zext-ctlz-trunc-to-ctlz-add.ll
===================================================================
--- llvm/test/Transforms/InstCombine/zext-ctlz-trunc-to-ctlz-add.ll
+++ llvm/test/Transforms/InstCombine/zext-ctlz-trunc-to-ctlz-add.ll
@@ -71,8 +71,8 @@
 define <vscale x 2 x i16> @trunc_ctlz_zext_nxv2i16_nxv2i63_multiple_uses(<vscale x 2 x i16> %x) {
 ; CHECK-LABEL: @trunc_ctlz_zext_nxv2i16_nxv2i63_multiple_uses(
 ; CHECK-NEXT:    [[Z:%.*]] = zext <vscale x 2 x i16> [[X:%.*]] to <vscale x 2 x i63>
-; CHECK-NEXT:    [[P:%.*]] = call <vscale x 2 x i63> @llvm.ctlz.nxv2i63(<vscale x 2 x i63> [[Z]], i1 true)
-; CHECK-NEXT:    [[ZZ:%.*]] = trunc <vscale x 2 x i63> [[P]] to <vscale x 2 x i16>
+; CHECK-NEXT:    [[TMP1:%.*]] = call <vscale x 2 x i16> @llvm.ctlz.nxv2i16(<vscale x 2 x i16> [[X]], i1 true)
+; CHECK-NEXT:    [[ZZ:%.*]] = add nuw nsw <vscale x 2 x i16> [[TMP1]], shufflevector (<vscale x 2 x i16> insertelement (<vscale x 2 x i16> undef, i16 47, i32 0), <vscale x 2 x i16> undef, <vscale x 2 x i32> zeroinitializer)
 ; CHECK-NEXT:    call void @use1(<vscale x 2 x i63> [[Z]])
 ; CHECK-NEXT:    ret <vscale x 2 x i16> [[ZZ]]
 ;
@@ -83,3 +83,33 @@
   ret <vscale x 2 x i16> %zz
 }
 
+; Negative case where types of x and zz don't match
+
+define i16 @trunc_ctlz_zext_i10_i32(i10 %x) {
+; CHECK-LABEL: @trunc_ctlz_zext_i10_i32(
+; CHECK-NEXT:    [[Z:%.*]] = zext i10 [[X:%.*]] to i32
+; CHECK-NEXT:    [[P:%.*]] = call i32 @llvm.ctlz.i32(i32 [[Z]], i1 false), !range [[RNG1:![0-9]+]]
+; CHECK-NEXT:    [[ZZ:%.*]] = trunc i32 [[P]] to i16
+; CHECK-NEXT:    ret i16 [[ZZ]]
+;
+  %z = zext i10 %x to i32
+  %p = call i32 @llvm.ctlz.i32(i32 %z, i1 false)
+  %zz = trunc i32 %p to i16
+  ret i16 %zz
+}
+
+; Negative case where size of x is less than 6
+
+define i5 @trunc_ctlz_zext_i5_i32(i5 %x) {
+; CHECK-LABEL: @trunc_ctlz_zext_i5_i32(
+; CHECK-NEXT:    [[Z:%.*]] = zext i5 [[X:%.*]] to i32
+; CHECK-NEXT:    [[P:%.*]] = call i32 @llvm.ctlz.i32(i32 [[Z]], i1 false), !range [[RNG2:![0-9]+]]
+; CHECK-NEXT:    [[ZZ:%.*]] = trunc i32 [[P]] to i5
+; CHECK-NEXT:    ret i5 [[ZZ]]
+;
+  %z = zext i5 %x to i32
+  %p = call i32 @llvm.ctlz.i32(i32 %z, i1 false)
+  %zz = trunc i32 %p to i5
+  ret i5 %zz
+}
+
Index: llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -951,15 +951,16 @@
   }
 
   // trunc (ctlz_i32(zext(A), B) --> add(ctlz_i16(A, B), C)
-  if (match(Src, m_OneUse(m_Intrinsic<Intrinsic::ctlz>(
-                     m_OneUse(m_ZExt(m_Value(A))), m_Value(B))))) {
-    Value *WidthDiff =
-        ConstantInt::get(A->getType(), Src->getType()->getScalarSizeInBits() -
-                                           A->getType()->getScalarSizeInBits());
-
-    Value *NarrowCtlz =
-        Builder.CreateIntrinsic(Intrinsic::ctlz, {Trunc.getType()}, {A, B});
-    return BinaryOperator::CreateAdd(NarrowCtlz, WidthDiff);
+  if (match(Src, m_OneUse(m_Intrinsic<Intrinsic::ctlz>(m_ZExt(m_Value(A)),
+                                                       m_Value(B))))) {
+    unsigned AWidth = A->getType()->getScalarSizeInBits();
+
+    if (AWidth == DestWidth && AWidth > 5) {
+      Value *WidthDiff = ConstantInt::get(A->getType(), SrcWidth - AWidth);
+      Value *NarrowCtlz =
+          Builder.CreateIntrinsic(Intrinsic::ctlz, {Trunc.getType()}, {A, B});
+      return BinaryOperator::CreateAdd(NarrowCtlz, WidthDiff);
+    }
   }
   return nullptr;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104038.351180.patch
Type: text/x-patch
Size: 3602 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210610/58bef88f/attachment-0001.bin>


More information about the llvm-commits mailing list