diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2025-05-15 17:38:05 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-15 17:38:05 -0700 |
commit | 8d3a70770fda43c1f1ae797f307adf25b65e7209 (patch) | |
tree | 6490fcf58bb0bcb00899542337d5a7ad3968620e /mlir/lib/Target/LLVMIR/ModuleImport.cpp | |
parent | de0bcd0564e4e67ae2afe1bad41c7bc505362e19 (diff) | |
download | llvm-8d3a70770fda43c1f1ae797f307adf25b65e7209.zip llvm-8d3a70770fda43c1f1ae797f307adf25b65e7209.tar.gz llvm-8d3a70770fda43c1f1ae797f307adf25b65e7209.tar.bz2 |
[MLIR][LLVM] Improve inline asm importer (#139989)
Add support for importing more information into InlineAsmOp:
elementtype, side effects, align stack, asm dialect and operand attrs.
Diffstat (limited to 'mlir/lib/Target/LLVMIR/ModuleImport.cpp')
-rw-r--r-- | mlir/lib/Target/LLVMIR/ModuleImport.cpp | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index 7d7d0bb..3f1884d 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -2073,6 +2073,40 @@ LogicalResult ModuleImport::convertIntrinsic(llvm::CallInst *inst) { return emitError(loc) << "unhandled intrinsic: " << diag(*inst); } +ArrayAttr +ModuleImport::convertAsmInlineOperandAttrs(const llvm::CallBase &llvmCall) { + const auto *ia = cast<llvm::InlineAsm>(llvmCall.getCalledOperand()); + unsigned argIdx = 0; + SmallVector<mlir::Attribute> opAttrs; + bool hasIndirect = false; + + for (const llvm::InlineAsm::ConstraintInfo &ci : ia->ParseConstraints()) { + // Only deal with constraints that correspond to call arguments. + if (ci.Type == llvm::InlineAsm::isLabel || !ci.hasArg()) + continue; + + // Only increment `argIdx` in terms of constraints containing arguments, + // which are guaranteed to happen in the same order of the call arguments. + if (ci.isIndirect) { + if (llvm::Type *paramEltType = llvmCall.getParamElementType(argIdx)) { + SmallVector<mlir::NamedAttribute> attrs; + attrs.push_back(builder.getNamedAttr( + mlir::LLVM::InlineAsmOp::getElementTypeAttrName(), + mlir::TypeAttr::get(convertType(paramEltType)))); + opAttrs.push_back(builder.getDictionaryAttr(attrs)); + hasIndirect = true; + } + } else { + opAttrs.push_back(builder.getDictionaryAttr({})); + } + argIdx++; + } + + // Avoid emitting an array where all entries are empty dictionaries. + return hasIndirect ? ArrayAttr::get(mlirModule->getContext(), opAttrs) + : nullptr; +} + LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) { // Convert all instructions that do not provide an MLIR builder. Location loc = translateLoc(inst->getDebugLoc()); @@ -2159,14 +2193,17 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) { Type resultTy = convertType(callInst->getType()); if (!resultTy) return failure(); + ArrayAttr operandAttrs = convertAsmInlineOperandAttrs(*callInst); return builder .create<InlineAsmOp>( loc, resultTy, *operands, builder.getStringAttr(asmI->getAsmString()), builder.getStringAttr(asmI->getConstraintString()), - /*has_side_effects=*/true, - /*is_align_stack=*/false, /*asm_dialect=*/nullptr, - /*operand_attrs=*/nullptr) + asmI->hasSideEffects(), asmI->isAlignStack(), + AsmDialectAttr::get( + mlirModule.getContext(), + convertAsmDialectFromLLVM(asmI->getDialect())), + operandAttrs) .getOperation(); } bool isIncompatibleCall; |