Unexpected branching behaviour when creating new basic blocks


I created a function that lowers SLL to a few substitute instructions in multiple basic blocks, as mentioned in this question. I’m now trying to compile picolibc, but it fails on the file regexec.c. Looking deeper, it seems to be caused by a situation involving two consecutive SHL instructions in LLVM IR.

Looking at the error messages and the Machine IR itself, it looks like the branching behaviour is somehow getting messed up, such as incorrect blocks listed as successors, phi operands coming from non-predecessor blocks, and an empty basic block.

Isolated SHL instructions compile successfully, as well as situations with two SHL instructions separated by at least one other instruction. However, reordering statements in regexec.ll such that the two SHL instructions aren’t sequential (by moving %coldp134.i.i assignment one line up) didn’t compile.

Any guidance as to why this might be happening would be greatly appreciated.

I’ve attached the relevant portions of my lowering code, LLVM IR and llc output with --debug and -verify-machininstrs.
llc-debug-output-trimmed.txt (12.7 KB)
RISCVISelLowering-trimmed.cpp (3.2 KB)
regexec-ir-trimmed.txt (3.9 KB)

One thing that jumped out at me is that you shouldn’t need to call MBBTail->transferSuccessorsAndUpdatePHIs(MBBOrig); if you called splitAt. splitAt already called transferSuccessorsAndUpdatePHIs. After the call to splitAt, MBBOrig has MBBTail as its only successor. It doesn’t make sense to copy that to MBBTail.

Good to know. I actually added that line after the fact thinking maybe it would fix the issue, but it was failing before that as well with the same errors.

Another issue is that MBBOrig still has MBBTail as a successor from the splitAt call.