From: Christian Ulmann Date: Thu, 16 Feb 2023 14:44:05 +0000 (+0100) Subject: [mlir][llvm] Use before def debug intrinsic import X-Git-Tag: upstream/17.0.6~17283 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=28542e99bb82b32dfc80ad372fcde3a016a8ca0b;p=platform%2Fupstream%2Fllvm.git [mlir][llvm] Use before def debug intrinsic import This commit adds special handling for the debug intrinsic value handling. LLVM allows to relax the def before use property for debug intrinsics, so this property cannot be assumed for metadata values. Reviewed By: gysit Differential Revision: https://reviews.llvm.org/D144177 --- diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td index 227a192..76e5b34 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td @@ -291,9 +291,13 @@ class LLVM_DbgIntrOp : LLVM_IntrOp argOperand = moduleImport.convertValue(llvmOperands[0]); + + FailureOr argOperand = moduleImport.convertMetadataValue(llvmOperands[0]); + // Drop the intrinsic when its operand could not be converted. This can + // happen for use before definition cases that are allowed for debug + // intrinsics. if (failed(argOperand)) - return failure(); + return success(); $_op = $_builder.create<$_qualCppClassName>($_location, *argOperand, $_var_attr($varInfo)); }]; diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h index aaf9b2c..be4f6e5 100644 --- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h @@ -119,6 +119,11 @@ public: /// LLVM values. FailureOr convertValue(llvm::Value *value); + /// Converts an LLVM metadata value to an MLIR value, or returns failure if + /// the conversion fails. Uses the `convertConstant` method to translate + /// constant LLVM values. + FailureOr convertMetadataValue(llvm::Value *value); + /// Converts a range of LLVM values to a range of MLIR values using the /// `convertValue` method, or returns failure if the conversion fails. FailureOr> convertValues(ArrayRef values); diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index ed462d8..d24f586 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -1132,11 +1132,8 @@ FailureOr ModuleImport::convertConstantExpr(llvm::Constant *constant) { } FailureOr ModuleImport::convertValue(llvm::Value *value) { - // A value may be wrapped as metadata, for example, when passed to a debug - // intrinsic. Unwrap these values before the conversion. - if (auto *nodeAsVal = dyn_cast(value)) - if (auto *node = dyn_cast(nodeAsVal->getMetadata())) - value = node->getValue(); + assert(!isa(value) && + "expected value to not be metadata"); // Return the mapped value if it has been converted before. if (valueMapping.count(value)) @@ -1152,6 +1149,27 @@ FailureOr ModuleImport::convertValue(llvm::Value *value) { return emitError(loc) << "unhandled value: " << diag(*value); } +FailureOr ModuleImport::convertMetadataValue(llvm::Value *value) { + // A value may be wrapped as metadata, for example, when passed to a debug + // intrinsic. Unwrap these values before the conversion. + auto *nodeAsVal = dyn_cast(value); + if (!nodeAsVal) + return failure(); + auto *node = dyn_cast(nodeAsVal->getMetadata()); + if (!node) + return failure(); + value = node->getValue(); + + // Return the mapped value if it has been converted before. + if (valueMapping.count(value)) + return lookupValue(value); + + // Convert constants such as immediate values that have no mapping yet. + if (auto *constant = dyn_cast(value)) + return convertConstantExpr(constant); + return failure(); +} + FailureOr> ModuleImport::convertValues(ArrayRef values) { SmallVector remapped; diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll index 6dc5463..896d422 100644 --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -344,3 +344,26 @@ declare !dbg !3 void @variadic_func() !3 = !DISubprogram(name: "variadic_func", scope: !2, file: !2, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, type: !4) !4 = !DISubroutineType(types: !5) !5 = !{null, null} + +; // ----- + +define void @dbg_use_before_def(ptr %arg) { + call void @llvm.dbg.value(metadata ptr %dbg_arg, metadata !7, metadata !DIExpression()), !dbg !9 + %dbg_arg = getelementptr double, ptr %arg, i64 16 + ret void +} + +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!1} +!llvm.module.flags = !{!0} +!0 = !{i32 2, !"Debug Info Version", i32 3} +!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2) +!2 = !DIFile(filename: "debug-info.ll", directory: "/") +!3 = !DICompositeType(tag: DW_TAG_class_type, name: "class_field", file: !2, line: 42, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !4) +!4 = !{!6} +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !3, flags: DIFlagArtificial | DIFlagObjectPointer) +!6 = !DIDerivedType(tag: DW_TAG_member, name: "call_field", file: !2, baseType: !5) +!7 = !DILocalVariable(scope: !8, name: "var", file: !2, type: !5); +!8 = distinct !DISubprogram(name: "dbg_use_before_def", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1) +!9 = !DILocation(line: 1, column: 2, scope: !8)