[llvm] Inst combine optimize unneded float to int cast when icmp (PR #155501)
Artem Trokhymchuk via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 26 14:32:50 PDT 2025
================
@@ -7611,6 +7613,208 @@ Instruction *InstCombinerImpl::foldICmpCommutative(CmpPredicate Pred,
return nullptr;
}
+enum class SignType {
+ Positive,
+ NonPositive,
+ Negative,
+ NonNegative,
+};
+
+/// Check signess of a constant integer or vector of integers
+///
+/// \param C constant to check for signedness
+/// \param SignType the sign type to check against
+///
+/// \return whether constant is signess corresponds with the requesed requested sign
+static bool checkConstantSignType(const Constant *C, SignType Sign) {
+ auto Check = [Sign](const ConstantInt *CI) {
+ switch (Sign) {
+ case SignType::Positive:
+ return !CI->isNegative() && !CI->isZero();
+ case SignType::NonPositive:
+ return CI->isNegative() || CI->isZero();
+ case SignType::Negative:
+ return CI->isNegative();
+ case SignType::NonNegative:
+ return !CI->isNegative();
+ default:
+ llvm_unreachable("Unknown sign type");
+ }
+ };
+
+ if (auto *CI = dyn_cast<ConstantInt>(C))
+ return Check(CI);
+
+ // Check every element for vector
+ if (auto *CDV = dyn_cast<ConstantDataVector>(C)) {
+ for (std::size_t i{}; i != CDV->getNumElements(); ++i) {
+ auto *CI = dyn_cast<ConstantInt>(CDV->getElementAsConstant(i));
+ if (!CI || !Check(CI))
+ return false;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+/// Cast ConstantInt to an appropriate APFloat instance
+///
+/// \param CI ConstantInt instance to cast
+/// \param FPType floating point type to cast to
+/// \param Addend addend to add to constant before casting
+///
+/// \return pair {cast status, APFloat result}
+static std::pair<APFloatBase::opStatus, APFloat>
+castCIToAPF(const ConstantInt *CI, const Type *FPType, int Addend) {
+ APFloat FVal{FPType->isFloatTy() ? APFloat::IEEEsingle()
+ : APFloat::IEEEdouble()};
+ APInt CIAPIntValue{CI->getValue()};
+
+ if (CIAPIntValue.isMaxSignedValue() && Addend > 0)
+ return std::make_pair(APFloatBase::opStatus::opOverflow, FVal);
+
+ if (CIAPIntValue.isMinSignedValue() && Addend < 0)
+ return std::make_pair(APFloatBase::opStatus::opUnderflow, FVal);
+
+ APFloatBase::opStatus Status{FVal.convertFromAPInt(
+ CI->getValue() + Addend, true, APFloat::rmNearestTiesToEven)};
+ return std::make_pair(Status, FVal);
+}
+
+/// Cast ConstantDataVector<ConstantInt> to ConstantVector<ConstantFP>
+///
+/// \param CDV ConstantInt datavector to cast
+/// \param FPType floating point type to cast to
+/// \param Addend addend to add before casting
+/// \param Context context to use
+///
+/// \return result constant
+static Constant *castCIDVToCFPDV(const ConstantDataVector *CDV, Type *FPType,
+ int Addend, LLVMContext &Context) {
+ SmallVector<Constant *, 16> Elts;
+ for (std::size_t i{}; i != CDV->getNumElements(); ++i) {
+ ConstantInt *CI = dyn_cast<ConstantInt>(CDV->getElementAsConstant(i));
+ if (!CI)
+ return nullptr;
+
+ auto ConverstionResult = castCIToAPF(CI, FPType, Addend);
+ if (ConverstionResult.first != APFloat::opOK)
+ return nullptr;
+
+ Elts.push_back(ConstantFP::get(FPType, ConverstionResult.second));
+ }
+ return ConstantVector::get(Elts);
+}
+
+/// Cast integral constant (either scalar or vector) to an appropriate vector one
+///
+/// \param C integral contsant to cast
+/// \param FPType floating point type to cast to
+/// \param Addend addend to add before casting
+///
+/// \return result constant
+static Constant *castIntegralConstantToFloat(const Constant *C, Type *FPType,
+ int Addend) {
+ auto getInnerType = [FPType]() -> Type * {
+ if (FPType->isFloatingPointTy())
+ return FPType;
+
+ if (!FPType->isVectorTy())
+ return nullptr;
+
+ return llvm::cast<llvm::VectorType>(FPType)->getElementType();
+ };
----------------
trokhymchuk wrote:
lambda is not needed, jsut calculate type once
https://github.com/llvm/llvm-project/pull/155501
More information about the llvm-commits
mailing list