summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2019-02-20 18:45:38 +0000
committerCraig Topper <craig.topper@intel.com>2019-02-20 18:45:38 +0000
commitf8498a615b8f0b728fcbc227acba3c38e1024e64 (patch)
tree8c8585b36b8b59d5cc615f70c952af184321d558 /llvm
parent13f45590e349ec7378bf3c4b6f95b710277c6b00 (diff)
downloadbcm5719-llvm-f8498a615b8f0b728fcbc227acba3c38e1024e64.tar.gz
bcm5719-llvm-f8498a615b8f0b728fcbc227acba3c38e1024e64.zip
[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. llvm-svn: 354498
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp10
-rw-r--r--llvm/test/CodeGen/X86/bt.ll29
2 files changed, 36 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index d7d7b8b7191..de69099d03d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/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/llvm/test/CodeGen/X86/bt.ll b/llvm/test/CodeGen/X86/bt.ll
index 7f6fbba9e3b..c3aea3d4163 100644
--- a/llvm/test/CodeGen/X86/bt.ll
+++ b/llvm/test/CodeGen/X86/bt.ll
@@ -1144,3 +1144,32 @@ define void @demanded_i32(i32* nocapture readonly, i32* nocapture, i32) nounwind
; <label>:16:
ret void
}
+
+; Make sure we can simplify bt when the shift amount has known zeros in it
+; which cause the and mask to have bits removed.
+define zeroext i1 @demanded_with_known_zeroes(i32 %bit, i32 %bits) {
+; X86-LABEL: demanded_with_known_zeroes:
+; X86: # %bb.0: # %entry
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
+; X86-NEXT: shlb $2, %cl
+; X86-NEXT: movzbl %cl, %ecx
+; X86-NEXT: btl %ecx, %eax
+; X86-NEXT: setb %al
+; X86-NEXT: retl
+;
+; X64-LABEL: demanded_with_known_zeroes:
+; X64: # %bb.0: # %entry
+; X64-NEXT: shlb $2, %dil
+; X64-NEXT: movzbl %dil, %eax
+; X64-NEXT: btl %eax, %esi
+; X64-NEXT: setb %al
+; X64-NEXT: retq
+entry:
+ %bit2 = shl i32 %bit, 2
+ %and = and i32 %bit2, 31
+ %shl = shl i32 1, %and
+ %and1 = and i32 %shl, %bits
+ %tobool = icmp ne i32 %and1, 0
+ ret i1 %tobool
+}
OpenPOWER on IntegriCloud