[llvm] Float2Int: Replace -float2int-max-integer-bw cl::opt with pass parameter (PR #223477)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 01:45:21 PDT 2026


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/223477

>From 6820fac44c408338fe6df283a4f1afe6505ae7ce Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sat, 12 Sep 2026 22:52:06 +0200
Subject: [PATCH] Float2Int: Replace -float2int-max-integer-bw cl::opt with
 pass parameter

Migrate the pass-specific command-line option to a new pass manager
pass parameter, exposed as float2int<max-integer-bw=N>.

Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
---
 .../llvm/Transforms/Scalar/Float2Int.h        |  9 +++++++
 llvm/lib/Passes/PassBuilder.cpp               | 24 +++++++++++++++++++
 llvm/lib/Passes/PassRegistry.def              |  5 +++-
 llvm/lib/Transforms/Scalar/Float2Int.cpp      | 16 +++++++------
 llvm/test/Other/new-pm-print-pipeline.ll      |  5 +++-
 .../Float2Int/pass-param-parse-errors.ll      |  7 ++++++
 llvm/test/Transforms/Float2Int/toolarge.ll    |  2 +-
 7 files changed, 58 insertions(+), 10 deletions(-)
 create mode 100644 llvm/test/Transforms/Float2Int/pass-param-parse-errors.ll

diff --git a/llvm/include/llvm/Transforms/Scalar/Float2Int.h b/llvm/include/llvm/Transforms/Scalar/Float2Int.h
index 9225ac4f052cf..a14e5f16cccf1 100644
--- a/llvm/include/llvm/Transforms/Scalar/Float2Int.h
+++ b/llvm/include/llvm/Transforms/Scalar/Float2Int.h
@@ -30,8 +30,14 @@ class Value;
 
 class Float2IntPass : public OptionalPassInfoMixin<Float2IntPass> {
 public:
+  Float2IntPass(unsigned MaxIntegerBW = 64) : MaxIntegerBW(MaxIntegerBW) {}
+
   LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
 
+  LLVM_ABI void
+  printPipeline(raw_ostream &OS,
+                function_ref<StringRef(StringRef)> MapClassName2PassName);
+
   // Glue for old PM.
   LLVM_ABI bool runImpl(Function &F, const DominatorTree &DT);
 
@@ -53,6 +59,9 @@ class Float2IntPass : public OptionalPassInfoMixin<Float2IntPass> {
   EquivalenceClasses<Instruction *> ECs;
   MapVector<Instruction *, Value *> ConvertedInsts;
   LLVMContext *Ctx;
+
+  /// Max integer bitwidth to consider in float2int.
+  const unsigned MaxIntegerBW;
 };
 }
 #endif // LLVM_TRANSFORMS_SCALAR_FLOAT2INT_H
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 858c76706427e..33fab34b2ea2c 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -1279,6 +1279,30 @@ Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
   return Result;
 }
 
+Expected<unsigned> parseFloat2IntOptions(StringRef Params) {
+  unsigned MaxIntegerBW = 64;
+  while (!Params.empty()) {
+    StringRef ParamName;
+    std::tie(ParamName, Params) = Params.split(';');
+
+    if (ParamName.consume_front("max-integer-bw=")) {
+      if (ParamName.getAsInteger(0, MaxIntegerBW)) {
+        return make_error<StringError>(
+            formatv("invalid argument to Float2Int pass max-integer-bw "
+                    "parameter: '{}'",
+                    ParamName)
+                .str(),
+            inconvertibleErrorCode());
+      }
+    } else {
+      return make_error<StringError>(
+          formatv("invalid Float2Int pass parameter '{}'", ParamName).str(),
+          inconvertibleErrorCode());
+    }
+  }
+  return MaxIntegerBW;
+}
+
 Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
   InstCombineOptions Result;
   // When specifying "instcombine" in -passes enable fix-point verification by
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 33c9e19988d7a..fc6995a794d1e 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -447,7 +447,6 @@ FUNCTION_PASS("extra-vector-passes",
               ExtraFunctionPassManager<ShouldRunExtraVectorPasses>())
 FUNCTION_PASS("fix-irreducible", FixIrreduciblePass())
 FUNCTION_PASS("flatten-cfg", FlattenCFGPass())
-FUNCTION_PASS("float2int", Float2IntPass())
 FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass())
 FUNCTION_PASS("gc-lowering", GCLoweringPass())
 FUNCTION_PASS("guard-widening", GuardWideningPass())
@@ -598,6 +597,10 @@ FUNCTION_PASS_WITH_PARAMS(
     "ee-instrument", "EntryExitInstrumenterPass",
     [](bool PostInlining) { return EntryExitInstrumenterPass(PostInlining); },
     parseEntryExitInstrumenterPassOptions, "post-inline")
