[llvm] [InstCombine] Evaluate zext nneg as sext where possible (PR #212230)

John Brawn via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 13 06:54:20 PDT 2026


================
@@ -1627,10 +1642,14 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &Zext) {
     uint32_t DestBitSize = DestTy->getScalarSizeInBits();
 
     // If the high bits are already filled with zeros, just replace this
-    // cast with the result.
-    if (MaskedValueIsZero(
-            Res, APInt::getHighBitsSet(DestBitSize, DestBitSize - SrcBitsKept),
-            &Zext))
+    // cast with the result. If we've evaluated as a signed expressions then
+    // instead check that the high bits are the sign bit, which we know is zero.
+    if (EvaluateAsSigned
+            ? (ComputeNumSignBits(Res, &Zext) > DestBitSize - SrcBitsKept)
+            : MaskedValueIsZero(
+                  Res,
+                  APInt::getHighBitsSet(DestBitSize, DestBitSize - SrcBitsKept),
+                  &Zext))
----------------
john-brawn-arm wrote:

Looking into this, canEvaluateSExtd uses canEvaluate which returns true for canAlwaysEvaluateInType which is true for trunc, so the checking of NoSignedWrap on trunc was never happening. However doing some experimenting, with the checking of ComputeNumSignBits we don't need to check for NoSignedWrap in canEvaluateSExtd at all, as ComputeNumSignBits ultimately uses KnownBits which correctly handles NoSignedWrap when deciding the number of sign bits.

Removing the checking of NoSignedWrap and instead relying on ComputeNumSignBits should simplify this a lot. I'll update this PR to do that.

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


More information about the llvm-commits mailing list