aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp9
-rw-r--r--test/Transforms/NaCl/rewrite-call-with-libfunc-argument.ll18
2 files changed, 25 insertions, 2 deletions
diff --git a/lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp b/lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp
index a01e8c6b2a..6656a672fe 100644
--- a/lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp
+++ b/lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp
@@ -171,9 +171,14 @@ bool RewritePNaClLibraryCalls::RewriteLibraryCall(
for (Value::use_iterator UI = LibFunc->use_begin(),
UE = LibFunc->use_end(); UI != UE;) {
Value *Use = *UI++;
+ // use_iterator will also provide call instructions in which the used
+ // value is an argument, and not the value being called. Make sure we
+ // rewrite only actual calls to LibFunc here.
if (CallInst *Call = dyn_cast<CallInst>(Use)) {
- (this->*(CallRewriter))(Call);
- Changed = true;
+ if (Call->getCalledValue() == LibFunc) {
+ (this->*(CallRewriter))(Call);
+ Changed = true;
+ }
}
}
diff --git a/test/Transforms/NaCl/rewrite-call-with-libfunc-argument.ll b/test/Transforms/NaCl/rewrite-call-with-libfunc-argument.ll
new file mode 100644
index 0000000000..56ee2d2c07
--- /dev/null
+++ b/test/Transforms/NaCl/rewrite-call-with-libfunc-argument.ll
@@ -0,0 +1,18 @@
+; RUN: opt < %s -rewrite-pnacl-library-calls -S | FileCheck %s
+
+; See https://code.google.com/p/nativeclient/issues/detail?id=3706
+; Make sure that when @longjmp is used as an argument in a call instruction,
+; the rewrite pass does the right thing and doesn't get confused.
+
+; CHECK: define internal void @longjmp(i64* %env, i32 %val) {
+
+declare void @longjmp(i64*, i32)
+
+declare void @somefunc(i32, void (i64*, i32)*, i32)
+
+define void @foo() {
+entry:
+ call void @somefunc(i32 1, void (i64*, i32)* @longjmp, i32 2)
+; CHECK: call void @somefunc(i32 1, void (i64*, i32)* @longjmp, i32 2)
+ ret void
+}