[PATCH] D35003: [MemoryBuiltins] Allow truncation in visitAllocaInst()

Mikael Holmén via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 11 23:19:43 PDT 2017


This revision was automatically updated to reflect the committed changes.
Closed by commit rL307754: [MemoryBuiltins] Allow truncation in visitAllocaInst() (authored by uabelho).

Changed prior to commit:
  https://reviews.llvm.org/D35003?vs=105962&id=106142#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D35003

Files:
  llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h
  llvm/trunk/lib/Analysis/MemoryBuiltins.cpp


Index: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp
===================================================================
--- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp
+++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp
@@ -505,6 +505,22 @@
   return unknown();
 }
 
+/// When we're compiling N-bit code, and the user uses parameters that are
+/// greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
+/// trouble with APInt size issues. This function handles resizing + overflow
+/// checks for us. Check and zext or trunc \p I depending on IntTyBits and
+/// I's value.
+bool ObjectSizeOffsetVisitor::CheckedZextOrTrunc(APInt &I) {
+  // More bits than we can handle. Checking the bit width isn't necessary, but
+  // it's faster than checking active bits, and should give `false` in the
+  // vast majority of cases.
+  if (I.getBitWidth() > IntTyBits && I.getActiveBits() > IntTyBits)
+    return false;
+  if (I.getBitWidth() != IntTyBits)
+    I = I.zextOrTrunc(IntTyBits);
+  return true;
+}
+
 SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
   if (!I.getAllocatedType()->isSized())
     return unknown();
@@ -515,8 +531,14 @@
 
   Value *ArraySize = I.getArraySize();
   if (const ConstantInt *C = dyn_cast<ConstantInt>(ArraySize)) {
-    Size *= C->getValue().zextOrSelf(IntTyBits);
-    return std::make_pair(align(Size, I.getAlignment()), Zero);
+    APInt NumElems = C->getValue();
+    if (!CheckedZextOrTrunc(NumElems))
+      return unknown();
+
+    bool Overflow;
+    Size = Size.umul_ov(NumElems, Overflow);
+    return Overflow ? unknown() : std::make_pair(align(Size, I.getAlignment()),
+                                                 Zero);
   }
   return unknown();
 }
@@ -561,21 +583,6 @@
   if (!Arg)
     return unknown();
 
-  // When we're compiling N-bit code, and the user uses parameters that are
-  // greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
-  // trouble with APInt size issues. This function handles resizing + overflow
-  // checks for us.
-  auto CheckedZextOrTrunc = [&](APInt &I) {
-    // More bits than we can handle. Checking the bit width isn't necessary, but
-    // it's faster than checking active bits, and should give `false` in the
-    // vast majority of cases.
-    if (I.getBitWidth() > IntTyBits && I.getActiveBits() > IntTyBits)
-      return false;
-    if (I.getBitWidth() != IntTyBits)
-      I = I.zextOrTrunc(IntTyBits);
-    return true;
-  };
-
   APInt Size = Arg->getValue();
   if (!CheckedZextOrTrunc(Size))
     return unknown();
Index: llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h
===================================================================
--- llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h
+++ llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h
@@ -224,6 +224,9 @@
   SizeOffsetType visitSelectInst(SelectInst &I);
   SizeOffsetType visitUndefValue(UndefValue&);
   SizeOffsetType visitInstruction(Instruction &I);
+
+private:
+  bool CheckedZextOrTrunc(APInt &I);
 };
 
 typedef std::pair<Value*, Value*> SizeOffsetEvalType;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D35003.106142.patch
Type: text/x-patch
Size: 3079 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170712/1c61ad7e/attachment.bin>


More information about the llvm-commits mailing list