[llvm-dev] Strange assertion error in RegisterCoalescer.cpp - "Missing recursion" - related to bundles needed for predicated blocks
Alex Susu via llvm-dev
llvm-dev at lists.llvm.org
Fri Jul 14 02:57:30 PDT 2017
Hello.
I get a "Missing recursion" assertion error in RegisterCoalescer.cpp when using
bundles (bundles created but not finalized) such as:
3760B %vreg186<def,dead> = EQ_H %vreg163, %vreg65
* NOP_BPF 1; dbg:test.c:11:21
* %vreg187<def,tied1> = WHEREEQ %vreg186<internal,tied0>
* %vreg188<def,tied1> = NOP_BITCONVERT_WH %vreg11<tied0>
* %vreg189<def,tied3> = ORV_SPECIAL_H %vreg185, %vreg185, %vreg79<tied0>
* %vreg190<def,tied1> = END_WHERE %vreg189<internal,tied0>
// Bundle has finished. Now we COPY using the def of vreg190 created inside the bundle
3776B %vreg191<def> = COPY %vreg190
3792B %vreg191<def,tied1> = NOP_BITCONVERT_HW %vreg191<tied0>
The error I get in the RegisterCoalescer.cpp pass for the above code is:
3776B %vreg191<def> = COPY %vreg190
Considering merging to MSA128H with %vreg190 in %vreg191
RHS = %vreg190 [3760r,3776r:0) 0 at 3760r
LHS = %vreg191 [3776r,3792r:0)[3792r,3808r:1) 0 at 3776r 1 at 3792r
llc: /llvm/lib/CodeGen/RegisterCoalescer.cpp:2261: void
{anonymous}::JoinVals::computeAssignment(unsigned int, {anonymous}::JoinVals&): Assertion
`Other.Vals[V.OtherVNI->id].isAnalyzed() && "Missing recursion"' failed.
The error is given because I (the NOP_BITCONVERT_HW instruction) use outside of the
bundle a vreg (virtual register) defined in the bundle and the TwoAddressInstructionPass
creates a COPY instruction outside of the bundle just before the use, but then the
RegisterCoalescer pass does NOT really know to handle a COPY using a vreg defined inside a
bundle.
Similarly, another bundle triggering the same error and the following instructions:
3696B %vreg181<def,dead> = EQ_H %vreg180, %vreg86
* NOP_BPF 1; dbg:test.c:11:21
* %vreg182<def,tied1> = WHEREEQ %vreg181<internal,tied0>
* %vreg183<def,tied3> = SUBV_SPECIAL_H %vreg65, %vreg78, %vreg78<tied0>
* %vreg79<def,tied3> = SUBCV_SPECIAL_H %vreg65, %vreg179, %vreg77<tied0>
* %vreg184<def,tied1> = END_WHERE %vreg79<internal,tied0>
// Bundle has finished. Pasting following instructions:
[...]
3856B %vreg189<def> = COPY %vreg79 // We COPY the def of vreg79 created
inside the bundle
3872B %vreg189<def,tied3> = ORV_SPECIAL_H %vreg185, %vreg185, %vreg189<tied0>
Here, I get a similar error from RegisterCoalescer:
3856B %vreg189<def> = COPY %vreg79; MSA128H:%vreg189,%vreg79 dbg:test.c:11:21
Considering merging to MSA128H with %vreg79 in %vreg189
RHS = %vreg79 [3696r,3856r:0) 0 at 3696r
LHS = %vreg189 [3856r,3872r:0)[3872r,3888r:1) 0 at 3856r 1 at 3872r
llc: /llvm/lib/CodeGen/RegisterCoalescer.cpp:2261: void
{anonymous}::JoinVals::computeAssignment(unsigned int, {anonymous}::JoinVals&): Assertion
`Other.Vals[V.OtherVNI->id].isAnalyzed() && "Missing recursion"' failed.
NOTE: I am aware that the ARM back end does something similar to support its
predicated IT block-predication instruction family in ARM/Thumb2ITBlockPass.cpp. Basically
this pass is creating a bundle for the predicated "block" of instructions after the
TwoAddressInstructionPass and RegisterCoalescer passes have already run (before running
the 2nd scheduling pass), to avoid the scheduler to change the order, etc of the
instructions in this predicated IT block; also Thumb2ITBlockPass moves any eventual COPY
instructions in the predicated IT block before it.
But the ARM/Thumb2ITBlockPass.cpp does NOT experience the issues I describe here
because his pass runs after the TwoAddressInstructionPass and RegisterCoalescer passes,
while I create bundles before them since bundles (created but not finalized, a small
detail that should not matter I guess) prevent the TwoAddressInstructionPass to generate
COPY instructions inside the code they pack.
Can somebody help me with this error? (I would like to mention I prefer not creating
an extra bundle with the instruction with the vreg use to avoid this error. Also, I can
provide an entire debug output of llc, if required.)
Thank you very much,
Alex
PS: Another rather different possibility to help me address the issue of avoiding
inserting new instructions in a block of predicated instructions (because such things
alter the semantics of my program): should we maybe make the TwoAddressInstructionPass and
RegisterCoalescer passes predication block aware?
More information about the llvm-dev
mailing list