Alex Susu via llvm-dev
2017-Jul-14 09:57 UTC
[llvm-dev] Strange assertion error in RegisterCoalescer.cpp - "Missing recursion" - related to bundles needed for predicated blocks
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?