Skip to content

Commit

Permalink
[Salvage] Change salvage debug info implementation to use DW_OP_LLVM_…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
SLTozer committed May 15, 2019
1 parent 157ae63 commit 17dd4d7
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
23 changes: 21 additions & 2 deletions llvm/lib/Transforms/Utils/Local.cpp
Expand Up @@ -1690,8 +1690,27 @@ DIExpression *llvm::salvageDebugInfoImpl(Instruction &I,
// No-op casts and zexts are irrelevant for debug info.
if (CI->isNoopCast(DL) || isa<ZExtInst>(&I))
return SrcDIExpr;
return nullptr;
} else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {

Type *Type = CI->getType();
// Casts other than Trunc or SExt to scalar types cannot be salvaged.
if (Type->isVectorTy() || (!isa<TruncInst>(&I) && !isa<SExtInst>(&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<SExtInst>(&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<GetElementPtrInst>(&I)) {
unsigned BitWidth =
M.getDataLayout().getIndexSizeInBits(GEP->getPointerAddressSpace());
// Rewrite a constant GEP into a DIExpression.
Expand Down
25 changes: 25 additions & 0 deletions 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(
2 changes: 2 additions & 0 deletions llvm/test/Transforms/InstCombine/cast-mul-select.ll
Expand Up @@ -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]]
Expand Down

0 comments on commit 17dd4d7

Please sign in to comment.