// argument variable would not work here, since the builder variables are
// converted before entering the builder, which would result in an error
// when attempting to convert an argument list.
- FailureOr<Value> argOperand = moduleImport.convertValue(llvmOperands[0]);
+
+ FailureOr<Value> 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));
}];
/// LLVM values.
FailureOr<Value> 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<Value> 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<SmallVector<Value>> convertValues(ArrayRef<llvm::Value *> values);
}
FailureOr<Value> 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<llvm::MetadataAsValue>(value))
- if (auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata()))
- value = node->getValue();
+ assert(!isa<llvm::MetadataAsValue>(value) &&
+ "expected value to not be metadata");
// Return the mapped value if it has been converted before.
if (valueMapping.count(value))
return emitError(loc) << "unhandled value: " << diag(*value);
}
+FailureOr<Value> 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<llvm::MetadataAsValue>(value);
+ if (!nodeAsVal)
+ return failure();
+ auto *node = dyn_cast<llvm::ValueAsMetadata>(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<llvm::Constant>(value))
+ return convertConstantExpr(constant);
+ return failure();
+}
+
FailureOr<SmallVector<Value>>
ModuleImport::convertValues(ArrayRef<llvm::Value *> values) {
SmallVector<Value> remapped;
!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)