How do I debug the mlir-translate bug?

When I translate my op to llvm ir, I encountered a bug.I ran the following command.But I think the information below still does not allow me to locate the problem. Is there any other way to locate the bug?If anyone can help me, I would appreciate it.Thanks!

$ mlir-translate log.mlir --buddy-to-llvmir -debug
Args: ../../build1/bin/buddy-translate log.mlir --buddy-to-llvmir -debug 
Load new dialect in Context builtin
ImplicitTypeIDRegistry::lookupOrInsert(mlir::SubElementTypeInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::ShapedType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::MemRefLayoutAttrInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::SubElementAttrInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::ElementsAttr)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::TypedAttr)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::SymbolOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpAsmOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::RegionKindInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::CastOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::ConditionallySpeculatable)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::MemoryEffectOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::ResourceBlobManagerDialectInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpAsmDialectInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::BytecodeDialectInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::AffineBinaryOpExprStorage)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::AffineConstantExprStorage)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::AffineDimExprStorage)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::AffineMapStorage)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::detail::IntegerSetStorage)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ZeroOperands<mlir::TypeID::get() [with Trait = mlir::OpTrait::ZeroOperands]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::OneRegion<mlir::TypeID::get() [with Trait = mlir::OpTrait::OneRegion]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ZeroResults<mlir::TypeID::get() [with Trait = mlir::OpTrait::ZeroResults]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ZeroSuccessors<mlir::TypeID::get() [with Trait = mlir::OpTrait::ZeroSuccessors]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::NoRegionArguments<mlir::TypeID::get() [with Trait = mlir::OpTrait::NoRegionArguments]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::NoTerminator<mlir::TypeID::get() [with Trait = mlir::OpTrait::NoTerminator]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::SingleBlock<mlir::TypeID::get() [with Trait = mlir::OpTrait::SingleBlock]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::OpInvariants<mlir::TypeID::get() [with Trait = mlir::OpTrait::OpInvariants]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::AffineScope<mlir::TypeID::get() [with Trait = mlir::OpTrait::AffineScope]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::IsIsolatedFromAbove<mlir::TypeID::get() [with Trait = mlir::OpTrait::IsIsolatedFromAbove]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::SymbolTable<mlir::TypeID::get() [with Trait = mlir::OpTrait::SymbolTable]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::SymbolOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::SymbolOpInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpAsmOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::OpAsmOpInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::RegionKindInterface::Trait<mlir::TypeID::get() [with Trait = mlir::RegionKindInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::HasOnlyGraphRegion<mlir::TypeID::get() [with Trait = mlir::OpTrait::HasOnlyGraphRegion]::Empty>)
Load new dialect in Context llvm
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMVoidType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMPPCFP128Type)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMX86MMXType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMTokenType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMLabelType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMMetadataType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::LLVMStructType)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::DataLayoutTypeInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::InferTypeOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::SymbolUserOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::BranchOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVM::FastmathFlagsInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::CallOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::FunctionOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::CallableOpInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::DialectInlinerInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::LLVMTranslationDialectInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::AutomaticAllocationScope<mlir::TypeID::get() [with Trait = mlir::OpTrait::AutomaticAllocationScope]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::FunctionOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::FunctionOpInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::CallableOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::CallableOpInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ZeroRegions<mlir::TypeID::get() [with Trait = mlir::OpTrait::ZeroRegions]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::OneResult<mlir::TypeID::get() [with Trait = mlir::OpTrait::OneResult]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::OneTypedResult<mlir::Type>::Impl<mlir::TypeID::get() [with Trait = mlir::OpTrait::OneTypedResult<mlir::Type>::Impl]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::ConditionallySpeculatable::Trait<mlir::TypeID::get() [with Trait = mlir::ConditionallySpeculatable::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::AlwaysSpeculatableImplTrait<mlir::TypeID::get() [with Trait = mlir::OpTrait::AlwaysSpeculatableImplTrait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::MemoryEffectOpInterface::Trait<mlir::TypeID::get() [with Trait = mlir::MemoryEffectOpInterface::Trait]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ConstantLike<mlir::TypeID::get() [with Trait = mlir::OpTrait::ConstantLike]::Empty>)
Load new dialect in Context gemmini
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::VariadicOperands<mlir::TypeID::get() [with Trait = mlir::OpTrait::VariadicOperands]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::ReturnLike<mlir::TypeID::get() [with Trait = mlir::OpTrait::ReturnLike]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::IsTerminator<mlir::TypeID::get() [with Trait = mlir::OpTrait::IsTerminator]::Empty>)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::DataLayoutSpecInterface)
ImplicitTypeIDRegistry::lookupOrInsert(mlir::OpTrait::NOperands<2>::Impl<mlir::TypeID::get() [with Trait = mlir::OpTrait::NOperands<2>::Impl]::Empty>)
buddy-translate: /home/sen/mybuddy/llvm/llvm/include/llvm/ADT/ArrayRef.h:255: const T& llvm::ArrayRef<T>::operator[](size_t) const [with T = llvm::Type*; size_t = long unsigned int]: Assertion `Index < Length && "Invalid index!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: ../../build1/bin/buddy-translate log.mlir --buddy-to-llvmir -debug
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  buddy-translate 0x000056213f8396af
1  buddy-translate 0x000056213f837074

Although an error is reported here,actually I didn’t use ArrayRef.I’m really at a loss.

/llvm/include/llvm/ADT/ArrayRef.h:255: const T& llvm::ArrayRef<T>::operator[](size_t) const [with T = llvm::Type*; size_t = long unsigned int]: Assertion `Index < Length && "Invalid index!"' failed.

