[llvm] [InstCombine] Match a new form of truncating saturation (PR #189703)
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 2 07:55:16 PDT 2026
================
@@ -1171,6 +1171,33 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
}
}
+ // trunc (select(icmp_ult(A, DestTy_umax+1), A, sext(icmp_sgt(A, 0)))) -->
+ // trunc (smin(smax(0, A), DestTy_umax))
+ if (SrcTy->isIntegerTy() && isPowerOf2_64(SrcTy->getPrimitiveSizeInBits()) &&
+ DestTy->isIntegerTy() &&
+ isPowerOf2_64(DestTy->getPrimitiveSizeInBits()) &&
+ match(Src,
+ m_OneUse(m_Select(
+ m_SpecificICmp(ICmpInst::ICMP_ULT, m_Value(A), m_Constant(C)),
+ m_Deferred(A),
+ m_SExt(m_SpecificICmp(ICmpInst::ICMP_SGT, m_Deferred(A),
+ m_Zero())))))) {
+ APInt UpperBound = C->getUniqueInteger();
+ APInt TruncatedMax = APInt::getAllOnes(DestTy->getIntegerBitWidth());
----------------
david-arm wrote:
According to the LangRef the bit size of the type you're truncating must be greater than the bit size of the destination type. Also, since A is one the selected inputs then the result of the select must have the same type as A. That means A must have a bigger size than the dest type and given we're comparing A against C then by definition C must also have a bigger type than the dest type. I think that means you can just do
```
APInt UpperBound = C->getUniqueInteger();
APInt TruncatedMax = APInt::getAllOnes(DestTy->getIntegerBitWidth());
TruncatedMax = TruncatedMax.zext(UpperBound.getBitWidth());
```
https://github.com/llvm/llvm-project/pull/189703
More information about the llvm-commits
mailing list