We have a chance for an optimization. Consider this code:
authorBill Wendling <isanbard@gmail.com>
Tue, 31 Aug 2010 22:41:22 +0000 (22:41 +0000)
committerBill Wendling <isanbard@gmail.com>
Tue, 31 Aug 2010 22:41:22 +0000 (22:41 +0000)
commit43a6c5e2fccadb299c35cb3147d112f706922acd
tree9aa70d04e8235ebdbbe4fba3c0c6cf6006832918
parent1d76ab7f56398c1ccc000e66a78402c928a3eb6b
We have a chance for an optimization. Consider this code:

int x(int t) {
  if (t & 256)
    return -26;
  return 0;
}

We generate this:

     tst.w   r0, #256
     mvn     r0, #25
     it      eq
     moveq   r0, #0

while gcc generates this:

     ands    r0, r0, #256
     it      ne
     mvnne   r0, #25
     bx      lr

Scandalous really!

During ISel time, we can look for this particular pattern. One where we have a
"MOVCC" that uses the flag off of a CMPZ that itself is comparing an AND
instruction to 0. Something like this (greatly simplified):

  %r0 = ISD::AND ...
  ARMISD::CMPZ %r0, 0         @ sets [CPSR]
  %r0 = ARMISD::MOVCC 0, -26  @ reads [CPSR]

All we have to do is convert the "ISD::AND" into an "ARM::ANDS" that sets [CPSR]
when it's zero. The zero value will all ready be in the %r0 register and we only
need to change it if the AND wasn't zero. Easy!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112664 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Target/ARM/ARMISelDAGToDAG.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb2.td
test/CodeGen/ARM/mvncc.ll [new file with mode: 0644]
test/CodeGen/Thumb2/thumb2-mvncc.ll [new file with mode: 0644]