ARMConstantIslands: Can a basic block that ends with a conditional branch fall through to the next basic block?

Hi!

In order to fix a conditional branch whose target is out of its range, ARMConstantIslands::fixupConditionalBr may split a basic block before the conditional branch.

The following code determines whether the basic block should be split (NeedSplit is true) or not:

bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB);

From the comment above:

// If the branch is at the end of its MBB and that has a fall-through block,
// direct the updated conditional branch to the fall-through block. Otherwise,
// split the MBB before the next instruction.

It can be seen that NeedSplit == true corresponds to the opposite of the case where the basic block ends with a conditional branch and may fall through to the next basic block.

Theoretically, it seems to be possible for a basic block that cannot fall through to the next basic block to contain a conditional branch at the end, if there is an unconditional branch before the conditional branch (ARMBaseInstrInfo::analyzeBranch handles such a case). In this case, the conditional branch is never executed.

Is it possible for LLVM to generate such a basic block before ARMConstantIslands? If it is, could you show me an example where such a conditional branch is useful?

How should ARMConstantIslands::fixupConditionalBr handle this case? The current implementation (version 4.0.0) would:

  1. Split the basic block before the original conditional branch, producing two basic blocks MBB (before the split point) and NextBB (after the split point);

  2. Add a new conditional branch targeting NextBB at the end of MBB;

  3. Add a new unconditional branch after the new conditional branch that targets the target of the original conditional branch;

  4. Remove the original conditional branch.

This produces an empty basic block when the original conditional branch is removed from NextBB, since it is the only instruction in NextBB. And the the empty basic block is targeted by the new conditional branch. Is this the correct way to handle this case?

Is it safe to ignore this case? If this case needs to be handled, how could one identify the destination basic block other than the target of the conditional branch?

Ming Zhang