[llvm] [InstCombine] Fold trunc(umin/umax(zext(x), y & mask)) to narrower umin/umax (PR #173221)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 27 02:40:35 PST 2025


================
@@ -607,6 +623,32 @@ bool TypeEvaluationHelper::canEvaluateTruncatedPred(Value *V, Type *Ty,
     return canEvaluateTruncatedImpl(I->getOperand(0), Ty, IC, CxtI) &&
            canEvaluateTruncatedImpl(I->getOperand(1), Ty, IC, CxtI);
 
+  case Instruction::Call:
+    if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
+      switch (II->getIntrinsicID()) {
+      case Intrinsic::umax:
+      case Intrinsic::umin: {
+        unsigned OrginalBitWidth = OrigTy->getScalarSizeInBits();
+        unsigned TargetBitWidth = Ty->getScalarSizeInBits();
+        assert(TargetBitWidth < OrginalBitWidth && "Unexpected bitwidths!");
+        APInt Mask = APInt::getBitsSetFrom(OrginalBitWidth, TargetBitWidth);
+        // If we know that all operands is always within the truncated
+        // range, we can perform the umin in the smaller type.
+        if (IC.MaskedValueIsZero(II->getArgOperand(0), Mask, CxtI) &&
+            IC.MaskedValueIsZero(II->getArgOperand(1), Mask, CxtI)) {
+          Value *Op0 = II->getArgOperand(0);
+          Value *Op1 = II->getArgOperand(1);
+          return canEvaluateTruncatedImpl(Op0, Ty, IC, CxtI) ||
----------------
nikic wrote:

Should be && rather than || ?

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


More information about the llvm-commits mailing list