[PATCH] D31348: [ValueTracking] Compute known bits for add/sub with less temporary APInts

Craig Topper via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 24 12:10:47 PDT 2017


craig.topper created this revision.

The previous operation used quite a few temporary objects which can allocate memory for larger than 64-bit types and made no use of the storage already allocated storage for KnownZeroes/Ones.

This patch tries to make more intelligent reuse of the objects. Computing the overall known bits is still kind of bad as the OR operation for LHS and RHS both create a temporary to hold the OR result.


https://reviews.llvm.org/D31348

Files:
  lib/Analysis/ValueTracking.cpp


Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -263,25 +263,39 @@
     CarryIn = 1;
   }
 
-  APInt PossibleSumZero = ~LHSKnownZero + ~RHSKnownZero + CarryIn;
-  APInt PossibleSumOne = LHSKnownOne + RHSKnownOne + CarryIn;
+  // Flip the known zeroes so we can add them.
+  LHSKnownZero.flipAllBits();
+  RHSKnownZero.flipAllBits();
+
+  // Create a sum for the known zeros.
+  KnownZero |= CarryIn;
+  KnownZero += LHSKnownZero;
+  KnownZero += RHSKnownZero;
+
+  // Restore the known zeroes and flip the sum.
+  LHSKnownZero.flipAllBits();
+  RHSKnownZero.flipAllBits();
+  KnownZero.flipAllBits();
+
+  // Create a sum for the known ones.
+  KnownOne |= CarryIn;
+  KnownOne += RHSKnownOne;
+  KnownOne += LHSKnownOne;
 
   // Compute known bits of the carry.
-  APInt CarryKnownZero = ~(PossibleSumZero ^ LHSKnownZero ^ RHSKnownZero);
-  APInt CarryKnownOne = PossibleSumOne ^ LHSKnownOne ^ RHSKnownOne;
+  APInt CarryKnownZero = KnownZero ^ LHSKnownZero ^ RHSKnownZero;
+  APInt CarryKnownOne = KnownOne ^ LHSKnownOne ^ RHSKnownOne;
 
   // Compute set of known bits (where all three relevant bits are known).
-  APInt LHSKnown = LHSKnownZero | LHSKnownOne;
-  APInt RHSKnown = RHSKnownZero | RHSKnownOne;
-  APInt CarryKnown = CarryKnownZero | CarryKnownOne;
-  APInt Known = LHSKnown & RHSKnown & CarryKnown;
-
-  assert((PossibleSumZero & Known) == (PossibleSumOne & Known) &&
+  APInt Known = std::move(CarryKnownZero) | std::move(CarryKnownOne);
+  Known &= LHSKnownZero | LHSKnownOne;
+  Known &= RHSKnownZero | RHSKnownOne;
+  assert((~KnownZero & Known) == (KnownOne & Known) &&
          "known bits of sum differ");
 
-  // Compute known bits of the result.
-  KnownZero = ~PossibleSumOne & Known;
-  KnownOne = PossibleSumOne & Known;
+  // Bits of sums are only known if all input bits were known.
+  KnownZero &= Known;
+  KnownOne &= Known;
 
   // Are we still trying to solve for the sign bit?
   if (!Known.isNegative()) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D31348.92989.patch
Type: text/x-patch
Size: 2076 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170324/75e381aa/attachment.bin>


More information about the llvm-commits mailing list