This is an archive of the discontinued LLVM Phabricator instance.

Harden MLIR detection of misconfiguration when missing dialect registration
ClosedPublic

Authored by mehdi_amini on May 27 2020, 12:02 PM.

Diff Detail

Event Timeline

mehdi_amini created this revision.May 27 2020, 12:02 PM
Herald added a project: Restricted Project. · View Herald Transcript
rriddle resigned from this revision.May 27 2020, 2:19 PM
rriddle accepted this revision.May 27 2020, 2:23 PM

I wonder if we should also add something to Op::classof. i.e. can you cast to FooOp if it isn't registered?

This revision is now accepted and ready to land.May 27 2020, 2:23 PM

I wonder if we should also add something to Op::classof. i.e. can you cast to FooOp if it isn't registered?

Right now I was trying to add code that runs in release mode, so I tried to hook into code path that are OK to pay the price: type creation is once per type and op creation is expensive enough to take a nullptr check.
Are you proposing to have an extra nullptr check for every cast to an operation? I can also do that.

jpienaar accepted this revision.May 27 2020, 3:41 PM

I wonder if we should also add something to Op::classof. i.e. can you cast to FooOp if it isn't registered?

Right now I was trying to add code that runs in release mode, so I tried to hook into code path that are OK to pay the price: type creation is once per type and op creation is expensive enough to take a nullptr check.
Are you proposing to have an extra nullptr check for every cast to an operation? I can also do that.

I'd prefer if we do keep it light: it would seem that if one is testing this with unit tests/NDEBUG then these would be caught with asserts . So with proper unit tests one should be catching these & should be rare (e.g., how often is a new dialect added to production build?) [which is also why I'm a little bit torn but don't feel strongly against].

I wonder if we should also add something to Op::classof. i.e. can you cast to FooOp if it isn't registered?

Right now I was trying to add code that runs in release mode, so I tried to hook into code path that are OK to pay the price: type creation is once per type and op creation is expensive enough to take a nullptr check.
Are you proposing to have an extra nullptr check for every cast to an operation? I can also do that.

I'd prefer if we do keep it light: it would seem that if one is testing this with unit tests/NDEBUG then these would be caught with asserts . So with proper unit tests one should be catching these & should be rare (e.g., how often is a new dialect added to production build?) [which is also why I'm a little bit torn but don't feel strongly against].

I brought this up because if we have a policy of not allowing the use of *Op classes for unregistered ops we should be consistent with erroring out.

As for enabling in release builds it depends on how often we expect unregistered operations to be used in production. If it is often, then we should only enable during debug builds. If not, it is fairly cheap to enable during release given that classof already has a fast path for operations that are registered. Regardless of which one we choose, it has the benefit of removing the fallback string comparison in favor of always returning false.

Disable cast<OpTy>(op) on unregistered operations

Add unreachable for the cast<OpTy>

(build fix)

I thought it would involve adding an extra check, but if it is free on the fast path then checking the cast<> case seems good!

We had many issues where the unit-test environment does not reproduce the exact registration state of the production path, this will help saving a bunch of debugging hopefully

rriddle added inline comments.May 27 2020, 8:22 PM
mlir/include/mlir/IR/OpDefinition.h
1238–1241

You will still want to check here. This path is only taken if the operation being casted is unregistered, not ConcreteType itself.

Add a method on the MLIRContext to check if an operation name is registered in the context

mehdi_amini marked 2 inline comments as done.May 27 2020, 8:30 PM
mehdi_amini added inline comments.
mlir/include/mlir/IR/OpDefinition.h
1238–1241

Yeah I figured when the test were failing...
So unfortunately this isn't "free" and I had to make it an assertion.

This revision was automatically updated to reflect the committed changes.
mehdi_amini marked an inline comment as done.