[llvm] [CodeGenPrepare] Convert `ctpop(X) ==/!= 1` into `ctpop(X) u</u> 2/1` (PR #111284)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 7 03:25:48 PDT 2024


================
@@ -2111,6 +2111,27 @@ bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
   return false;
 }
 
+/// Some targets have better codegen for `ctpop(X) u< 2` than `ctpop(X) == 1`.
+/// This function converts `ctpop(X) ==/!= 1` into `ctpop(X) u</u> 2/1` if the
+/// result cannot be zero.
+static bool adjustIsPower2Test(CmpInst *Cmp, const DataLayout &DL) {
+  ICmpInst::Predicate Pred;
+  if (!match(Cmp, m_ICmp(Pred, m_Intrinsic<Intrinsic::ctpop>(), m_One())))
+    return false;
+  if (!ICmpInst::isEquality(Pred))
+    return false;
+  auto *II = cast<IntrinsicInst>(Cmp->getOperand(0));
----------------
nikic wrote:

When you say "here" you mean as opposed to InstCombine or DAGCombine? I think the reason to do this in IR is that the range attribute gets lost otherwise. Also, there's another PR open that moves the is pow2 idiom recognition to CGP because it can end up split across blocks otherwise, so we'd end up with this in CGP anyway (https://github.com/llvm/llvm-project/pull/102731).

As for doing it in InstCombine instead, I think it's problematic there because it goes against the usual canonicalization direction and may lead to infinite loops.

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


More information about the llvm-commits mailing list