[llvm] Add known and demanded bits support for zext nneg (PR #70858)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 5 07:24:56 PST 2023


================
@@ -1103,6 +1103,9 @@ static void computeKnownBitsFromOperator(const Operator *I,
     assert(SrcBitWidth && "SrcBitWidth can't be zero");
     Known = Known.anyextOrTrunc(SrcBitWidth);
     computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+    if (auto *Inst = dyn_cast<Instruction>(I);
+        Inst && Inst->getOpcode() == Instruction::ZExt && Inst->hasNonNeg())
+      Known.makeNonNegative();
----------------
nikic wrote:

> It seems like doing it this way is missing an optimization. Be proving a conflict, haven't we proven the resulting value to be poison? If so, why are we not taking advantage of that to fold the value to poison?

Yes, a conflict implies the result is poison. I think the reason for the current approach is just "historical reasons" -- at some point somebody made the choice that we don't want to deal with conflicting KnownBits and we've stuck to that since. I'd be open to reevaluate that choice, but it's not something we can allow in just one place, it needs to be supported across all the KnownBits-based infrastructure-
 
> Glancing through the code for KnownBits and SimplifyDemanded, I don't see any clear evidence of a consistent scheme being followed. Do you know the big picture here?

Usually one of 1. locally resolve the conflict (e.g. here unset the negative bit or don't set non-negative), 2. return unknown bits or 3. return zero.

See e.g. https://github.com/llvm/llvm-project/blob/6e175935c10d5e50f8a63495338d52839b004e99/llvm/lib/Analysis/ValueTracking.cpp#L426 for a very similar case to this one, which solves this by doing a `!Known.isNegative()` check first.

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


More information about the llvm-commits mailing list