[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