llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.67k stars 11.85k forks source link

simple-register-coalescing fails to update/invalidate DBG_VALUE #49957

Open markuslavin opened 3 years ago

markuslavin commented 3 years ago
Bugzilla Link 50613
Version trunk
OS All
Blocks llvm/llvm-project#30616
Attachments Reproducer input for Arm target.
CC @dstenb,@jmorse,@jdm

Extended Description

With input as follows

bb.0: liveins: $r0 %4:gpr = COPY $r0 %9:gpr = COPY %4 %9:gpr = ADDri %9, 4, 14, $noreg, $noreg %12:gpr = COPY %9 B %bb.1 bb.1: %10:gpr = COPY %12 DBG_VALUE %4, $noreg, !​10, !DIExpression(), debug-location !​8 %11:gpr = COPY %10 %11:gpr = ADDri %11, 4, 14, $noreg, $noreg %12:gpr = COPY %11 B %bb.1

after issuing $ llc dbg-coalesc-arm-reduced.mir -run-pass=liveintervals -run-pass=simple-register-coalescing -o - -debug-only=regalloc we get

bb.0: successors: %bb.1(0x80000000) liveins: $r0

%2:gpr = COPY $r0
%2:gpr = ADDri %2, 4, 14 /* CC::al */, $noreg, $noreg
B %bb.1

bb.1: successors: %bb.1(0x80000000)

DBG_VALUE %2, $noreg, <0xa03e470>, !DIExpression(), debug-location !DILocation(line: 1, column: 1, scope: <0xa03e520>)
%2:gpr = ADDri %2, 4, 14 /* CC::al */, $noreg, $noreg
B %bb.1

That is the DBG_VALUE is now using a register with different value (previously $r0 but now $r0+4).

I believe this situation should be handled by

commit d9c9a4e48d286a04d09a8fdea87f486a9ec02cd0 Author: Jeremy Morse jeremy.morse@sony.com Date: Mon Nov 25 13:38:27 2019 +0000

[DebugInfo] Avoid register coalesing unsoundly changing DBG_VALUE locations

PS. It took a while to get to this reproducer so obviously it does handle quite a few similar situations.

jmorse commented 3 years ago

Misery. checkMergingChangesDbgValues is supposed to be able to detect these scenarios, I've been vaguely aware that there's a scenario that isn't covered, this reproducer looks like it's found it. Core to this problem is that I don't fully understand the different merge strategies that register-coalesing uses :|.

Note that this isn't high on my priority list to fix; checkMergingChangesDbgValues only ever destroys variable locations, the oft-plugged instruction referencing work can actually preserve them. The optimal solution is killing off DBG_VALUEs / DBG_VALUE_LISTs, as it's the wrong representation to cope with things like register coalescing.