When user code intentionally dereferences null, the alignment of the
authorDan Gohman <gohman@apple.com>
Wed, 28 Jul 2010 17:14:23 +0000 (17:14 +0000)
committerDan Gohman <gohman@apple.com>
Wed, 28 Jul 2010 17:14:23 +0000 (17:14 +0000)
dereference is theoretically infinite. Put a cap on the computed
alignment to avoid overflow, noticed by John Regehr.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109596 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineCalls.cpp

index fc62bb0cf8491ce6c0df47b6b9a6163026db8693..0d5e30205a09f71c18467e3c596210b8835bca79 100644 (file)
@@ -96,12 +96,17 @@ static unsigned EnforceKnownAlignment(Value *V,
 /// increase the alignment of the ultimate object, making this check succeed.
 unsigned InstCombiner::GetOrEnforceKnownAlignment(Value *V,
                                                   unsigned PrefAlign) {
-  unsigned BitWidth = TD ? TD->getTypeSizeInBits(V->getType()) :
-                      sizeof(PrefAlign) * CHAR_BIT;
+  assert(V->getType()->isPointerTy() &&
+         "GetOrEnforceKnownAlignment expects a pointer!");
+  unsigned BitWidth = TD ? TD->getPointerSizeInBits() : 64;
   APInt Mask = APInt::getAllOnesValue(BitWidth);
   APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
   ComputeMaskedBits(V, Mask, KnownZero, KnownOne);
   unsigned TrailZ = KnownZero.countTrailingOnes();
+
+  // LLVM doesn't support alignments larger than this currently.
+  TrailZ = std::min(TrailZ, unsigned(sizeof(unsigned) * CHAR_BIT - 1));
+
   unsigned Align = 1u << std::min(BitWidth - 1, TrailZ);
 
   if (PrefAlign > Align)