================
@@ -11177,6 +11177,40 @@ std::pair<SDValue, uint64_t> 
lookThroughSignExtension(SDValue Val) {
   return {Val, Val.getValueSizeInBits() - 1};
 }
 
+// Op is an SDValue that is being compared to 0. If the comparison is a bit
+// test, optimize it to a TBZ or TBNZ.
+static SDValue optimizeBitTest(SDValue Op, SDValue Chain, SDValue Dest,
+                               unsigned Opcode, SelectionDAG &DAG) {
+  SDLoc DL(Op);
+
+  if (Op.getOpcode() != ISD::AND)
+    return SDValue();
+
+  // See if we can use a TBZ to fold in an AND as well.
+  // TBZ has a smaller branch displacement than CBZ.  If the offset is
+  // out of bounds, a late MI-layer pass rewrites branches.
+  // 403.gcc is an example that hits this case.
+  if (isa<ConstantSDNode>(Op.getOperand(1)) &&
+      isPowerOf2_64(Op.getConstantOperandVal(1))) {
+    SDValue Test = Op.getOperand(0);
+    uint64_t Mask = Op.getConstantOperandVal(1);
+    return DAG.getNode(Opcode, DL, MVT::Other, Chain, Test,
+                       DAG.getConstant(Log2_64(Mask), DL, MVT::i64), Dest);
+  }
+
+  if (Op.getOperand(0).getOpcode() == ISD::SHL) {
----------------
pcc wrote:

Yes, the code would stay the same size with the check for a single use of the 
shift. Checking for a single use of the AND could theoretically save one 
instruction, but it seems like an uncommon code pattern; in stage2 clang it 
only changed the code size of about 15 functions and more often than not led to 
increased code size because of something that a later pass did. So I don't 
think it's worth adding any use checks here.

https://github.com/llvm/llvm-project/pull/172962
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to