[llvm-dev] Optimizing Compare instruction selection

Eli Friedman via llvm-dev llvm-dev at lists.llvm.org
Sat Jun 1 18:23:03 PDT 2019

There are basically two possible approaches here.

One approach is to just wait until after isel to handle this: check for an addition instruction immediately followed by an cmp; then erase the cmp. See, for example, ARMBaseInstrInfo::optimizeCompareInstr.

Another, you make a dedicated target-specific ISel node that produces two results: essentially, one is the result of the arithmetic, and the other is the status register.  See, for example, X86TargetLowering::LowerBRCOND.

I don't think you'd want to try to do anything in Select(); I mean, you could try to pattern-match (cmp x, (add x, y)) or whatever, but you'd probably run into trouble if the add has multiple uses.


From: llvm-dev <llvm-dev-bounces at lists.llvm.org> on behalf of Joan Lluch via llvm-dev <llvm-dev at lists.llvm.org>
Sent: Saturday, June 1, 2019 10:09 AM
To: llvm-dev
Subject: [EXT] [llvm-dev] Optimizing Compare instruction selection

I attempt to optimize the use of the 'CMP' instruction on my architecture by removing the instruction instances where the Status Register already had the correct status flags.

The cmp instruction in my architecture is the typical one that compares two registers, or a register with an immediate, and sets the Status Flags accordingly. I implemented my 'cmp'  instruction in LLVM by custom lowering the SETCC, SELECT_CC and BR_CC in the usual way, mostly following the ARM implementation. In particular the target cmp instruction is created and glued to a target conditional instruction, such as a conditional branch, or a conditional select.

The generated code may look like this:

add R0, R1, R2
cmp R0, #0
breq Label

This works fine, but now I would want to go one step further:

As part of the SETCC and SELECT_CC lowering, I can determine if the conditions are met in my architecture to avoid generating a 'cmp' instruction at all. For example, if the left operand of the SETCC is an 'addition', the right operand is constant zero, and the condition is 'ISD::CondCode::SETEQ, I can safely assume that the Status Register in my architecture already has the right condition just before the 'cmp', which has been set by the target 'add' instruction. So at this point I want to avoid generating the 'cmp' because it is redundant.

My goal is to replace the assembly code shown above, by just this:

add R0, R1, R2
breq Label

The 'cmp' was redundant in this case because the add instruction already set the Z (zero) flag

I tried several things, but I got stuck in some way in all of them. For example, an approach that I tried is to have a 'dummy_cmp' instruction, that I generate instead of the regular 'cmp' when the comparison is redundant. The 'dummy_cmp' must be removed at a latter stage, ideally during the selDAGToDAG phase, but I failed to do so.

- So my first question is. How do I remove the 'dummy_cmp' node in the MyTargetISelDAGtoDAG::Select() function?

Another approach that I tried, which I regard as preferable, is to directly avoid the creation of a 'cmp' instruction during ISelLowering. Instead of 'cmp', use the LHS operand of the SETCC operand if it mets the conditions described above. The problem that I found with this approach is that the 'cmp' is just a 'glue' to the target branch or select instruction, however, the LHS is an actual operand (for example an 'add' node), so I need to create a 'glue' for it, in order to be attached to the target branch instruction.

- My second question is therefore, how do I create a 'glue' for an existing 'add' node that I can attach to the target conditional instruction as a replacement of the 'cmp' instruction?

Joan Lluch
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190602/3bcae89e/attachment.html>

More information about the llvm-dev mailing list