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

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 7 00:19:14 PDT 2025


================
@@ -7611,6 +7613,117 @@ 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));
+}
+
+/// 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) {
+  if (!FPType->isFPOrFPVectorTy())
+    return nullptr;
+
+  Constant *CWithAddend = ConstantFoldBinaryOpOperands(
+      Instruction::Add, C, ConstantInt::getSigned(C->getType(), Addend), DL);
+  return ConstantFoldCastOperand(Instruction::SIToFP, CWithAddend, FPType, DL);
+}
+
+/// Fold icmp (fptosi %arg) C -> fcmp $arg
+/// Folds:
+///  - icmp sgt %arg <negative> -> fcmp ogt %arg <negative>
+///  - icmp sgt %arg <non-negative> -> fcmp oge %arg (<non-negative> + 1)
+///  - icmp slt %arg <positive> -> fcmp olt %arg <positive>
+///  - icmp slt %arg <non-positive> -> fcmp ole %arg (<non-positive> - 1)
+///
+/// \param ICmp icmp instruction
+/// \param IC InstCombiner isntance
+/// \param DL target data layout
+///
+/// \return folded instruction or nullptr, if failed to combine instructions
+static Instruction *foldICmpFToSIToFCmp(ICmpInst &ICmp, InstCombiner &IC,
+                                        const DataLayout &DL) {
+  // Expect that canonical form: first argument is fptosi, second is constant
+  CmpPredicate Pred;
+  Value *FloatOp;
+  Constant *C;
+  if (!match(&ICmp, m_ICmp(Pred, m_FPToSI(m_Value(FloatOp)), m_ImmConstant(C))))
+    return nullptr;
+
+  if (Pred != ICmpInst::ICMP_SGT && Pred != ICmpInst::ICMP_SLT)
+    return nullptr;
----------------
nikic wrote:

You can use `default: return nullptr` instead of the separate check.

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


More information about the llvm-commits mailing list