[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

     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 

   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,

   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