Index: lib/Analysis/CFLAliasAnalysis.cpp =================================================================== --- lib/Analysis/CFLAliasAnalysis.cpp +++ lib/Analysis/CFLAliasAnalysis.cpp @@ -398,6 +398,8 @@ } template void visitCallLikeInst(InstT &Inst) { + // TODO: Add support for noalias args/all the other fun function attributes + // that we can tack on. SmallVector Targets; if (getPossibleTargets(&Inst, Targets)) { if (tryInterproceduralAnalysis(Targets, &Inst, Inst.arg_operands())) @@ -406,8 +408,12 @@ Output.clear(); } + // Because the function is opaque, we need to note that anything + // could have happened to the arguments, and that the result could alias + // just about anything, too. for (Value *V : Inst.arg_operands()) Output.push_back(Edge(&Inst, V, EdgeType::Assign, AttrAll)); + Output.push_back(Edge(&Inst, &Inst, EdgeType::Assign, AttrAll)); } void visitCallInst(CallInst &Inst) { visitCallLikeInst(Inst); } Index: test/Analysis/CFLAliasAnalysis/opaque-call-alias.ll =================================================================== --- test/Analysis/CFLAliasAnalysis/opaque-call-alias.ll +++ test/Analysis/CFLAliasAnalysis/opaque-call-alias.ll @@ -0,0 +1,20 @@ +; We previously had a case where we would put results from a no-args call in +; its own stratified set. This would make cases like the one in @test say that +; nothing (except %Escapes and %Arg) can alias + +; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s + +; CHECK: Function: test +; CHECK: MayAlias: i8* %Arg, i8* %Escapes +; CHECK: MayAlias: i8* %Arg, i8* %Retrieved +; CHECK: MayAlias: i8* %Escapes, i8* %Retrieved +define void @test(i8* %Arg) { + %Noalias = alloca i8 + %Escapes = alloca i8 + call void @set_thepointer(i8* %Escapes) + %Retrieved = call i8* @get_thepointer() + ret void +} + +declare void @set_thepointer(i8* %P) +declare i8* @get_thepointer()