[ARM] Compute known bits for ARMISD::CMOV
authorJames Molloy <james.molloy@arm.com>
Thu, 5 Nov 2015 15:21:58 +0000 (15:21 +0000)
committerJames Molloy <james.molloy@arm.com>
Thu, 5 Nov 2015 15:21:58 +0000 (15:21 +0000)
We can conservatively know that CMOV's known bits are the intersection of known bits for each of its operands. This helps PerformCMOVToBFICombine find more opportunities.

I tried hard to create a testcase for this and failed - we have to sufficiently confuse DAG.computeKnownBits which can see through all the cheap tricks I tried to narrow my larger testcase down :(

This code is actually exercised in CodeGen/ARM/bfi.ll, there's just no functional difference because DAG.computeKnownBits gets the right answer in that case.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252168 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelLowering.cpp

index 221cb1ac36195c9f58ae7806989e71accbb50e8d..992902d6f6eb18b07c0f95cb2dded8794515934a 100644 (file)
@@ -10243,6 +10243,16 @@ static void computeKnownBits(SelectionDAG &DAG, SDValue Op, APInt &KnownZero,
     KnownOne &= Mask;
     return;
   }
+  if (Op.getOpcode() == ARMISD::CMOV) {
+    APInt KZ2(KnownZero.getBitWidth(), 0);
+    APInt KO2(KnownOne.getBitWidth(), 0);
+    computeKnownBits(DAG, Op.getOperand(1), KnownZero, KnownOne);
+    computeKnownBits(DAG, Op.getOperand(2), KZ2, KO2);
+
+    KnownZero &= KZ2;
+    KnownOne &= KO2;
+    return;
+  }
   return DAG.computeKnownBits(Op, KnownZero, KnownOne);
 }