diff options
author | Hal Finkel <hfinkel@anl.gov> | 2014-10-14 20:51:26 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2014-10-14 20:51:26 +0000 |
commit | db5f86a9bf983dc0f3ea659bc1897803b8f1fd52 (patch) | |
tree | a826796844e375402c7d5c2f83727ba5d54533d5 | |
parent | 0ca42bb5a8f0e1a3290cd0bd33fdc443941b08ff (diff) | |
download | bcm5719-llvm-db5f86a9bf983dc0f3ea659bc1897803b8f1fd52.tar.gz bcm5719-llvm-db5f86a9bf983dc0f3ea659bc1897803b8f1fd52.zip |
[CFL-AA] CFL-AA should not assert on an va_arg instruction
The CFL-AA implementation was missing a visit* routine for va_arg instructions,
causing it to assert when run on a function that had one. For now, handle these
in a conservative way.
Fixes PR20954.
llvm-svn: 219718
-rw-r--r-- | llvm/lib/Analysis/CFLAliasAnalysis.cpp | 11 | ||||
-rw-r--r-- | llvm/test/Analysis/CFLAliasAnalysis/va.ll | 29 |
2 files changed, 40 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/CFLAliasAnalysis.cpp b/llvm/lib/Analysis/CFLAliasAnalysis.cpp index 0386afeb23a..20bd286eea3 100644 --- a/llvm/lib/Analysis/CFLAliasAnalysis.cpp +++ b/llvm/lib/Analysis/CFLAliasAnalysis.cpp @@ -317,6 +317,17 @@ public: Output.push_back(Edge(Ptr, Val, EdgeType::Dereference, AttrNone)); } + void visitVAArgInst(VAArgInst &Inst) { + // We can't fully model va_arg here. For *Ptr = Inst.getOperand(0), it does + // two things: + // 1. Loads a value from *((T*)*Ptr). + // 2. Increments (stores to) *Ptr by some target-specific amount. + // For now, we'll handle this like a landingpad instruction (by placing the + // result in its own group, and having that group alias externals). + auto *Val = &Inst; + Output.push_back(Edge(Val, Val, EdgeType::Assign, AttrAll)); + } + static bool isFunctionExternal(Function *Fn) { return Fn->isDeclaration() || !Fn->hasLocalLinkage(); } diff --git a/llvm/test/Analysis/CFLAliasAnalysis/va.ll b/llvm/test/Analysis/CFLAliasAnalysis/va.ll new file mode 100644 index 00000000000..3094cb0967f --- /dev/null +++ b/llvm/test/Analysis/CFLAliasAnalysis/va.ll @@ -0,0 +1,29 @@ +; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s + +; CHECK-LABEL: Function: test1 +; CHECK: 0 no alias responses + +define i32 @test1(i32 %X, ...) { + ; Initialize variable argument processing + %ap = alloca i8* + %ap2 = bitcast i8** %ap to i8* + call void @llvm.va_start(i8* %ap2) + + ; Read a single integer argument + %tmp = va_arg i8** %ap, i32 + + ; Demonstrate usage of llvm.va_copy and llvm.va_end + %aq = alloca i8* + %aq2 = bitcast i8** %aq to i8* + call void @llvm.va_copy(i8* %aq2, i8* %ap2) + call void @llvm.va_end(i8* %aq2) + + ; Stop processing of arguments. + call void @llvm.va_end(i8* %ap2) + ret i32 %tmp +} + +declare void @llvm.va_start(i8*) +declare void @llvm.va_copy(i8*, i8*) +declare void @llvm.va_end(i8*) + |