[llvm-branch-commits] [mlir] [mlir] Add `OpFoldResults` definition (PR #229215)

Mehdi Amini via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Oct 6 00:50:51 PDT 2026


================
@@ -54,6 +61,101 @@ struct CastInfo<To, const mlir::OpFoldResult>
 namespace mlir {
 /// Allow printing to a stream.
 raw_ostream &operator<<(raw_ostream &os, OpFoldResult ofr);
+
+/// The result of a fold of any op. Replacement i is an Attribute (replace
+/// result i with a constant), a Value (replace result i with that value), or
+/// null / op->getResult(i) (keep result i). A separate bit records an in-place
+/// change of the op.
+class [[nodiscard]] OpFoldResults {
+public:
+  /// Failure: the fold did not apply and the IR is unchanged.
+  OpFoldResults() = default;
+  /// Failure, the same as the default constructor.
+  OpFoldResults(std::nullptr_t);
+  /// success(): the op changed in place. failure(): failure.
+  OpFoldResults(LogicalResult status);
+  /// One replacement. Valid only when the op has exactly one result at run
+  /// time. A null replacement, or the op's own result, keeps the result, so the
+  /// fold fails. Unlike `OpFoldResult fold`, the op's own result does not mean
+  /// in place; use success() or setModifiedInPlace() for an in-place change.
+  OpFoldResults(OpFoldResult replacement);
+  OpFoldResults(Value replacement);
+  OpFoldResults(Attribute replacement);
+  /// One replacement per result.
+  OpFoldResults(std::initializer_list<OpFoldResult> replacements);
+  /// One replacement per range element. An empty range is a failure.
+  template <typename RangeT,
+            typename = std::enable_if_t<
+                !std::is_convertible_v<RangeT, Attribute> &&
+                !std::is_convertible_v<RangeT, Value> &&
+                std::is_convertible_v<llvm::detail::ValueOfRange<RangeT>,
+                                      OpFoldResult>>>
+  OpFoldResults(RangeT &&range) {
+    llvm::append_range(replacements, range);
+  }
+  /// Incremental form: every result is kept and the op is not changed in
+  /// place.
+  explicit OpFoldResults(Operation *op);
----------------
joker-eph wrote:

What's the difference between this and returning a failure? 
I'm not clear on why we need this constructor. 

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


More information about the llvm-branch-commits mailing list