Did you try what the message suggests, that is: “(ensure you have llvm-symbolizer in your PATH or set the environment var LLVM_SYMBOLIZER_PATH to point to it):”? This will produce a better stack trace.

Otherwise, build a configuration with debug info available (-DCMAKE_BUILD_TYPE=Debug or -DCMAKE_BUILD_TYPE=RelWithDebInfo) and run under a debugger.

I have used gdb to locate where the problem is.Here is the op I defined. The reason for this bug is that overloadedResults and overloadedOperands are empty.

class Gemmini_IntrOpBase<string mnemonic, list<Trait> traits = []> : 
  LLVM_IntrOpBase</*Dialect dialect=*/Gemmini_Dialect, 
                  /*string opName=*/"intr." # mnemonic,
                  /*string enumName=*/"riscv_" # !subst(".", "_", mnemonic),
                  /*list<int> overloadedOperands=*/[], 
                  /*list<int> overloadedOperands=*/[], 
                  /*list<Trait> traits=*/traits, 
                  /*int numResults=*/0>;

def Gemmini_ConfigSt_IntrOp : Gemmini_IntrOpBase<"configSt">, 
  Arguments<(ins I64, I64)>;

You can see the file generated with mlir-tbgen.

 llvm::Function *fn = llvm::Intrinsic::getDeclaration(
        module,
        llvm::Intrinsic::riscv_configSt,
        { 
                 // there is empty.
        });

But if I set overloadedResults and overloadedOperands.There will be new bugs here. "Calling a function with bad signature!.
In general, I don’t think overloadedResults and overloadedOperands are being used correctly.Actually I don’t want Operands and Operands to be overloaded.

Can you help me to see how LLVM_IntrOpBase should be set?
Because I don’t want to overload overloadedOperands and overloadedOperands, I set here, and Arguments<(ins I64, I64)>;.

/*list<int> overloadedOperands=*/[], 
/*list<int> overloadedOperands=*/[],
Arguments<(ins I64, I64)>;

But this problem can occur.

/llvm/include/llvm/ADT/ArrayRef.h:255: const T& llvm::ArrayRef<T>::operator[](size_t) const [with T = llvm::Type*; size_t = long unsigned int]: Assertion `Index < Length && "Invalid index!"' failed.

How is the LLVM IR intrinsic defined? It looks like it does have overloaded operands or results, so they must be reflected in MLIR.

Also, try the generator that I mentioned elsewhere – llvm-project/llvm-intrinsics.td at main · llvm/llvm-project · GitHub. It gives a sensible default implementation for intrnisics.

Sorry,I just writed the code

lass Gemmini_IntrOpBase<string mnemonic, list<Trait> traits = []> : 
  LLVM_IntrOpBase</*Dialect dialect=*/Gemmini_Dialect, 
                  /*string opName=*/"intr." # mnemonic,
                  /*string enumName=*/"riscv_" # !subst(".", "_", mnemonic),
                  /*list<int> overloadedResults=*/[], 
                  /*list<int> overloadedOperands=*/[], 
                  /*list<Trait> traits=*/traits, 
                  /*int numResults=*/0>;

def Gemmini_ConfigSt_IntrOp : Gemmini_IntrOpBase<"configSt">, 
  Arguments<(ins I64, I64)>;

When I use the following command.

$ ./mlir-tblgen /Gemmini.td -I ../../mlir/include -gen-llvmir-intrinsics
error: The class 'Intrinsic' is not defined

What you post is the definition of an MLIR op that corresponds to the LLVM IR intrinsic. What I want to see is the definition of the intrinsic itself, like this one llvm-project/IntrinsicsRISCV.td at main · llvm/llvm-project · GitHub. The generator also runs on that definition. Do you even have it?

This is my definition of Intrinsic.

let TargetPrefix = "riscv" in 
def int_riscv_configSt : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], []>;

The generator gives me this:

def LLVM_riscv_configSt : LLVM_IntrOp<"configSt", [], [], [], 0, 0, 0>, 
                          Arguments<(ins LLVM_Type, LLVM_Type)>;

However, I extended the Intrinsic outside of the source tree, not in the llvm source code, by which I mean we took the llvm llc out of it. I manually compiled the extended library. Mlr-translate does not link to this library. I am not sure if this will have any impact.

I didn’t understand you earlier. Thank you very much.

This sounds extremely suspicious. If it doesn’t link to the library, how is it expected to construct the IR object defined in that library? Intrinsic construction takes an llvm::Intrinsic::ID, which is an enum in LLVM. If the vanilla LLVM is called, the enum value is quite likely mapped to a different intrinsic than what you are trying to construct, with different overloads.

I’ll try it later.

The lack of extended mlir-translate did have an impact, but by regenerating the library, I have solved the problem.

mlir-translate log.mlir --buddy-to-llvmir
; ModuleID = 'LLVMDialectModule'
source_filename = "LLVMDialectModule"

declare ptr @malloc(i64)

declare void @free(ptr)

define void @fun() {
  call void @llvm.riscv.configSt(i64 111111, i64 123456)
  ret void
}

; Function Attrs: nounwind
declare void @llvm.riscv.configSt(i64, i64) #0

attributes #0 = { nounwind }

!llvm.module.flags = !{!0}

!0 = !{i32 2, !"Debug Info Version", i32 3}