Skip to content

Commit 71fbfb4

Browse files
committed
[WebAssembly] Omit DBG_VALUE after terminator
When a stackified variable has an associated `DBG_VALUE` instruction, DebugFixup pass adds a `DBG_VALUE` instruction after the stackified value's last use to clear the variable's debug range info. But when the last use instruction is a terminator, it can cause a verification failure (when run with `-verify-machineinstrs`) because there are no instructions allowed after a terminator. For example: ``` %myvar = ... DBG_VALUE target-index(wasm-operand-stack), $noreg, !"myvar", ... BR_IF 0, %myvar, ... DBG_VALUE $noreg, $noreg, !"myvar", ... ``` In this test, `%myvar` is stackified, so the first `DBG_VALUE` instruction's first operand has changed to `wasm-operand-stack` to denote it. And an additional `DBG_VALUE` instruction is added after its last use, `BR_IF`, to signal variable `myvar` is not in the operand stack anymore. But because the `DBG_VALUE` instruction is added after the `BR_IF`, a terminator, it fails MachineVerifier. `DBG_VALUE` instructions are used in `DbgEntityHistoryCalculator` to compute value ranges to emit DWARF info, and it turns out the `DbgEntityHistoryCalculator` terminates ranges at the end of a BB, so we don't need to emit `DBG_VALUE` after a terminator. Fixes https://bugs.llvm.org/show_bug.cgi?id=50175. Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D102309
1 parent 8e35a18 commit 71fbfb4

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyDebugFixup.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,17 @@ bool WebAssemblyDebugFixup::runOnMachineFunction(MachineFunction &MF) {
111111
Stack.pop_back();
112112
assert(Prev.Reg == MO.getReg() &&
113113
"WebAssemblyDebugFixup: Pop: Register not matched!");
114-
if (Prev.DebugValue) {
114+
// We should not put a DBG_VALUE after a terminator; debug ranges
115+
// are terminated at the end of a BB anyway.
116+
if (Prev.DebugValue && !MI.isTerminator()) {
115117
// This stackified reg is a variable that started life at
116118
// Prev.DebugValue, so now that we're popping it we must insert
117119
// a $noreg DBG_VALUE for the variable to end it, right after
118120
// the current instruction.
119121
BuildMI(*Prev.DebugValue->getParent(), std::next(MII),
120-
Prev.DebugValue->getDebugLoc(), TII->get(WebAssembly::DBG_VALUE), false,
121-
Register(), Prev.DebugValue->getOperand(2).getMetadata(),
122+
Prev.DebugValue->getDebugLoc(),
123+
TII->get(WebAssembly::DBG_VALUE), false, Register(),
124+
Prev.DebugValue->getOperand(2).getMetadata(),
122125
Prev.DebugValue->getOperand(3).getMetadata());
123126
}
124127
}

llvm/test/CodeGen/WebAssembly/stackified-debug.ll

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
; RUN: llc < %s | FileCheck %s
1+
; RUN: llc -verify-machineinstrs < %s | FileCheck %s
2+
; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s --check-prefix DWARF
23

34
; Input C code:
45

@@ -42,8 +43,6 @@
4243
; CHECK: .int8 159 # DW_OP_stack_value
4344

4445

45-
46-
4746
source_filename = "stackified.c"
4847
target triple = "wasm32-unknown-unknown"
4948

@@ -57,10 +56,32 @@ entry:
5756
ret void, !dbg !22
5857
}
5958

60-
declare i32 @input()
59+
; DebugFixup pass should not add a DBG_VALUE after the BR_IF instruction at the
60+
; end of the 'entry' BB, because it is not allowed to have more instructions
61+
; after a terminator and debug ranges are terminated at the end of a BB anyway.
62+
; If this passes 'llc -verify-machineinstrs', that means the DBG_VALUE
63+
; instruction is correctly omitted.
64+
65+
; DWARF-LABEL: DW_AT_name ("no_dbg_value_after_terminator")
66+
; DWARF: DW_TAG_variable
67+
; DWARF-NEXT: DW_AT_location
68+
; DWARF-NEXT: [
69+
; DWARF-NEXT: DW_AT_name ("myvar")
70+
define void @no_dbg_value_after_terminator(i32 %a, i32 %b) !dbg !23 {
71+
entry:
72+
%cmp = icmp ne i32 %a, %b, !dbg !25
73+
call void @llvm.dbg.value(metadata i1 %cmp, metadata !27, metadata !DIExpression(DW_OP_LLVM_convert, 1, DW_ATE_unsigned, DW_OP_LLVM_convert, 8, DW_ATE_unsigned, DW_OP_stack_value)), !dbg !25
74+
br i1 %cmp, label %bb.1, label %bb.0, !dbg !25
6175

62-
declare !dbg !4 void @output(i32, i32)
76+
bb.0: ; preds = %entry
77+
unreachable
6378

79+
bb.1: ; preds = %entry
80+
ret void
81+
}
82+
83+
declare i32 @input()
84+
declare !dbg !4 void @output(i32, i32)
6485
declare void @llvm.dbg.value(metadata, metadata, metadata)
6586

6687
!llvm.dbg.cu = !{!0}
@@ -90,3 +111,9 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
90111
!20 = !DILocation(line: 5, column: 11, scope: !12)
91112
!21 = !DILocation(line: 6, column: 3, scope: !12)
92113
!22 = !DILocation(line: 7, column: 1, scope: !12)
114+
!23 = distinct !DISubprogram(name: "no_dbg_value_after_terminator", scope: null, type: !24, spFlags: DISPFlagDefinition, unit: !0)
115+
!24 = !DISubroutineType(types: !2)
116+
!25 = !DILocation(line: 0, scope: !26)
117+
!26 = distinct !DILexicalBlock(scope: !23)
118+
!27 = !DILocalVariable(name: "myvar", scope: !26, type: !28)
119+
!28 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean)

0 commit comments

Comments
 (0)