mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
MemoryBuiltins: Properly guard ObjectSizeOffsetVisitor against cycles in the IR.
The previous fix only checked for simple cycles, use a set to catch longer cycles too. Drop the broken check from the ObjectSizeOffsetEvaluator. The BoundsChecking pass doesn't have to deal with invalid IR like InstCombine does. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162120 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
32811bef95
commit
168843c013
@ -146,6 +146,7 @@ class ObjectSizeOffsetVisitor
|
|||||||
bool RoundToAlign;
|
bool RoundToAlign;
|
||||||
unsigned IntTyBits;
|
unsigned IntTyBits;
|
||||||
APInt Zero;
|
APInt Zero;
|
||||||
|
SmallPtrSet<Instruction *, 8> SeenInsts;
|
||||||
|
|
||||||
APInt align(APInt Size, uint64_t Align);
|
APInt align(APInt Size, uint64_t Align);
|
||||||
|
|
||||||
@ -203,7 +204,6 @@ class ObjectSizeOffsetEvaluator
|
|||||||
const TargetData *TD;
|
const TargetData *TD;
|
||||||
LLVMContext &Context;
|
LLVMContext &Context;
|
||||||
BuilderTy Builder;
|
BuilderTy Builder;
|
||||||
ObjectSizeOffsetVisitor Visitor;
|
|
||||||
IntegerType *IntTy;
|
IntegerType *IntTy;
|
||||||
Value *Zero;
|
Value *Zero;
|
||||||
CacheMapTy CacheMap;
|
CacheMapTy CacheMap;
|
||||||
|
@ -358,11 +358,16 @@ ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const TargetData *TD,
|
|||||||
|
|
||||||
SizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) {
|
SizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) {
|
||||||
V = V->stripPointerCasts();
|
V = V->stripPointerCasts();
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(V)) {
|
||||||
|
// If we have already seen this instruction, bail out. Cycles can happen in
|
||||||
|
// unreachable code after constant propagation.
|
||||||
|
if (!SeenInsts.insert(I))
|
||||||
|
return unknown();
|
||||||
|
|
||||||
if (GEPOperator *GEP = dyn_cast<GEPOperator>(V))
|
if (GEPOperator *GEP = dyn_cast<GEPOperator>(V))
|
||||||
return visitGEPOperator(*GEP);
|
return visitGEPOperator(*GEP);
|
||||||
if (Instruction *I = dyn_cast<Instruction>(V))
|
|
||||||
return visit(*I);
|
return visit(*I);
|
||||||
|
}
|
||||||
if (Argument *A = dyn_cast<Argument>(V))
|
if (Argument *A = dyn_cast<Argument>(V))
|
||||||
return visitArgument(*A);
|
return visitArgument(*A);
|
||||||
if (ConstantPointerNull *P = dyn_cast<ConstantPointerNull>(V))
|
if (ConstantPointerNull *P = dyn_cast<ConstantPointerNull>(V))
|
||||||
@ -371,9 +376,12 @@ SizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) {
|
|||||||
return visitGlobalVariable(*GV);
|
return visitGlobalVariable(*GV);
|
||||||
if (UndefValue *UV = dyn_cast<UndefValue>(V))
|
if (UndefValue *UV = dyn_cast<UndefValue>(V))
|
||||||
return visitUndefValue(*UV);
|
return visitUndefValue(*UV);
|
||||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
|
||||||
if (CE->getOpcode() == Instruction::IntToPtr)
|
if (CE->getOpcode() == Instruction::IntToPtr)
|
||||||
return unknown(); // clueless
|
return unknown(); // clueless
|
||||||
|
if (CE->getOpcode() == Instruction::GetElementPtr)
|
||||||
|
return visitGEPOperator(cast<GEPOperator>(*CE));
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG(dbgs() << "ObjectSizeOffsetVisitor::compute() unhandled value: " << *V
|
DEBUG(dbgs() << "ObjectSizeOffsetVisitor::compute() unhandled value: " << *V
|
||||||
<< '\n');
|
<< '\n');
|
||||||
@ -473,10 +481,6 @@ ObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst&) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SizeOffsetType ObjectSizeOffsetVisitor::visitGEPOperator(GEPOperator &GEP) {
|
SizeOffsetType ObjectSizeOffsetVisitor::visitGEPOperator(GEPOperator &GEP) {
|
||||||
// Ignore self-referencing GEPs, they can occur in unreachable code.
|
|
||||||
if (&GEP == GEP.getPointerOperand())
|
|
||||||
return unknown();
|
|
||||||
|
|
||||||
SizeOffsetType PtrData = compute(GEP.getPointerOperand());
|
SizeOffsetType PtrData = compute(GEP.getPointerOperand());
|
||||||
if (!bothKnown(PtrData) || !GEP.hasAllConstantIndices())
|
if (!bothKnown(PtrData) || !GEP.hasAllConstantIndices())
|
||||||
return unknown();
|
return unknown();
|
||||||
@ -510,10 +514,6 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitPHINode(PHINode&) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SizeOffsetType ObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) {
|
SizeOffsetType ObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) {
|
||||||
// ignore malformed self-looping selects
|
|
||||||
if (I.getTrueValue() == &I || I.getFalseValue() == &I)
|
|
||||||
return unknown();
|
|
||||||
|
|
||||||
SizeOffsetType TrueSide = compute(I.getTrueValue());
|
SizeOffsetType TrueSide = compute(I.getTrueValue());
|
||||||
SizeOffsetType FalseSide = compute(I.getFalseValue());
|
SizeOffsetType FalseSide = compute(I.getFalseValue());
|
||||||
if (bothKnown(TrueSide) && bothKnown(FalseSide) && TrueSide == FalseSide)
|
if (bothKnown(TrueSide) && bothKnown(FalseSide) && TrueSide == FalseSide)
|
||||||
@ -533,8 +533,7 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {
|
|||||||
|
|
||||||
ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(const TargetData *TD,
|
ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(const TargetData *TD,
|
||||||
LLVMContext &Context)
|
LLVMContext &Context)
|
||||||
: TD(TD), Context(Context), Builder(Context, TargetFolder(TD)),
|
: TD(TD), Context(Context), Builder(Context, TargetFolder(TD)) {
|
||||||
Visitor(TD, Context) {
|
|
||||||
IntTy = TD->getIntPtrType(Context);
|
IntTy = TD->getIntPtrType(Context);
|
||||||
Zero = ConstantInt::get(IntTy, 0);
|
Zero = ConstantInt::get(IntTy, 0);
|
||||||
}
|
}
|
||||||
@ -559,6 +558,7 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute(Value *V) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
|
SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
|
||||||
|
ObjectSizeOffsetVisitor Visitor(TD, Context);
|
||||||
SizeOffsetType Const = Visitor.compute(V);
|
SizeOffsetType Const = Visitor.compute(V);
|
||||||
if (Visitor.bothKnown(Const))
|
if (Visitor.bothKnown(Const))
|
||||||
return std::make_pair(ConstantInt::get(Context, Const.first),
|
return std::make_pair(ConstantInt::get(Context, Const.first),
|
||||||
@ -719,10 +719,6 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitSelectInst(SelectInst &I) {
|
SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitSelectInst(SelectInst &I) {
|
||||||
// ignore malformed self-looping selects
|
|
||||||
if (I.getTrueValue() == &I || I.getFalseValue() == &I)
|
|
||||||
return unknown();
|
|
||||||
|
|
||||||
SizeOffsetEvalType TrueSide = compute_(I.getTrueValue());
|
SizeOffsetEvalType TrueSide = compute_(I.getTrueValue());
|
||||||
SizeOffsetEvalType FalseSide = compute_(I.getFalseValue());
|
SizeOffsetEvalType FalseSide = compute_(I.getFalseValue());
|
||||||
|
|
||||||
|
@ -247,7 +247,8 @@ entry:
|
|||||||
|
|
||||||
; technically reachable, but this malformed IR may appear as a result of constant propagation
|
; technically reachable, but this malformed IR may appear as a result of constant propagation
|
||||||
xpto:
|
xpto:
|
||||||
%gep = getelementptr i8* %gep, i32 1
|
%gep2 = getelementptr i8* %gep, i32 1
|
||||||
|
%gep = getelementptr i8* %gep2, i32 1
|
||||||
%o = call i32 @llvm.objectsize.i32(i8* %gep, i1 true)
|
%o = call i32 @llvm.objectsize.i32(i8* %gep, i1 true)
|
||||||
; CHECK: ret i32 undef
|
; CHECK: ret i32 undef
|
||||||
ret i32 %o
|
ret i32 %o
|
||||||
|
Loading…
Reference in New Issue
Block a user