[llvm] [InstCombine] Fold ctlz(zext(bitreverse(x))) to cttz(x) (PR #218279)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 23 12:34:28 PDT 2026


================
@@ -612,6 +612,25 @@ static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombinerImpl &IC) {
       auto *Bw = ConstantInt::get(Ty, APInt(BitWidth, BitWidth));
       return IC.replaceInstUsesWith(II, IC.Builder.CreateSub(Bw, Cttz));
     }
+
+    // ctlz(zext(bitreverse(x))) -> zext(cttz(x) | (WideBits - NarrowBits))
+    // [poison-on-zero]
+    // ctlz(zext(bitreverse(x))) -> zext(cttz(x) + (WideBits - NarrowBits))
+    // [defined-on-zero]
+    if (match(Op0, m_OneUse(m_ZExt(m_BitReverse(m_Value(X)))))) {
+      Type *NarrowTy = X->getType();
+      unsigned WideBits = II.getType()->getScalarSizeInBits();
+      unsigned NarrowBits = NarrowTy->getScalarSizeInBits();
+      bool IsPoison = match(Op1, m_One());
+
+      auto *Cttz = IC.Builder.CreateBinaryIntrinsic(
+          Intrinsic::cttz, X, ConstantInt::getBool(II.getContext(), IsPoison));
+      auto *Diff = ConstantInt::get(NarrowTy, WideBits - NarrowBits);
+      Value *Combined = IsPoison ? IC.Builder.CreateOr(Cttz, Diff)
----------------
nikic wrote:

This is unnecessary, InstCombine will fold the add to or disjoint if possible by itself.

https://github.com/llvm/llvm-project/pull/218279


More information about the llvm-commits mailing list