[llvm] r298711 - [InstCombine] Provide a way to calculate KnownZero/One for Add/Sub in SimplifyDemandedUseBits without recursing into ComputeKnownBits

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 24 09:56:51 PDT 2017


Author: ctopper
Date: Fri Mar 24 11:56:51 2017
New Revision: 298711

URL: http://llvm.org/viewvc/llvm-project?rev=298711&view=rev
Log:
[InstCombine] Provide a way to calculate KnownZero/One for Add/Sub in SimplifyDemandedUseBits without recursing into ComputeKnownBits

SimplifyDemandedUseBits for Add/Sub already recursed down LHS and RHS for simplifying bits. If that didn't provide any simplifications we fall back to calling computeKnownBits which will recurse again. Instead just take the known bits for LHS and RHS we already have and call into a new function in ValueTracking that can calculate the known bits given the LHS/RHS bits.




Modified:
    llvm/trunk/include/llvm/Analysis/ValueTracking.h
    llvm/trunk/lib/Analysis/ValueTracking.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ValueTracking.h?rev=298711&r1=298710&r2=298711&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/ValueTracking.h (original)
+++ llvm/trunk/include/llvm/Analysis/ValueTracking.h Fri Mar 24 11:56:51 2017
@@ -55,6 +55,11 @@ template <typename T> class ArrayRef;
                         const Instruction *CxtI = nullptr,
                         const DominatorTree *DT = nullptr,
                         OptimizationRemarkEmitter *ORE = nullptr);
+  /// Compute known bits for add/sub using LHS/RHS known bits.
+  void computeKnownBitsForAddSub(bool Add, bool NSW,
+                                 APInt &KnownZero, APInt &KnownOne,
+                                 APInt &LHSKnownZero, APInt &LHSKnownOne,
+                                 APInt &RHSKnownZero, APInt &RHSKnownOne);
   /// Compute known bits from the range metadata.
   /// \p KnownZero the set of bits that are known to be zero
   /// \p KnownOne the set of bits that are known to be one

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=298711&r1=298710&r2=298711&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Fri Mar 24 11:56:51 2017
@@ -250,37 +250,29 @@ unsigned llvm::ComputeNumSignBits(const
   return ::ComputeNumSignBits(V, Depth, Query(DL, AC, safeCxtI(V, CxtI), DT));
 }
 
