mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-01 01:30:36 +00:00
Detect self-referential values.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104957 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
34220aedc4
commit
17d95965cb
@ -93,6 +93,8 @@ namespace {
|
||||
void visitUnreachableInst(UnreachableInst &I);
|
||||
|
||||
Value *findValue(Value *V, bool OffsetOk) const;
|
||||
Value *findValueImpl(Value *V, bool OffsetOk,
|
||||
SmallPtrSet<Value *, 4> &Visited) const;
|
||||
|
||||
public:
|
||||
Module *Mod;
|
||||
@ -498,6 +500,17 @@ void Lint::visitUnreachableInst(UnreachableInst &I) {
|
||||
/// will simplify most of these kinds of things away. But it's a goal of
|
||||
/// this Lint pass to be useful even on non-optimized IR.
|
||||
Value *Lint::findValue(Value *V, bool OffsetOk) const {
|
||||
SmallPtrSet<Value *, 4> Visited;
|
||||
return findValueImpl(V, OffsetOk, Visited);
|
||||
}
|
||||
|
||||
/// findValueImpl - Implementation helper for findValue.
|
||||
Value *Lint::findValueImpl(Value *V, bool OffsetOk,
|
||||
SmallPtrSet<Value *, 4> &Visited) const {
|
||||
// Detect self-referential values.
|
||||
if (!Visited.insert(V))
|
||||
return UndefValue::get(V->getType());
|
||||
|
||||
// TODO: Look through sext or zext cast, when the result is known to
|
||||
// be interpreted as signed or unsigned, respectively.
|
||||
// TODO: Look through calls with unique return values.
|
||||
@ -509,7 +522,7 @@ Value *Lint::findValue(Value *V, bool OffsetOk) const {
|
||||
for (;;) {
|
||||
if (Value *U = FindAvailableLoadedValue(L->getPointerOperand(),
|
||||
BB, BBI, 6, AA))
|
||||
return findValue(U, OffsetOk);
|
||||
return findValueImpl(U, OffsetOk, Visited);
|
||||
BB = L->getParent()->getUniquePredecessor();
|
||||
if (!BB) break;
|
||||
BBI = BB->end();
|
||||
@ -517,27 +530,27 @@ Value *Lint::findValue(Value *V, bool OffsetOk) const {
|
||||
} else if (CastInst *CI = dyn_cast<CastInst>(V)) {
|
||||
if (CI->isNoopCast(TD ? TD->getIntPtrType(V->getContext()) :
|
||||
Type::getInt64Ty(V->getContext())))
|
||||
return findValue(CI->getOperand(0), OffsetOk);
|
||||
return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
|
||||
} else if (PHINode *PN = dyn_cast<PHINode>(V)) {
|
||||
if (Value *W = PN->hasConstantValue(DT))
|
||||
return findValue(W, OffsetOk);
|
||||
return findValueImpl(W, OffsetOk, Visited);
|
||||
} else if (ExtractValueInst *Ex = dyn_cast<ExtractValueInst>(V)) {
|
||||
if (Value *W = FindInsertedValue(Ex->getAggregateOperand(),
|
||||
Ex->idx_begin(),
|
||||
Ex->idx_end()))
|
||||
if (W != V)
|
||||
return findValue(W, OffsetOk);
|
||||
return findValueImpl(W, OffsetOk, Visited);
|
||||
}
|
||||
|
||||
// As a last resort, try SimplifyInstruction or constant folding.
|
||||
if (Instruction *Inst = dyn_cast<Instruction>(V)) {
|
||||
if (Value *W = SimplifyInstruction(Inst, TD))
|
||||
if (W != Inst)
|
||||
return findValue(W, OffsetOk);
|
||||
return findValueImpl(W, OffsetOk, Visited);
|
||||
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
|
||||
if (Value *W = ConstantFoldConstantExpression(CE, TD))
|
||||
if (W != V)
|
||||
return findValue(W, OffsetOk);
|
||||
return findValueImpl(W, OffsetOk, Visited);
|
||||
}
|
||||
|
||||
return V;
|
||||
|
@ -122,3 +122,14 @@ exit:
|
||||
%t7 = inttoptr i64 %t6 to i32*
|
||||
ret i32* %t7
|
||||
}
|
||||
|
||||
; CHECK: Undefined behavior: Undef pointer dereference
|
||||
define i32* @self_reference() {
|
||||
entry:
|
||||
unreachable
|
||||
exit:
|
||||
%t3 = phi i32* [ %t4, %exit ]
|
||||
%t4 = bitcast i32* %t3 to i32*
|
||||
%x = volatile load i32* %t3
|
||||
br label %exit
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user