llvm / llvm-project

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

-verify-regalloc discovers "Instruction ending live segment on dead slot has no dead flag" #32371

Open JonPsson opened 7 years ago

JonPsson commented 7 years ago
Bugzilla Link 33024
Version trunk
OS Linux
Attachments reduced testcase
CC @MatzeB,@JonPsson,@uweigand

Extended Description

With this reduced llvm-stress test case, run with

llc -mtriple=s390x-linux-gnu -mcpu=z13 -verify-regalloc -disable-lsr -disable-machine-licm -disable-machine-dce -join-liveintervals=false -o /dev/null ./tc_deadslot.ll

It seems that loadRegFromStackSlot() is called, and then verifier complains that the created instruction is missing a dead-flag. I am not sure where this should be fixed...

Output:

0B BB#0: derived from LLVM BB %BB Live Ins: %R2L 16B %vreg5 = COPY %R2L; GR32Bit:%vreg5 32B %vreg10 = VGBM 0; VR128Bit:%vreg10 48B VST %vreg10, <fi#0>, 0, %noreg; mem:ST16FixedStack0 VR128Bit:%vreg10 Successors according to CFG: BB#1(?%)

64B BB#1: derived from LLVM BB %CF253 Predecessors according to CFG: BB#0 BB#1 72B %vreg11 = VGBM 0; VR128Bit:%vreg11 80B %vreg3 = COPY %vreg11; VR128Bit:%vreg3,%vreg11 96B %vreg3<def,dead,tied1> = VLVGF %vreg3, %vreg5, %noreg, 2; VR128Bit:%vreg3 GR32Bit:%vreg5 112B ADJCALLSTACKDOWN 0 128B %vreg6 = LZDR; FP64Bit:%vreg6 144B %F0D = COPY %vreg6; FP64Bit:%vreg6 160B %F2D = COPY %vreg6; FP64Bit:%vreg6 176B CallBRASL , %F0D, %F2D, <regmask %F8D %F9D %F10D %F11D %F12D %F13D %F14D %F15D %F8S %F9S %F10S %F11S %F12S %F13S %F14S %F15S %R6D %R7D %R8D %R9D %R10D %R11D %R12D %R13D %R14D %R15D %R6H %R7H %R8H %R9H %R10H %R11H %R12H %R13H %R14H %R15H %R6L %R7L %R8L %R9L %R10L %R11L %R12L %R13L %R14L %R15L>, %CC<imp-def,dead>, %F0D, ... 192B ADJCALLSTACKUP 0, 0 208B %vreg7 = COPY %F0D; VR64Bit:%vreg7 224B %vreg2 = VL <fi#0>, 0, %noreg; mem:LD16FixedStack0 VR128Bit:%vreg2 240B %vreg4<def,dead> = COPY %vreg7; VR64Bit:%vreg4,%vreg7 256B %vreg8 = LHIMux 0; GRX32Bit:%vreg8 272B CHIMux %vreg8, 0, %CC; GRX32Bit:%vreg8 288B BRC 14, 6, <BB#1>, %CC<imp-use,kill> 304B J <BB#2> Successors according to CFG: BB#1(0x7c000000 / 0x80000000 = 96.88%) BB#2(0x04000000 / 0x80000000 = 3.12%)

320B BB#2: derived from LLVM BB %CF258 Predecessors according to CFG: BB#1 BB#2 336B J <BB#2> Successors according to CFG: BB#2(?%)

End machine code for function autogen_SD9889.

Bad machine code: Instruction ending live segment on dead slot has no dead flag

bjope commented 2 years ago

mentioned in issue llvm/llvm-bugzilla-archive#39154

JonPsson commented 6 years ago

reduced testcase that works on trunk Old test case seem to not trigger the bug anymore.

Run new test case with:

bin/llc -mtriple=s390x-linux-gnu -mcpu=z13 -disable-machine-dce -join-liveintervals=false -verify-machineinstrs -o /dev/null ./tc_deadslot_2.ll

=>

Bad machine code: Instruction ending live segment on dead slot has no dead flag

JonPsson commented 6 years ago

ping! I see this assertion not that unfrequently with csmith programs.

JonPsson commented 7 years ago

It seems that this was actually a dead COPY to begin with:

IR Dump After Live Register Matrix :

224B %vreg2<def,dead> = COPY %vreg0; VR128Bit:%vreg2,%vreg0

After spilling

224B %vreg2 = VL <fi#0>, 0, %noreg; mem:LD16[FixedStack0]

*** Bad machine code: Instruction ending live segment on dead slot has no dead fl

It looks like %vreg0 was spilled, but it is only reloaded once into a dead register. Eventually, loadRegFromStackSlot() is called which fails to preserve the dead flag.

Perhaps the dead COPY should just be removed somewhere before that point?

MatzeB commented 7 years ago

To answer this question we would need more information on how this happens. You would expect code that calls loadRegFromStackSlot() has at least 1 one user at the moment it is called. If that is not the case then the bug is there.

If the user is later removed for some reason then we have to set the dead flag at that point and the bug would be there.