[llvm] [InstCombine] Optimize unneeded float to int cast when icmp (PR #155501)

Artem Trokhymchuk via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 2 09:50:47 PDT 2025


================
@@ -7611,6 +7614,168 @@ 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 CheckSign = [Sign](const APInt &Value) {
+    switch (Sign) {
+    case SignType::Positive:
+      return Value.isStrictlyPositive();
+    case SignType::NonPositive:
+      return Value.isNonPositive();
+    case SignType::Negative:
+      return Value.isNegative();
+    case SignType::NonNegative:
+      return Value.isNonNegative();
+    default:
+      llvm_unreachable("Unknown sign type");
+    }
+  };
+
+  return match(C, m_CheckedInt(CheckSign));
+}
+
+/// Get inner type: if the type matches CheckFn, the type itself
+/// is returned. Otherwise, type is converted to vector and inner
+/// type is retuend.
+///
+/// \param T type to get inner type from
+/// \param CheckFn function to check whether T is acceptable
+///
+/// \param if T matches CheckFn, the T is retuend. otherwise T
+/// is converted to VectorType and inner type is retuend
+static Type *getInnerType(Type *T, bool (Type::*CheckFn)() const) {
+  if ((T->*CheckFn)())
+    return T;
+
+  VectorType *VT{llvm::cast<llvm::VectorType>(T)};
+  if (!VT)
+    return nullptr;
+
+  return VT->getElementType();
+}
+
+/// Converts Addend to an appropriate constant and returns it
+///
+/// \param C constant to extract type and size (if vector) to
+/// create an appropriate addned type
+/// \param Addend addend to create constant from
+///
+/// \return Constant of the C type and with Addend in storage
+static Constant *getConstantAddend(const Constant *C, int Addend) {
+  Type *InnerType{getInnerType(
+      C->getType(), static_cast<bool (Type::*)() const>(&Type::isIntegerTy))};
+  if (!InnerType)
+    return nullptr;
+
+  IntegerType *IntegralInnerType = llvm::dyn_cast<llvm::IntegerType>(InnerType);
+  if (!IntegralInnerType)
+    return nullptr;
+
+  Constant *CIAddend{
+      ConstantInt::get(InnerType, APInt{IntegralInnerType->getBitWidth(),
+                                        static_cast<uint64_t>(Addend), true})};
+  if (C->getType()->isIntegerTy())
+    return CIAddend;
+
+  const ConstantDataVector *CDV = dyn_cast<ConstantDataVector>(C);
+  if (!CDV)
+    return nullptr;
+
+  return ConstantDataVector::getSplat(CDV->getNumElements(), CIAddend);
+}
+
+/// 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
+/// \param DL target data layout
+///
+/// \return result constant
+static Constant *castIntegralConstantToFloat(Constant *C, Type *FPType,
+                                             int Addend, const DataLayout &DL) {
+  Type *InnerType{getInnerType(FPType, &Type::isFloatingPointTy)};
+  if (!InnerType || !InnerType->isFloatingPointTy())
+    return nullptr;
----------------
trokhymchuk wrote:

thanks, updated the code, pls take a look

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


More information about the llvm-commits mailing list