BR_CC questions

I am implementing a new backend and am pretty sure I don't quite understand "the way" one is supposed to implement conditional branches.

My target CPU natively supports a conditional branch instruction that accepts a condition to test (equal, less than, etc.), two operands (two registers, or one register and one immediate), and finally a target PC to branch to if the comparison succeeds.

Great -- that all seems to mesh directly with the ISD::BR_CC opcode.

However... I can't seem to use 'brcc' or 'br_cc' in the .td file. Neither is recognized as a valid keyword. I can use 'brcond', but given the capabilities of the CPU I'm targeting, it seems better to implement BR_CC directly and do setOperationAction(ISD::BRCOND, MVT::Other, Expand) to get BRCOND nodes expanded into BR_CC. Correct?

I tried implementing comparison operations and 'brcond' in the .td file, but that yields assembly code that does a comparison instruction followed by a branch instruction, when the underlying CPU supports folding the comparison into the branch.

Is it in fact possible to use BR_CC directly in the TD file? If so, how? In particular, what pattern would I use? If not, what is the recommended way to proceed (at a high level) when the target CPU supports conditional branches as I outlined above?

Thanks for any help!

I am implementing a new backend and am pretty sure I don't quite understand "the way" one is supposed to implement conditional branches.

My target CPU natively supports a conditional branch instruction that accepts a condition to test (equal, less than, etc.), two operands (two registers, or one register and one immediate), and finally a target PC to branch to if the comparison succeeds.

Great -- that all seems to mesh directly with the ISD::BR_CC opcode.

However... I can't seem to use 'brcc' or 'br_cc' in the .td file. Neither is recognized as a valid keyword. I can use 'brcond', but given the capabilities of the CPU I'm targeting, it seems better to implement BR_CC directly and do setOperationAction(ISD::BRCOND, MVT::Other, Expand) to get BRCOND nodes expanded into BR_CC. Correct?

I tried implementing comparison operations and 'brcond' in the .td file, but that yields assembly code that does a comparison instruction followed by a branch instruction, when the underlying CPU supports folding the comparison into the branch.

Is it in fact possible to use BR_CC directly in the TD file? If so, how? In particular, what pattern would I use? If not, what is the recommended way to proceed (at a high level) when the target CPU supports conditional branches as I outlined above?

There is no def in tablegen for br_cc. I'm not sure why. If you look in
include/llvm/Target/TargetSelectionDAG.td, you will see all the SDNodes
that can be used in TableGen.

You have a few options for handling BR_CC. You could custom select it
to a target node during legalization. It looks like there are a few
targets that do this. Or you could manually select it to a MachineSDNode
in TargetDAGToDAGISel::Select(). You could also define a br_cc node in
TableGen and write a pattern for it.

-Tom

Awesome, I ran into the same thing exactly.

And I have a patch for it. I wasn’t sure that there were interest, but apparently, I’m not the only one.

0001-Make-br_cc-matchable-in-td-files.patch (1.3 KB)