From 17dd4d7403770bd683675e45f5517e0cdb8f9b2b Mon Sep 17 00:00:00 2001 From: Stephen Tozer Date: Wed, 15 May 2019 13:15:48 +0000 Subject: [PATCH] [Salvage] Change salvage debug info implementation to use DW_OP_LLVM_convert where needed Fixes issue: https://bugs.llvm.org/show_bug.cgi?id=40645 Previously, LLVM had no functional way of performing casts inside of a DIExpression(), which made salvaging cast instructions other than Noop casts impossible. With the recent addition of DW_OP_LLVM_convert this salvaging is now possible, and so can be used to fix the attached bug as well as any cases where SExt instruction results are lost in the debugging metadata. This patch introduces this fix by expanding the salvage debug info method to cover these cases using the new operator. Differential revision: https://reviews.llvm.org/D61184 llvm-svn: 360772 --- llvm/lib/Transforms/Utils/Local.cpp | 23 ++++++++++++++++++-- llvm/test/DebugInfo/salvage-cast-debug-info.ll | 25 ++++++++++++++++++++++ .../test/Transforms/InstCombine/cast-mul-select.ll | 2 ++ 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100755 llvm/test/DebugInfo/salvage-cast-debug-info.ll diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 2a4e905..04e6cbb 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1690,8 +1690,27 @@ DIExpression *llvm::salvageDebugInfoImpl(Instruction &I, // No-op casts and zexts are irrelevant for debug info. if (CI->isNoopCast(DL) || isa(&I)) return SrcDIExpr; - return nullptr; - } else if (auto *GEP = dyn_cast(&I)) { + + Type *Type = CI->getType(); + // Casts other than Trunc or SExt to scalar types cannot be salvaged. + if (Type->isVectorTy() || (!isa(&I) && !isa(&I))) + return nullptr; + + Value *FromValue = CI->getOperand(0); + unsigned FromTypeBitSize = FromValue->getType()->getScalarSizeInBits(); + + unsigned ToTypeBitSize = Type->getScalarSizeInBits(); + + // The result of the cast will be sign extended iff the instruction is a + // SExt; signedness is otherwise irrelevant on the expression stack. + unsigned Encoding = + isa(&I) ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned; + + return applyOps({dwarf::DW_OP_LLVM_convert, FromTypeBitSize, Encoding, + dwarf::DW_OP_LLVM_convert, ToTypeBitSize, Encoding}); + } + + if (auto *GEP = dyn_cast(&I)) { unsigned BitWidth = M.getDataLayout().getIndexSizeInBits(GEP->getPointerAddressSpace()); // Rewrite a constant GEP into a DIExpression. diff --git a/llvm/test/DebugInfo/salvage-cast-debug-info.ll b/llvm/test/DebugInfo/salvage-cast-debug-info.ll new file mode 100755 index 0000000..1c8196a --- /dev/null +++ b/llvm/test/DebugInfo/salvage-cast-debug-info.ll @@ -0,0 +1,25 @@ +; RUN: opt %s -debugify -early-cse -S | FileCheck %s +define i32 @foo(i64 %nose, i32 %more) { +; CHECK-LABEL: @foo( +; CHECK: call void @llvm.dbg.value(metadata i64 %nose, metadata [[V1:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_convert, 64, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned +; CHECK: call void @llvm.dbg.value(metadata i64 %nose.shift, metadata [[V2:![0-9]+]] +; CHECK: call void @llvm.dbg.value(metadata i64 %nose.shift, metadata [[V3:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_convert, 64, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned + +entry: + %nose.trunc = trunc i64 %nose to i32 + %nose.shift = lshr i64 %nose, 32 + %nose.trunc.2 = trunc i64 %nose.shift to i32 + %add = add nsw i32 %more, 1 + ret i32 %add +} + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 2} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{!"clang version 9.0.0 "} + +; CHECK: [[V1]] = !DILocalVariable( +; CHECK: [[V2]] = !DILocalVariable( +; CHECK: [[V3]] = !DILocalVariable( diff --git a/llvm/test/Transforms/InstCombine/cast-mul-select.ll b/llvm/test/Transforms/InstCombine/cast-mul-select.ll index c501fd8..f82d2fd 100644 --- a/llvm/test/Transforms/InstCombine/cast-mul-select.ll +++ b/llvm/test/Transforms/InstCombine/cast-mul-select.ll @@ -13,6 +13,8 @@ define i32 @mul(i32 %x, i32 %y) { ; we preserve the debug information in the resulting ; instruction. ; DBGINFO-LABEL: @mul( +; DBGINFO-NEXT: call void @llvm.dbg.value(metadata i32 %x +; DBGINFO-NEXT: call void @llvm.dbg.value(metadata i32 %y ; DBGINFO-NEXT: [[C:%.*]] = mul i32 {{.*}} ; DBGINFO-NEXT: [[D:%.*]] = and i32 {{.*}} ; DBGINFO-NEXT: call void @llvm.dbg.value(metadata i32 [[C]] -- 2.7.4