]> granicus.if.org Git - llvm/commitdiff
[X86] Add test case to show missed opportunity to remove an explicit AND on the bit...
authorCraig Topper <craig.topper@intel.com>
Wed, 20 Feb 2019 18:45:38 +0000 (18:45 +0000)
committerCraig Topper <craig.topper@intel.com>
Wed, 20 Feb 2019 18:45:38 +0000 (18:45 +0000)
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
test/CodeGen/X86/bt.ll

index d7d7b8b7191578c54da9d38f7899a3178a1fed17..de69099d03d7c049ef329133ae43062c6440ba0c 100644 (file)
@@ -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: {
index 7f6fbba9e3bbaf506764892fe4b8c89b1cebdc0e..c3aea3d41634e1b7111be66732d5fca4404957bc 100644 (file)
@@ -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
+}