diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -14,8 +14,10 @@ #include "llvm/IR/AutoUpgrade.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" @@ -27,6 +29,7 @@ #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsX86.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/ErrorHandling.h" @@ -844,6 +847,11 @@ break; } case 'd': { + if (Name == "dbg.addr") { + rename(F); + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value); + return true; + } if (Name == "dbg.value" && F->arg_size() == 4) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value); @@ -4128,7 +4136,20 @@ NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)}); break; - case Intrinsic::dbg_value: + case Intrinsic::dbg_value: { + StringRef Name = F->getName(); + Name = Name.substr(5); // Strip llvm. + // Upgrade `dbg.addr` to `dbg.value` with `DW_OP_deref`. + if (Name.startswith("dbg.addr")) { + DIExpression *Expr = cast( + cast(CI->getArgOperand(2))->getMetadata()); + Expr = DIExpression::append(Expr, dwarf::DW_OP_deref); + NewCall = + Builder.CreateCall(NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), + MetadataAsValue::get(C, Expr)}); + break; + } + // Upgrade from the old version that had an extra offset argument. assert(CI->arg_size() == 4); // Drop nonzero offsets instead of attempting to upgrade them. @@ -4141,6 +4162,7 @@ } CI->eraseFromParent(); return; + } case Intrinsic::ptr_annotation: // Upgrade from versions that lacked the annotation attribute argument. diff --git a/llvm/test/Bitcode/upgrade-dbg-addr.ll b/llvm/test/Bitcode/upgrade-dbg-addr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/upgrade-dbg-addr.ll @@ -0,0 +1,33 @@ +; Test upgrade of dbg.addr intrinsics into dbg.value with DW_OP_deref appended +; +; RUN: llvm-dis < %s.bc | FileCheck %s +; RUN: verify-uselistorder < %s.bc + +define i32 @example(i32 %num) { +entry: + %num.addr = alloca i32, align 4 + store i32 %num, ptr %num.addr, align 4 + ; CHECK-NOT: call void @llvm.dbg.addr + ; CHECK: call void @llvm.dbg.value(metadata ptr %num.addr, metadata ![[#]], metadata !DIExpression(DW_OP_plus_uconst, 0, DW_OP_deref)) + call void @llvm.dbg.addr(metadata ptr %num.addr, metadata !16, metadata !DIExpression(DW_OP_plus_uconst, 0)), !dbg !17 + %0 = load i32, ptr %num.addr, align 4 + ret i32 %0 +} + +; CHECK: declare void @llvm.dbg.value(metadata, metadata, metadata) +declare void @llvm.dbg.addr(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1) +!1 = !DIFile(filename: "/app/example.c", directory: "/app") +!2 = !{i32 2, !"Debug Info Version", i32 3} +!10 = distinct !DISubprogram(name: "example", scope: !11, file: !11, line: 1, type: !12, scopeLine: 1, unit: !0, retainedNodes: !15) +!11 = !DIFile(filename: "example.c", directory: "/app") +!12 = !DISubroutineType(types: !13) +!13 = !{!14} +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !{} +!16 = !DILocalVariable(name: "num", arg: 1, scope: !10, file: !11, line: 1, type: !14) +!17 = !DILocation(line: 1, column: 17, scope: !10) diff --git a/llvm/test/Bitcode/upgrade-dbg-addr.ll.bc b/llvm/test/Bitcode/upgrade-dbg-addr.ll.bc new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@