[llvm-bugs] [Bug 50359] New: [WebAssembly] WebAssemblyOptimizeLiveIntervals does not split DBG_VALUEs
via llvm-bugs
llvm-bugs at lists.llvm.org
Sun May 16 00:41:47 PDT 2021
https://bugs.llvm.org/show_bug.cgi?id=50359
Bug ID: 50359
Summary: [WebAssembly] WebAssemblyOptimizeLiveIntervals does
not split DBG_VALUEs
Product: libraries
Version: trunk
Hardware: All
OS: All
Status: NEW
Severity: normal
Priority: P
Component: Backend: WebAssembly
Assignee: unassignedbugs at nondot.org
Reporter: aheejin at gmail.com
CC: aardappel at gmail.com, dschuff at google.com,
llvm-bugs at lists.llvm.org, ydelendik at mozilla.com
WebAssemblyOptimizeLiveIntervals pass splits register live intervals by
splitting a single register having multiple defs into multiple registers. But
it does not handle splitting of corresponding DBG_VALUE instructions. For
example:
test.ll:
```
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
define i32 @test(i32* %arg0, i32* %arg1) {
entry:
%tmp0 = load i32, i32* %arg0
%tmp1 = load i32, i32* %arg1
%tmp2 = add i32 %tmp0, %tmp1
call void @llvm.dbg.value(metadata i32 %tmp0, metadata !6, metadata
!DIExpression()), !dbg !8
ret i32 %tmp2
}
declare void @llvm.dbg.value(metadata, metadata, metadata)
!llvm.module.flags = !{!0}
!llvm.dbg.cu = !{!1}
!0 = !{i32 2, !"Debug Info Version", i32 3}
!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang
version 3.9.0 (trunk 266005) (llvm/trunk 266105)", isOptimized: false,
runtimeVersion: 0, emissionKind: FullDebug, enums: !3)
!2 = !DIFile(filename: "test.c", directory: "/")
!3 = !{}
!4 = distinct !DISubprogram(name: "test", scope: !2, file: !2, line: 10, type:
!5, isLocal: false, isDefinition: true, scopeLine: 11, flags: DIFlagPrototyped,
isOptimized: true, unit: !1, retainedNodes: !3)
!5 = !DISubroutineType(types: !3)
!6 = !DILocalVariable(name: "var", scope: !4, file: !2, line: 15, type: !7)
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!8 = !DILocation(line: 15, column: 6, scope: !4)
```
Run:
$ llc -print-after-all test.ll
Right before WebAssemblyOptimizeLiveIntervals, the function is:
```
Function Live Ins: $arguments
bb.0.entry:
liveins: $arguments
%2:i32 = ARGUMENT_i32 0, implicit $arguments
%0:i32 = ARGUMENT_i32 1, implicit $arguments
dead %4:i32 = IMPLICIT_DEF
dead %3:i32 = IMPLICIT_DEF
dead %1:i32 = IMPLICIT_DEF
%1:i32 = LOAD_I32_A32 2, 0, %0:i32, implicit-def dead $arguments :: (load 4
from %ir.arg1)
%3:i32 = LOAD_I32_A32 2, 0, %2:i32, implicit-def dead $arguments :: (load 4
from %ir.arg0)
%4:i32 = ADD_I32 %3:i32, %1:i32, implicit-def dead $arguments
DBG_VALUE %3:i32, $noreg, !"var", !DIExpression(), debug-location !8;
test.c:15:6 line no:15
RETURN %4:i32, implicit-def dead $arguments
```
(Here IMPLICIT_DEFs were added by WebAssemblyPrepareForLiveIntervals pass)
Note that the DBG_VALUE is referring to %3, the result of LOAD_I32_A32.
WebAssemblyOptimizeLiveIntervals pass currently consists of two parts. First
part splits live ranges, and the second part removes unnecessary IMPLICIT_DEF
instructions added by WebAssemblyPrepareForLiveIntervals pass.
After the first part (splitting live ranges), this becomes:
```
Function Live Ins: $arguments
bb.0.entry:
liveins: $arguments
%2:i32 = ARGUMENT_i32 0, implicit $arguments
%0:i32 = ARGUMENT_i32 1, implicit $arguments
dead %4:i32 = IMPLICIT_DEF
dead %3:i32 = IMPLICIT_DEF
dead %1:i32 = IMPLICIT_DEF
%5:i32 = LOAD_I32_A32 2, 0, %0:i32, implicit-def dead $arguments :: (load 4
from %ir.arg1)
%6:i32 = LOAD_I32_A32 2, 0, %2:i32, implicit-def dead $arguments :: (load 4
from %ir.arg0)
%7:i32 = ADD_I32 %6:i32, %5:i32, implicit-def dead $arguments
DBG_VALUE %3:i32, $noreg, !"var", !DIExpression(), debug-location !8;
test.c:15:6 line no:15
RETURN %7:i32, implicit-def dead $arguments
```
Now %3 is split into %3 and %6, each of which has a single def. Here
DBG_VALUE's operand needs to change from %3 to %6 as well but it doesn't, which
is a bug.
After the second part (removing unnecessary IMPLICIT_DEFs), this becomes:
```
Function Live Ins: $arguments
bb.0.entry:
liveins: $arguments
%2:i32 = ARGUMENT_i32 0, implicit $arguments
%0:i32 = ARGUMENT_i32 1, implicit $arguments
%5:i32 = LOAD_I32_A32 2, 0, %0:i32, implicit-def dead $arguments :: (load 4
from %ir.arg1)
%6:i32 = LOAD_I32_A32 2, 0, %2:i32, implicit-def dead $arguments :: (load 4
from %ir.arg0)
%7:i32 = ADD_I32 %6:i32, %5:i32, implicit-def dead $arguments
DBG_VALUE %3:i32, $noreg, !"var", !DIExpression(), debug-location !8;
test.c:15:6 line no:15
RETURN %7:i32, implicit-def dead $arguments
```
Now IMPLICIT_DEFs are removed and the DBG_VALUE's operand %3 does not even have
a def.
---
Note that this bug is not related to generation and removal of IMPLICIT_DEFs;
they happen to appear in this example, and the bug is that when we split live
ranges, we don't handle their corresponding DBG_VALUE instructions.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210516/598fd560/attachment.html>
More information about the llvm-bugs
mailing list