This is an archive of the discontinued LLVM Phabricator instance.

[MLIR] Fix OpDefinition::classof check for shared libraries.
AbandonedPublic

Authored by stephenneuendorffer on Jan 13 2020, 12:01 AM.

Details

Summary

When using MLIR in a shared library, it is possible for the shared library
to load a different, but equivalent version of a class method. As a result,
function pointer comparison is not a reliable check of class equivalence.
This causes problems related to this code in OpDefinition.h:

/// Return true if this "op class" can match against the specified operation.
static bool classof(Operation *op) {
  if (auto *abstractOp = op->getAbstractOperation()) {
    return &classof == abstractOp->classof;
  }
  return op->getName().getStringRef() == ConcreteType::getOperationName();
}

It appears that the intention is to implement the normal LLVM cast<>/isa<>
mechanism, but without a fixed enum of Kinds. Primarily, the operation
name check allows casting based on the operation name, which are assumed
to be unique for an operation class. (Aside: is this enforced anywhere?)
Before this, another, more efficient, check based on pointer equality of
the classof method. Unfortunately, this pointer equality check fails
if/when the classof method is inlined into a shared object (e.g. libLLVM.so)
and also exists in the main executable, resulting in triggering the assert()
inside cast<>.

This patch fixes this method to fall back to the slow, but accurate string
comparison if the function pointer comparison fails.