+FUNCTION_PASS_WITH_PARAMS(
+    "float2int", "Float2IntPass",
+    [](unsigned MaxIntegerBW) { return Float2IntPass(MaxIntegerBW); },
+    parseFloat2IntOptions, "max-integer-bw=N")
 FUNCTION_PASS_WITH_PARAMS(
     "func-properties-stats", "FunctionPropertiesStatisticsPass",
     [](bool IsPreOptimizations) {
diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp
index 37822cf05f144..d1d9a8740c39f 100644
--- a/llvm/lib/Transforms/Scalar/Float2Int.cpp
+++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp
@@ -20,7 +20,6 @@
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Module.h"
-#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 #include <deque>
@@ -40,12 +39,6 @@ using namespace llvm;
 // as non-transformable. If we see an instruction that converts from the
 // integer domain to FP domain (uitofp,sitofp), we terminate our walk.
 
-/// The largest integer type worth dealing with.
-static cl::opt<unsigned>
-MaxIntegerBW("float2int-max-integer-bw", cl::init(64), cl::Hidden,
-             cl::desc("Max integer bitwidth to consider in float2int"
-                      "(default=64)"));
-
 // Given a FCmp predicate, return a matching ICmp predicate if one
 // exists, otherwise return BAD_ICMP_PREDICATE.
 static CmpInst::Predicate mapFCmpPred(CmpInst::Predicate P) {
@@ -513,3 +506,12 @@ PreservedAnalyses Float2IntPass::run(Function &F, FunctionAnalysisManager &AM) {
   PA.preserveSet<CFGAnalyses>();
   return PA;
 }
+
+void Float2IntPass::printPipeline(
+    raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
+  static_cast<PassInfoMixin<Float2IntPass> *>(this)->printPipeline(
+      OS, MapClassName2PassName);
+  OS << '<';
+  OS << "max-integer-bw=" << MaxIntegerBW;
+  OS << '>';
+}
diff --git a/llvm/test/Other/new-pm-print-pipeline.ll b/llvm/test/Other/new-pm-print-pipeline.ll
index a8fcf113e49b2..f012afa354723 100644
--- a/llvm/test/Other/new-pm-print-pipeline.ll
+++ b/llvm/test/Other/new-pm-print-pipeline.ll
@@ -4,7 +4,7 @@
 ; CHECK-0: function(adce),function(adce)
 
 ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='module(rpo-function-attrs,require<globals-aa>,function(float2int,lower-constant-intrinsics,loop(loop-rotate)),invalidate<globals-aa>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-1
-; CHECK-1: rpo-function-attrs,require<globals-aa>,function(float2int,lower-constant-intrinsics,loop(loop-rotate<header-duplication;no-prepare-for-lto;no-check-exit-count>)),invalidate<globals-aa>
+; CHECK-1: rpo-function-attrs,require<globals-aa>,function(float2int<max-integer-bw=64>,lower-constant-intrinsics,loop(loop-rotate<header-duplication;no-prepare-for-lto;no-check-exit-count>)),invalidate<globals-aa>
 
 ;; Test that we get ClassName printed when there is no ClassName to pass-name mapping (as is the case for the BitcodeWriterPass).
 ; RUN: opt -o /dev/null -disable-verify -print-pipeline-passes -passes='function(mem2reg)' < %s -disable-pipeline-verification | FileCheck %s --match-full-lines --check-prefixes=CHECK-3
@@ -126,3 +126,6 @@
 
 ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(infer-address-spaces,infer-address-spaces<assume-default-is-flat-addrspace>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-39
 ; CHECK-39: function(infer-address-spaces,infer-address-spaces<assume-default-is-flat-addrspace>)
+
+; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(float2int,float2int<max-integer-bw=32>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-40
+; CHECK-40: function(float2int<max-integer-bw=64>,float2int<max-integer-bw=32>)
diff --git a/llvm/test/Transforms/Float2Int/pass-param-parse-errors.ll b/llvm/test/Transforms/Float2Int/pass-param-parse-errors.ll
new file mode 100644
index 0000000000000..907a4c1ca768f
--- /dev/null
+++ b/llvm/test/Transforms/Float2Int/pass-param-parse-errors.ll
@@ -0,0 +1,7 @@
+; RUN: not opt -passes='float2int<unknown>' -disable-output %s 2>&1 | FileCheck -check-prefix=UNKNOWNERR %s
+; RUN: not opt -passes='float2int<max-integer-bw=>' -disable-output %s 2>&1 | FileCheck -check-prefix=BW-EMPTY-ERR %s
+; RUN: not opt -passes='float2int<max-integer-bw=x>' -disable-output %s 2>&1 | FileCheck -check-prefix=BW-NOTINT-ERR %s
+
+; UNKNOWNERR: invalid Float2Int pass parameter '{{.*}}'
+; BW-EMPTY-ERR: invalid argument to Float2Int pass max-integer-bw parameter: ''
+; BW-NOTINT-ERR: invalid argument to Float2Int pass max-integer-bw parameter: 'x'
diff --git a/llvm/test/Transforms/Float2Int/toolarge.ll b/llvm/test/Transforms/Float2Int/toolarge.ll
index 8c04d1085ec31..7b4b1a316bf9b 100644
--- a/llvm/test/Transforms/Float2Int/toolarge.ll
+++ b/llvm/test/Transforms/Float2Int/toolarge.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -passes=float2int -float2int-max-integer-bw=256 -S | FileCheck %s
+; RUN: opt < %s -passes='float2int<max-integer-bw=256>' -S | FileCheck %s
 
 ; CHECK-LABEL: @neg_toolarge
 ; CHECK:  %1 = uitofp i80 %a to fp128



More information about the llvm-commits mailing list