Fix PR 2160 by making sure arguments to external functions get marked as pointing to anything
llvm-svn: 48509
This commit is contained in:
parent
b0c409a235
commit
5fef9aea12
|
|
@ -647,9 +647,13 @@ Andersens::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
|
||||||
|
|
||||||
if (N1->PointsTo->empty())
|
if (N1->PointsTo->empty())
|
||||||
return NoModRef;
|
return NoModRef;
|
||||||
|
#if FULL_UNIVERSAL
|
||||||
|
if (!UniversalSet->PointsTo->test(FindNode(getNode(P))))
|
||||||
|
return NoModRef; // Universal set does not contain P
|
||||||
|
#else
|
||||||
if (!N1->PointsTo->test(UniversalSet))
|
if (!N1->PointsTo->test(UniversalSet))
|
||||||
return NoModRef; // P doesn't point to the universal set.
|
return NoModRef; // P doesn't point to the universal set.
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return AliasAnalysis::getModRefInfo(CS, P, Size);
|
return AliasAnalysis::getModRefInfo(CS, P, Size);
|
||||||
|
|
@ -1266,29 +1270,43 @@ void Andersens::AddConstraintsForCall(CallSite CS, Function *F) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CallSite::arg_iterator ArgI = CS.arg_begin(), ArgE = CS.arg_end();
|
CallSite::arg_iterator ArgI = CS.arg_begin(), ArgE = CS.arg_end();
|
||||||
|
bool external = !F || F->isDeclaration();
|
||||||
if (F) {
|
if (F) {
|
||||||
// Direct Call
|
// Direct Call
|
||||||
Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end();
|
Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end();
|
||||||
for (; AI != AE && ArgI != ArgE; ++AI, ++ArgI)
|
for (; AI != AE && ArgI != ArgE; ++AI, ++ArgI)
|
||||||
if (isa<PointerType>(AI->getType())) {
|
{
|
||||||
if (isa<PointerType>((*ArgI)->getType())) {
|
#if !FULL_UNIVERSAL
|
||||||
// Copy the actual argument into the formal argument.
|
if (external && isa<PointerType>((*ArgI)->getType()))
|
||||||
Constraints.push_back(Constraint(Constraint::Copy, getNode(AI),
|
{
|
||||||
getNode(*ArgI)));
|
// Add constraint that ArgI can now point to anything due to
|
||||||
} else {
|
// escaping, as can everything it points to. The second portion of
|
||||||
Constraints.push_back(Constraint(Constraint::Copy, getNode(AI),
|
// this should be taken care of by universal = *universal
|
||||||
UniversalSet));
|
Constraints.push_back(Constraint(Constraint::Copy,
|
||||||
}
|
getNode(*ArgI),
|
||||||
} else if (isa<PointerType>((*ArgI)->getType())) {
|
UniversalSet));
|
||||||
#if FULL_UNIVERSAL
|
}
|
||||||
Constraints.push_back(Constraint(Constraint::Copy,
|
|
||||||
UniversalSet,
|
|
||||||
getNode(*ArgI)));
|
|
||||||
#else
|
|
||||||
Constraints.push_back(Constraint(Constraint::Copy,
|
|
||||||
getNode(*ArgI),
|
|
||||||
UniversalSet));
|
|
||||||
#endif
|
#endif
|
||||||
|
if (isa<PointerType>(AI->getType())) {
|
||||||
|
if (isa<PointerType>((*ArgI)->getType())) {
|
||||||
|
// Copy the actual argument into the formal argument.
|
||||||
|
Constraints.push_back(Constraint(Constraint::Copy, getNode(AI),
|
||||||
|
getNode(*ArgI)));
|
||||||
|
} else {
|
||||||
|
Constraints.push_back(Constraint(Constraint::Copy, getNode(AI),
|
||||||
|
UniversalSet));
|
||||||
|
}
|
||||||
|
} else if (isa<PointerType>((*ArgI)->getType())) {
|
||||||
|
#if FULL_UNIVERSAL
|
||||||
|
Constraints.push_back(Constraint(Constraint::Copy,
|
||||||
|
UniversalSet,
|
||||||
|
getNode(*ArgI)));
|
||||||
|
#else
|
||||||
|
Constraints.push_back(Constraint(Constraint::Copy,
|
||||||
|
getNode(*ArgI),
|
||||||
|
UniversalSet));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Indirect Call
|
//Indirect Call
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
; RUN: llvm-as < %s | opt -anders-aa -gvn | llvm-dis \
|
||||||
|
; RUN: | not grep {ret i32 undef}
|
||||||
|
|
||||||
|
;; From PR 2160
|
||||||
|
declare void @f(i32*)
|
||||||
|
|
||||||
|
define i32 @g() {
|
||||||
|
entry:
|
||||||
|
%tmp = alloca i32 ; <i32*> [#uses=2]
|
||||||
|
call void @f( i32* %tmp )
|
||||||
|
%tmp2 = load i32* %tmp ; <i32> [#uses=1]
|
||||||
|
ret i32 %tmp2
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue