Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mlir/test/mlir-tblgen/op-decl-and-defs.td
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,14 @@ def NS_FOp : NS_Op<"op_with_all_types_constraint",

// DEFS: FOp FOp::create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Value a) {
// DEFS: ::mlir::OperationState __state__(location, getOperationName());
// DEFS: build(builder, __state__, a);
// DEFS: build(builder, __state__, static_cast<decltype(a)>(a));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't std::forward also work here? I think that's more idiomatic

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would think that the idiomatic way would be to std::move here?

Taking the snippet from the PR description:

  let builders = [ 
    OpBuilder<(ins "::mlir::Value":$cdr,
                   "::mlir::ValueRange":$packs,
                   "std::unique_ptr<::mlir::Region>&&":$body)>
  ];

I would instead write this builder as:

  let builders = [ 
    OpBuilder<(ins "::mlir::Value":$cdr,
                   "::mlir::ValueRange":$packs,
                   "std::unique_ptr<::mlir::Region>":$body)>
  ];

That is, taking the unique_ptr by value and relying on the move.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think move could have unexpected consequences on values passed by (non-const) reference -- IMO making arguments explicitly rvalue references and forwarding is less surprising

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I will see if I can change it to std::forward. I am used to having potential auto&& placeholder types which is not possible here.

Copy link
Contributor Author

@ricejasonf ricejasonf Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the DAG syntax, is a type strictly required? Can they put an addtional attribute or any non-type info there? I am having trouble finding where this is specified in the documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found a comment:

// The type string is used verbatim to produce code and, therefore, must be a
// valid C++ type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user passes by value say T, then the std::forward<T> will cast to T&&. I think it would still be fine, but then we are casting trivial types like int to reference types (ie int&&).

I can still change it if you would like.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be std::forward<dectlype(foo)> (which will become a static cast under the hood, but IMO the intent will be more obvious)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IE, I think the semantics we want is to move when either T or T&& and not move with T&.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, that means I can use just std::unique_ptr<mlir::Region> without the && in the parameter list.

// DEFS: auto __res__ = ::llvm::dyn_cast<FOp>(builder.create(__state__));
// DEFS: assert(__res__ && "builder didn't return the right type");
// DEFS: return __res__;
// DEFS: }

// DEFS: FOp FOp::create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Value a) {
// DEFS: return create(builder, builder.getLoc(), a);
// DEFS: return create(builder, builder.getLoc(), static_cast<decltype(a)>(a));
// DEFS: }

def NS_GOp : NS_Op<"op_with_fixed_return_type", []> {
Expand Down
9 changes: 8 additions & 1 deletion mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2641,7 +2641,14 @@ void OpEmitter::genInlineCreateBody(
std::string nonBuilderStateArgs = "";
if (!nonBuilderStateArgsList.empty()) {
llvm::raw_string_ostream nonBuilderStateArgsOS(nonBuilderStateArgs);
interleaveComma(nonBuilderStateArgsList, nonBuilderStateArgsOS);
interleave(
nonBuilderStateArgsList,
[&](StringRef name) {
nonBuilderStateArgsOS << "static_cast<decltype(" << name << ")>("
<< name << ')';
},
[&] { nonBuilderStateArgsOS << ", "; });

nonBuilderStateArgs = ", " + nonBuilderStateArgs;
}
if (cWithLoc)
Expand Down