-static void computeKnownBitsAddSub(bool Add, const Value *Op0, const Value *Op1,
-                                   bool NSW,
-                                   APInt &KnownZero, APInt &KnownOne,
-                                   APInt &KnownZero2, APInt &KnownOne2,
-                                   unsigned Depth, const Query &Q) {
-  unsigned BitWidth = KnownZero.getBitWidth();
-
-  // If an initial sequence of bits in the result is not needed, the
-  // corresponding bits in the operands are not needed.
-  APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
-  computeKnownBits(Op0, LHSKnownZero, LHSKnownOne, Depth + 1, Q);
-  computeKnownBits(Op1, KnownZero2, KnownOne2, Depth + 1, Q);
-
+/// Compute known bits for add/sub using LHS/RHS known bits.
+void llvm::computeKnownBitsForAddSub(bool Add, bool NSW,
+                                     APInt &KnownZero, APInt &KnownOne,
+                                     APInt &LHSKnownZero, APInt &LHSKnownOne,
+                                     APInt &RHSKnownZero, APInt &RHSKnownOne) {
   // Carry in a 1 for a subtract, rather than a 0.
   uint64_t CarryIn = 0;
   if (!Add) {
     // Sum = LHS + ~RHS + 1
-    std::swap(KnownZero2, KnownOne2);
+    std::swap(RHSKnownZero, RHSKnownOne);
     CarryIn = 1;
   }
 
-  APInt PossibleSumZero = ~LHSKnownZero + ~KnownZero2 + CarryIn;
-  APInt PossibleSumOne = LHSKnownOne + KnownOne2 + CarryIn;
+  APInt PossibleSumZero = ~LHSKnownZero + ~RHSKnownZero + CarryIn;
+  APInt PossibleSumOne = LHSKnownOne + RHSKnownOne + CarryIn;
 
   // Compute known bits of the carry.
-  APInt CarryKnownZero = ~(PossibleSumZero ^ LHSKnownZero ^ KnownZero2);
-  APInt CarryKnownOne = PossibleSumOne ^ LHSKnownOne ^ KnownOne2;
+  APInt CarryKnownZero = ~(PossibleSumZero ^ LHSKnownZero ^ RHSKnownZero);
+  APInt CarryKnownOne = PossibleSumOne ^ LHSKnownOne ^ RHSKnownOne;
 
   // Compute set of known bits (where all three relevant bits are known).
   APInt LHSKnown = LHSKnownZero | LHSKnownOne;
-  APInt RHSKnown = KnownZero2 | KnownOne2;
+  APInt RHSKnown = RHSKnownZero | RHSKnownOne;
   APInt CarryKnown = CarryKnownZero | CarryKnownOne;
   APInt Known = LHSKnown & RHSKnown & CarryKnown;
 
@@ -296,14 +288,36 @@ static void computeKnownBitsAddSub(bool
     if (NSW) {
       // Adding two non-negative numbers, or subtracting a negative number from
       // a non-negative one, can't wrap into negative.
-      if (LHSKnownZero.isNegative() && KnownZero2.isNegative())
+      if (LHSKnownZero.isNegative() && RHSKnownZero.isNegative())
         KnownZero.setSignBit();
       // Adding two negative numbers, or subtracting a non-negative number from
       // a negative one, can't wrap into non-negative.
-      else if (LHSKnownOne.isNegative() && KnownOne2.isNegative())
+      else if (LHSKnownOne.isNegative() && RHSKnownOne.isNegative())
         KnownOne.setSignBit();
     }
   }
+
+  // Put the RHS/LHS back how we found them.
+  if (!Add) {
+    std::swap(RHSKnownZero, RHSKnownOne);
+  }
+}
+
+static void computeKnownBitsAddSub(bool Add, const Value *Op0, const Value *Op1,
+                                   bool NSW,
+                                   APInt &KnownZero, APInt &KnownOne,
+                                   APInt &KnownZero2, APInt &KnownOne2,
+                                   unsigned Depth, const Query &Q) {
+  unsigned BitWidth = KnownZero.getBitWidth();
+
+  // If an initial sequence of bits in the result is not needed, the
+  // corresponding bits in the operands are not needed.
+  APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
+  computeKnownBits(Op0, LHSKnownZero, LHSKnownOne, Depth + 1, Q);
+  computeKnownBits(Op1, KnownZero2, KnownOne2, Depth + 1, Q);
+
+  computeKnownBitsForAddSub(Add, NSW, KnownZero, KnownOne, LHSKnownZero,
+                            LHSKnownOne, KnownZero2, KnownOne2);
 }
 
 static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW,

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp?rev=298711&r1=298710&r2=298711&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp Fri Mar 24 11:56:51 2017
@@ -538,7 +538,7 @@ Value *InstCombiner::SimplifyDemandedUse
                                LHSKnownZero, LHSKnownOne, Depth + 1) ||
           ShrinkDemandedConstant(I, 1, DemandedFromOps) ||
           SimplifyDemandedBits(I->getOperandUse(1), DemandedFromOps,
-                               LHSKnownZero, LHSKnownOne, Depth + 1)) {
+                               RHSKnownZero, RHSKnownOne, Depth + 1)) {
         // Disable the nsw and nuw flags here: We can no longer guarantee that
         // we won't wrap after simplification. Removing the nsw/nuw flags is
         // legal here because the top bit is not demanded.
@@ -549,9 +549,10 @@ Value *InstCombiner::SimplifyDemandedUse
       }
     }
 
-    // Otherwise just hand the add/sub off to computeKnownBits to fill in
-    // the known zeros and ones.
-    computeKnownBits(V, KnownZero, KnownOne, Depth, CxtI);
+    // Otherwise compute the known bits using the RHS/LHS known bits.
+    bool NSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
+    computeKnownBitsForAddSub(V, NSW, KnownZero, KnownOne, LHSKnownZero,
+                              LHSKnownOne, RHSKnownZero, RHSKnownOne);
     break;
   }
   case Instruction::Shl:




More information about the llvm-commits mailing list