diff options
| -rw-r--r-- | llvm/lib/Analysis/IPA/Andersens.cpp | 54 | ||||
| -rw-r--r-- | llvm/test/Analysis/Andersens/modreftest2.ll | 14 | 
2 files changed, 50 insertions, 18 deletions
diff --git a/llvm/lib/Analysis/IPA/Andersens.cpp b/llvm/lib/Analysis/IPA/Andersens.cpp index a66a6faf1c5..49c6edd6207 100644 --- a/llvm/lib/Analysis/IPA/Andersens.cpp +++ b/llvm/lib/Analysis/IPA/Andersens.cpp @@ -647,9 +647,13 @@ Andersens::getModRefInfo(CallSite CS, Value *P, unsigned Size) {        if (N1->PointsTo->empty())          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))          return NoModRef;  // P doesn't point to the universal set. +#endif      }    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(); +  bool external = !F ||  F->isDeclaration();    if (F) {      // Direct Call      Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end(); -    for (; AI != AE && ArgI != ArgE; ++AI, ++ArgI) -      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())) { +    for (; AI != AE && ArgI != ArgE; ++AI, ++ArgI)  +      { +#if !FULL_UNIVERSAL +        if (external && isa<PointerType>((*ArgI)->getType()))  +          { +            // Add constraint that ArgI can now point to anything due to +            // escaping, as can everything it points to. The second portion of +            // this should be taken care of by universal = *universal +            Constraints.push_back(Constraint(Constraint::Copy, +                                             getNode(*ArgI), +                                             UniversalSet)); +          } +#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))); +          Constraints.push_back(Constraint(Constraint::Copy, +                                           UniversalSet, +                                           getNode(*ArgI)));  #else -        Constraints.push_back(Constraint(Constraint::Copy, -                                         getNode(*ArgI), -                                         UniversalSet)); +          Constraints.push_back(Constraint(Constraint::Copy, +                                           getNode(*ArgI), +                                           UniversalSet));  #endif +        }        }    } else {      //Indirect Call diff --git a/llvm/test/Analysis/Andersens/modreftest2.ll b/llvm/test/Analysis/Andersens/modreftest2.ll new file mode 100644 index 00000000000..2bb21673676 --- /dev/null +++ b/llvm/test/Analysis/Andersens/modreftest2.ll @@ -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 +} +  | 

