[PATCH] [X86] Combine (cmov (and/or (setcc) (setcc))) into (cmov (cmov))

Ahmed Bougacha ahmed.bougacha at gmail.com
Fri Feb 13 16:23:46 PST 2015


Fold and/or of setcc's to double CMOV:
  (CMOV F, T, ((cc1 | cc2) != 0)) -> (CMOV (CMOV F, T, cc1), T, cc2)
  (CMOV F, T, ((cc1 & cc2) != 0)) -> (CMOV (CMOV T, F, !cc1), F, !cc2)

In practice, when we need to lower to control flow using a custom inserter,
we represent the double CMOV using a special node, CMOV2:
  (CMOV F, T, ((cc1 | cc2) != 0)) -> (CMOV2 F, T, cc1, cc2)
  (CMOV F, T, ((cc1 & cc2) != 0)) -> (CMOV2 T, F, !cc1, !cc2)
This enables the custom inserter to only need to insert one PHI, instead
of two if it looked at two independent CMOVs.

This combine lets us generate:
  cmovcc1 (jcc1 if we don't have CMOV)
  cmovcc2 (same)
instead of:
  setcc1
  setcc2
  and/or
  cmovne (jne if we don't have CMOV)

When we can't use the CMOV instruction, it might increase branch mispredicts.
When we can, or when there is no mispredict, this improves throughput and reduces register pressure.

---

This is pretty much the same thing as D7622, except here the pattern is exposed during ops legalization.  By the time we get to the combiner, we already have X86ISD nodes, so even an independent combine wouldn't have been useful.

The CMOV2 pseudo is yucky, but I can't see an alternative.  If you do it the obvious way (just form two CMOVs all the time) the custom inserter (which definitely should not look at other instructions) adds a PHI between the two jumps, which ends up creating a few copies all around.  For instance, for the (sitofp (zext (fcmp une))) testcase:

        ucomiss %xmm1, %xmm0
        movss  <1.0f>, %xmm0
        movaps  %xmm0, %xmm1
        jne     .LBB5_2
        xorps   %xmm1, %xmm1
.LBB5_2:
        jp      .LBB5_4
        movaps  %xmm1, %xmm0
.LBB5_4:
        retq

http://reviews.llvm.org/D7634

Files:
  lib/Target/X86/X86ISelLowering.cpp
  lib/Target/X86/X86ISelLowering.h
  lib/Target/X86/X86InstrCompiler.td
  lib/Target/X86/X86InstrInfo.td
  test/CodeGen/X86/cmovcmov.ll
  test/CodeGen/X86/fast-isel-select-cmov2.ll

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D7634.19947.patch
Type: text/x-patch
Size: 27172 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150214/1a5bee25/attachment.bin>


More information about the llvm-commits mailing list