[llvm] r300094 - [InstCombine] Teach SimplifyMultipleUseDemandedBits to handle And/Or/Xor known bits using the LHS/RHS known bits it already acquired without recursing back into computeKnownBits.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 12 12:32:48 PDT 2017


Author: ctopper
Date: Wed Apr 12 14:32:47 2017
New Revision: 300094

URL: http://llvm.org/viewvc/llvm-project?rev=300094&view=rev
Log:
[InstCombine] Teach SimplifyMultipleUseDemandedBits to handle And/Or/Xor known bits using the LHS/RHS known bits it already acquired without recursing back into computeKnownBits.

This replicates the known bits and constant creation code from the single use case for these instructions and adds it here. The computeKnownBits and constant creation code for other instructions is now in the default case of the opcode switch.



Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp?rev=300094&r1=300093&r2=300094&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp Wed Apr 12 14:32:47 2017
@@ -770,6 +770,12 @@ Value *InstCombiner::SimplifyMultipleUse
     computeKnownBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth + 1,
                      CxtI);
 
+    // If the client is only demanding bits that we know, return the known
+    // constant.
+    if ((DemandedMask & ((RHSKnownZero | LHSKnownZero)|
+                         (RHSKnownOne & LHSKnownOne))) == DemandedMask)
+      return Constant::getIntegerValue(ITy, RHSKnownOne & LHSKnownOne);
+
     // If all of the demanded bits are known 1 on one side, return the other.
     // These bits cannot contribute to the result of the 'and' in this
     // context.
@@ -780,10 +786,10 @@ Value *InstCombiner::SimplifyMultipleUse
         (DemandedMask & ~RHSKnownZero))
       return I->getOperand(1);
 
-    // If all of the demanded bits in the inputs are known zeros, return zero.
-    if ((DemandedMask & (RHSKnownZero|LHSKnownZero)) == DemandedMask)
-      return Constant::getNullValue(ITy);
-
+    // Output known-1 bits are only known if set in both the LHS & RHS.
+    KnownOne = RHSKnownOne & LHSKnownOne;
+    // Output known-0 are known to be clear if zero in either the LHS | RHS.
+    KnownZero = RHSKnownZero | LHSKnownZero;
     break;
 
   case Instruction::Or:
@@ -796,6 +802,12 @@ Value *InstCombiner::SimplifyMultipleUse
     computeKnownBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth + 1,
                      CxtI);
 
+    // If the client is only demanding bits that we know, return the known
+    // constant.
+    if ((DemandedMask & ((RHSKnownZero & LHSKnownZero)|
+                         (RHSKnownOne | LHSKnownOne))) == DemandedMask)
+      return Constant::getIntegerValue(ITy, RHSKnownOne | LHSKnownOne);
+
     // If all of the demanded bits are known zero on one side, return the
     // other.  These bits cannot contribute to the result of the 'or' in this
     // context.
@@ -815,9 +827,13 @@ Value *InstCombiner::SimplifyMultipleUse
         (DemandedMask & (~LHSKnownZero)))
       return I->getOperand(1);
 
+    // Output known-0 bits are only known if clear in both the LHS & RHS.
+    KnownZero = RHSKnownZero & LHSKnownZero;
+    // Output known-1 are known to be set if set in either the LHS | RHS.
+    KnownOne = RHSKnownOne | LHSKnownOne;
     break;
 
-  case Instruction::Xor:
+  case Instruction::Xor: {
     // We can simplify (X^Y) -> X or Y in the user's context if we know that
     // only bits from X or Y are demanded.
 
@@ -826,6 +842,18 @@ Value *InstCombiner::SimplifyMultipleUse
     computeKnownBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth + 1,
                      CxtI);
 
+    // Output known-0 bits are known if clear or set in both the LHS & RHS.
+    APInt IKnownZero = (RHSKnownZero & LHSKnownZero) |
+                       (RHSKnownOne & LHSKnownOne);
+    // Output known-1 are known to be set if set in only one of the LHS, RHS.
+    APInt IKnownOne =  (RHSKnownZero & LHSKnownOne) |
+                       (RHSKnownOne & LHSKnownZero);
+
+    // If the client is only demanding bits that we know, return the known
+    // constant.
+    if ((DemandedMask & (IKnownZero|IKnownOne)) == DemandedMask)
+      return Constant::getIntegerValue(ITy, IKnownOne);
+
     // If all of the demanded bits are known zero on one side, return the
     // other.
     if ((DemandedMask & RHSKnownZero) == DemandedMask)
@@ -833,16 +861,23 @@ Value *InstCombiner::SimplifyMultipleUse
     if ((DemandedMask & LHSKnownZero) == DemandedMask)
       return I->getOperand(1);
 
+    // Output known-0 bits are known if clear or set in both the LHS & RHS.
+    KnownZero = std::move(IKnownZero);
+    // Output known-1 are known to be set if set in only one of the LHS, RHS.
+    KnownOne  = std::move(IKnownOne);
     break;
   }
+  default:
+    // Compute the KnownZero/KnownOne bits to simplify things downstream.
+    computeKnownBits(I, KnownZero, KnownOne, Depth, CxtI);
+
+    // If this user is only demanding bits that we know, return the known
+    // constant.
+    if ((DemandedMask & (KnownZero|KnownOne)) == DemandedMask)
+      return Constant::getIntegerValue(ITy, KnownOne);
 
-  // Compute the KnownZero/KnownOne bits to simplify things downstream.
-  computeKnownBits(I, KnownZero, KnownOne, Depth, CxtI);
-
-  // If this user is only demanding bits that we know, return the known
-  // constant.
-  if ((DemandedMask & (KnownZero|KnownOne)) == DemandedMask)
-    return Constant::getIntegerValue(ITy, KnownOne);
+    break;
+  }
 
   return nullptr;
 }




More information about the llvm-commits mailing list