[PATCH] D60096: [InstCombine] Simplify ctlz/cttz with bitreverse

Dávid Bolvanský via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 1 13:41:45 PDT 2019


xbolva00 created this revision.
xbolva00 added a reviewer: spatel.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D60096

Files:
  lib/Transforms/InstCombine/InstCombineCalls.cpp
  test/Transforms/InstCombine/ctlz-cttz-bitreverse.ll


Index: test/Transforms/InstCombine/ctlz-cttz-bitreverse.ll
===================================================================
--- test/Transforms/InstCombine/ctlz-cttz-bitreverse.ll
+++ test/Transforms/InstCombine/ctlz-cttz-bitreverse.ll
@@ -0,0 +1,26 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+define i32 @ctlz_bitreverse(i32) {
+; CHECK-LABEL: @ctlz_bitreverse(
+; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.cttz.i32(i32 [[TMP0:%.*]], i1 true), !range !0
+; CHECK-NEXT:    ret i32 [[TMP2]]
+;
+  %2 = tail call i32 @llvm.bitreverse.i32(i32 %0)
+  %3 = tail call i32 @llvm.ctlz.i32(i32 %2, i1 true)
+  ret i32 %3
+}
+
+define i32 @cttz_bitreverse(i32) {
+; CHECK-LABEL: @cttz_bitreverse(
+; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.ctlz.i32(i32 [[TMP0:%.*]], i1 true), !range !0
+; CHECK-NEXT:    ret i32 [[TMP2]]
+;
+  %2 = tail call i32 @llvm.bitreverse.i32(i32 %0)
+  %3 = tail call i32 @llvm.cttz.i32(i32 %2, i1 true)
+  ret i32 %3
+}
+
+declare i32 @llvm.bitreverse.i32(i32)
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
Index: lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1264,12 +1264,20 @@
   assert((II.getIntrinsicID() == Intrinsic::cttz ||
           II.getIntrinsicID() == Intrinsic::ctlz) &&
          "Expected cttz or ctlz intrinsic");
+  bool IsTZ = II.getIntrinsicID() == Intrinsic::cttz;
   Value *Op0 = II.getArgOperand(0);
+  Value *X;
+  // ctlz(bitreverse(x)) -> cttz(x)
+  // cttz(bitreverse(x)) -> ctlz(x)
+  if (match(Op0, m_BitReverse(m_Value(X)))) {
+    return IC.replaceInstUsesWith(II, IC.Builder.CreateBinaryIntrinsic(
+                                       IsTZ ? Intrinsic::ctlz : Intrinsic::cttz,
+                                       X, II.getArgOperand(1)));
+  }
 
   KnownBits Known = IC.computeKnownBits(Op0, 0, &II);
 
   // Create a mask for bits above (ctlz) or below (cttz) the first known one.
-  bool IsTZ = II.getIntrinsicID() == Intrinsic::cttz;
   unsigned PossibleZeros = IsTZ ? Known.countMaxTrailingZeros()
                                 : Known.countMaxLeadingZeros();
   unsigned DefiniteZeros = IsTZ ? Known.countMinTrailingZeros()


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60096.193172.patch
Type: text/x-patch
Size: 2392 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190401/e7482791/attachment.bin>


More information about the llvm-commits mailing list