Skip to content

[domaintool][OM] Assertion failure when bouncing through extra object #10264

@seldridge

Description

@seldridge

I've got a failure when using domaintool with the following example. This is likely a general bug (that I introduced) in the OM evaluator:

om.class @Domain(%in: !om.string)  -> (out: !om.string) {
  om.class.fields %in : !om.string
}
om.class @Foo_Class(%basepath: !om.frozenbasepath)  -> (test: i1) {
  %0 = om.constant "A" : !om.string
  %1 = om.object @Domain(%0) : (!om.string) -> !om.class.type<@Domain>
  %2 = om.object.field %1, [@out] : (!om.class.type<@Domain>) -> !om.string
  %3 = om.object @Domain(%2) : (!om.string) -> !om.class.type<@Domain>
  %4 = om.object.field %3, [@out] : (!om.class.type<@Domain>) -> !om.string
  %5 = om.constant "B" : !om.string
  %6 = om.prop.eq %4, %5 : !om.string
  om.class.fields %6 : i1
}

Running this, I hit an assertion:

# ./build/bin/domaintool ./build/Foo.reduced.mlir -module Foo
Assertion failed: (detail::isPresent(Val) && "dyn_cast on a non-existent value"), function dyn_cast, file Casting.h,
line 656.
zsh: abort      domaintool Foo.reduced.mlir -module Foo

The problem is that in ReferenceValue::getStrippedValue, while this is walking backwards, eventually this hits a
currentValue.get() which is nullptr:

(lldb) frame select 5
frame #5: 0x000000010339faa0
domaintool`circt::om::evaluator::ReferenceValue::getStrippedValue(this=0x000000010f30de58) const at Evaluator.h:136:22
   133    FailureOr<EvaluatorValuePtr> getStrippedValue() const {
   134      llvm::SmallPtrSet<ReferenceValue *, 4> visited;
   135      auto currentValue = value;
-> 136      while (auto *v = dyn_cast<ReferenceValue>(currentValue.get())) {
   137        // Detect a cycle.                                                                                          138        if (!visited.insert(v).second)                                                                              139          return failure();
(lldb) print currentValue.get()                                                                                        (std::shared_ptr<circt::om::evaluator::EvaluatorValue>::element_type *) nullptr                                        (lldb) print currentValue
(circt::om::evaluator::EvaluatorValuePtr) nullptr {                                                                      pointer = nullptr                                                                                                    }

If I remove the second om.object, then everything works.

Metadata

Metadata

Assignees

Labels

OMObject ModelbugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions