[llvm] 27e9f0f - [KnownBits] Merge the minimum shift amount and leading/trailing shift value bits handling.

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 13 08:42:05 PST 2020


Author: Simon Pilgrim
Date: 2020-11-13T16:40:20Z
New Revision: 27e9f0f95ef7b144d008bc1cf1459dced6cb5842

URL: https://github.com/llvm/llvm-project/commit/27e9f0f95ef7b144d008bc1cf1459dced6cb5842
DIFF: https://github.com/llvm/llvm-project/commit/27e9f0f95ef7b144d008bc1cf1459dced6cb5842.diff

LOG: [KnownBits] Merge the minimum shift amount and leading/trailing shift value bits handling.

By starting with the source shift value minimum leading/trailing bits, we can then add the minimum known shift amount to more accurately predict the minimum leading/trailing bits of the result.

This is currently only covered by the exhaustive unit tests in KnownBitsTests.cpp, but will help with some of the regressions encountered in D90479 (PR44526).

Added: 
    

Modified: 
    llvm/lib/Support/KnownBits.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp
index e10f97bb7518..7b94e7b95949 100644
--- a/llvm/lib/Support/KnownBits.cpp
+++ b/llvm/lib/Support/KnownBits.cpp
@@ -160,12 +160,16 @@ KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS) {
     return Known;
   }
 
+  // No matter the shift amount, the trailing zeros will stay zero.
+  unsigned MinTrailingZeros = LHS.countMinTrailingZeros();
+
   // Minimum shift amount low bits are known zero.
-  if (RHS.getMinValue().ult(BitWidth))
-    Known.Zero.setLowBits(RHS.getMinValue().getZExtValue());
+  if (RHS.getMinValue().ult(BitWidth)) {
+    MinTrailingZeros += RHS.getMinValue().getZExtValue();
+    MinTrailingZeros = std::min(MinTrailingZeros, BitWidth);
+  }
 
-  // No matter the shift amount, the trailing zeros will stay zero.
-  Known.Zero.setLowBits(LHS.countMinTrailingZeros());
+  Known.Zero.setLowBits(MinTrailingZeros);
   return Known;
 }
 
@@ -183,12 +187,16 @@ KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
     return Known;
   }
 
+  // No matter the shift amount, the leading zeros will stay zero.
+  unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
+
   // Minimum shift amount high bits are known zero.
-  if (RHS.getMinValue().ult(BitWidth))
-    Known.Zero.setHighBits(RHS.getMinValue().getZExtValue());
+  if (RHS.getMinValue().ult(BitWidth)) {
+    MinLeadingZeros += RHS.getMinValue().getZExtValue();
+    MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
+  }
 
-  // No matter the shift amount, the leading zeros will stay zero.
-  Known.Zero.setHighBits(LHS.countMinLeadingZeros());
+  Known.Zero.setHighBits(MinLeadingZeros);
   return Known;
 }
 
@@ -204,8 +212,24 @@ KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS) {
     return Known;
   }
 
-  // TODO: Minimum shift amount high bits are known sign bits.
-  // TODO: No matter the shift amount, the leading sign bits will stay.
+  // No matter the shift amount, the leading sign bits will stay.
+  unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
+  unsigned MinLeadingOnes = LHS.countMinLeadingOnes();
+
+  // Minimum shift amount high bits are known sign bits.
+  if (RHS.getMinValue().ult(BitWidth)) {
+    if (MinLeadingZeros) {
+      MinLeadingZeros += RHS.getMinValue().getZExtValue();
+      MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
+    }
+    if (MinLeadingOnes) {
+      MinLeadingOnes += RHS.getMinValue().getZExtValue();
+      MinLeadingOnes = std::min(MinLeadingOnes, BitWidth);
+    }
+  }
+
+  Known.Zero.setHighBits(MinLeadingZeros);
+  Known.One.setHighBits(MinLeadingOnes);
   return Known;
 }
 


        


More information about the llvm-commits mailing list