mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-09 12:04:02 +00:00
[MemoryBuiltins] Allow truncation in visitAllocaInst()
Summary: Solves PR33689. If the pointer size is less than the size of the type used for the array size in an alloca (the <ty> type below) then we could trigger the assert in the PR. In that example we have pointer size i16 and <ty> is i32. <result> = alloca [inalloca] <type> [, <ty> <NumElements>] [, align <alignment>] Handle the situation by allowing truncation as well as zero extension in ObjectSizeOffsetVisitor::visitAllocaInst(). Also, we now detect overflow in visitAllocaInst(), similar to how it was already done in visitCallSite(). Reviewers: craig.topper, rnk, george.burgess.iv Reviewed By: george.burgess.iv Subscribers: davide, llvm-commits Differential Revision: https://reviews.llvm.org/D35003 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307754 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4b013660b8
commit
97e16560aa
@ -224,6 +224,9 @@ public:
|
||||
SizeOffsetType visitSelectInst(SelectInst &I);
|
||||
SizeOffsetType visitUndefValue(UndefValue&);
|
||||
SizeOffsetType visitInstruction(Instruction &I);
|
||||
|
||||
private:
|
||||
bool CheckedZextOrTrunc(APInt &I);
|
||||
};
|
||||
|
||||
typedef std::pair<Value*, Value*> SizeOffsetEvalType;
|
||||
|
@ -505,6 +505,22 @@ SizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) {
|
||||
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 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
|
||||
|
||||
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 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) {
|
||||
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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user