[llvm] r354498 - [X86] Add test case to show missed opportunity to remove an explicit AND on the bit position from BT when it has known zeros.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 20 10:45:38 PST 2019


Author: ctopper
Date: Wed Feb 20 10:45:38 2019
New Revision: 354498

URL: http://llvm.org/viewvc/llvm-project?rev=354498&view=rev
Log:
[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.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/trunk/test/CodeGen/X86/bt.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=354498&r1=354497&r2=354498&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Feb 20 10:45:38 2019
@@ -2102,9 +2102,13 @@ SDValue SelectionDAG::GetDemandedBits(SD
     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: {

Modified: llvm/trunk/test/CodeGen/X86/bt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bt.ll?rev=354498&r1=354497&r2=354498&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/bt.ll (original)
+++ llvm/trunk/test/CodeGen/X86/bt.ll Wed Feb 20 10:45:38 2019
@@ -1144,3 +1144,32 @@ define void @demanded_i32(i32* nocapture
 ; <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
+}




More information about the llvm-commits mailing list