[llvm] [X86] Shrink i32 unsigned compares to i8/i16 when high bits are zero (PR #197801)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 04:26:52 PDT 2026


================
@@ -24316,6 +24285,34 @@ static SDValue EmitCmp(SDValue Op0, SDValue Op1, X86::CondCode X86CC,
     Op1 = DAG.getNode(ISD::TRUNCATE, dl, CmpVT, Op1);
   }
 
+  // Try to shrink i32 unsigned compares to i8 or i16 when both operands'
+  // high bits are known zero and neither operand is a constant. Eligible
+  // i64 compares are shrunk to i32 above.
+  if (CmpVT == MVT::i32 && !isX86CCSigned(X86CC) &&
+      Op0.hasOneUse() && // Hacky way to not break CSE opportunities with sub.
+      !isa<ConstantSDNode>(Op0) && !isa<ConstantSDNode>(Op1)) {
+    auto BothOpsFit = [&](unsigned Bits) {
+      APInt Hi = APInt::getHighBitsSet(32, 32 - Bits);
+      return DAG.MaskedValueIsZero(Op0, Hi) && DAG.MaskedValueIsZero(Op1, Hi);
+    };
+    // Narrowing to i16 is only when this enables an (and x, 0xFFFF) in an
+    // operand to be removed downstream
+    auto IsI16Eliminable = [](SDValue Op) {
+      if (Op.getOpcode() == ISD::AND)
+        if (auto *C = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
+          return C->getAPIntValue().countr_one() >= 16;
----------------
RKSimon wrote:

I don't understand what this is doing? The trailing ones in the mask have to be 16 bits or MORE?

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


More information about the llvm-commits mailing list