The INLINEASM_BR (produced by asm goto) caused the backend to trigger an assertion without this patch, since that opcode was not recognized and properly handled.
This patch should handle all current cases in the backend by recognizing the opcode in getBranchInfo() and properly recording it in SystemZII::Branch. Since INLINEASM_BR is "variadic", and doesn't have any MCOperandInfo in the MCInstrDesc, I thought it best to not add any MachineOperand pointer from it in SystemZInstrInfo::getBranchInfo(). A new type SystemZII::AsmGoto is the SystemZII::BranchType given to it. I guess this could be SystemZII::Other instead, or something, since the AsmGoto type is not actually checked for anywhere.
An alternative would be to just detect the INLINEASM_BR opcode independently of getBranchInfo(), but I think that maybe would be less helpful the next time a branch needs to be analyzed - likely with getBranchInfo().
Places in backend I found that processes branches:
SystemZLongBranch:
I first thought this needed handling as well, but it turns out this is not needed since INLINEASM_BR returns false from both MI.isConditionalBranch() and MI.isUnconditionalBranch() called in SystemZLongBranch::describeTerminator().
Note: Is Large/branch-01.ll broken? I don't see any brcth in the output. Maybe just the comment is wrong? In fact it seems that the test now has Size==65204 which is less than MaxForwardRange so SystemZLongBranch does not actually run on it.
SystemZHazardRecognizer:
Needs no extra handling since branches are just checked for generally with the purpose to update the decoder group state (optimization).
SystemZMachineScheduler:
Needs to check that there is a branch Target operand, which is done by using the new isRelative() and hasMBBTarget() methods of SystemZII::Branch.
SystemZInstrInfo:
analyzeBranch() and removeBranch() needs to use hasMBBTarget().
The test asm-20.ll now runs with postra scheduling enabled (-mcpu=z14) which should make it test both analyzeBranch() and SystemZMachineScheduler().
The name seems weird. If the branch target is a register operand, we have an indirect branch, not a relative branch. (In fact, relative branches are those that have an MBB target operand!)
As I'm not sure there's anything we can ever do to optimize an indirect branch, I'm not sure why we even need this.