From 350bc2910b07dec014bf5550053d21c26846052f Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 20 Feb 2019 18:45:38 +0000 Subject: [PATCH] [X86] Add test case to show missed opportunity to remove an explicit AND on the bit position from BT when it has known zeros. If the bit position has known zeros in it, then the AND immediate will likely be optimized to remove bits. This can prevent GetDemandedBits from recognizing that the AND is unnecessary. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354498 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 10 +++++--- test/CodeGen/X86/bt.ll | 29 +++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d7d7b8b7191..de69099d03d 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2102,9 +2102,13 @@ SDValue SelectionDAG::GetDemandedBits(SDValue V, const APInt &Mask) { break; case ISD::AND: { // X & -1 -> X (ignoring bits which aren't demanded). - ConstantSDNode *AndVal = isConstOrConstSplat(V.getOperand(1)); - if (AndVal && Mask.isSubsetOf(AndVal->getAPIntValue())) - return V.getOperand(0); + // Also handle the case where masked out bits in X are known to be zero. + if (ConstantSDNode *RHSC = isConstOrConstSplat(V.getOperand(1))) { + const APInt &AndVal = RHSC->getAPIntValue(); + if (Mask.isSubsetOf(AndVal) || + Mask.isSubsetOf(computeKnownBits(V.getOperand(0)).Zero | AndVal)) + return V.getOperand(0); + } break; } case ISD::ANY_EXTEND: { diff --git a/test/CodeGen/X86/bt.ll b/test/CodeGen/X86/bt.ll index 7f6fbba9e3b..c3aea3d4163 100644 --- a/test/CodeGen/X86/bt.ll +++ b/test/CodeGen/X86/bt.ll @@ -1144,3 +1144,32 @@ define void @demanded_i32(i32* nocapture readonly, i32* nocapture, i32) nounwind ;