aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/IR/Intrinsics.td12
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp7
-rw-r--r--test/NaCl/ARM/lit.local.cfg2
-rw-r--r--test/NaCl/ARM/nacl-setlongjmp-intrinsics.ll18
-rw-r--r--test/NaCl/X86/nacl-setlongjmp-intrinsics.ll18
5 files changed, 49 insertions, 8 deletions
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index 3d85b2f89f..f9f662929b 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -472,13 +472,11 @@ def int_convertuu : Intrinsic<[llvm_anyint_ty],
// @LOCALMOD-BEGIN
//===----------------------- Native Client Intrinsics ---------------------===//
-// TODO(sehr): conditionalize this on IsNaCl64 | IsNaCl32 | IsNaClArm.
-// The expansions of these are in lib/Target/X86/X86InstrNacl.{td, cpp} and
-// lib/Target/ARM/ARMInstrInfo.td.
-def int_nacl_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_ptr_ty]>,
- GCCBuiltin<"__builtin_nacl_setjmp">;
-def int_nacl_longjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>,
- GCCBuiltin<"__builtin_nacl_longjmp">;
+// NaCl-specific setjmp/longjmp intrinsics.
+// See https://code.google.com/p/nativeclient/issues/detail?id=3429
+def int_nacl_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
+def int_nacl_longjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoReturn]>;
// Fast built-in version of NaCl's tls_get() IRT interface.
def int_nacl_read_tp : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>,
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index b7a7e2e133..9113fb1b6f 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5215,6 +5215,13 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
setValue(&I, DAG.getNode(ISD::NACL_TARGET_ARCH, dl, DestVT));
return 0;
}
+ // Native Client Intrinsics for setjmp/longjmp
+ case Intrinsic::nacl_setjmp: {
+ return "setjmp";
+ }
+ case Intrinsic::nacl_longjmp: {
+ return "longjmp";
+ }
// @LOCALMOD-END
}
}
diff --git a/test/NaCl/ARM/lit.local.cfg b/test/NaCl/ARM/lit.local.cfg
index 1f10377867..bac2ffab31 100644
--- a/test/NaCl/ARM/lit.local.cfg
+++ b/test/NaCl/ARM/lit.local.cfg
@@ -1,4 +1,4 @@
-config.suffixes = ['.ll', '.s']
+config.suffixes = ['.ll']
targets = set(config.root.targets_to_build.split())
if not 'ARM' in targets:
diff --git a/test/NaCl/ARM/nacl-setlongjmp-intrinsics.ll b/test/NaCl/ARM/nacl-setlongjmp-intrinsics.ll
new file mode 100644
index 0000000000..73251d10f3
--- /dev/null
+++ b/test/NaCl/ARM/nacl-setlongjmp-intrinsics.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple=arm-unknown-nacl -filetype=asm %s -o - \
+; RUN: | FileCheck %s --check-prefix=ARM
+; Test that @llvm.nacl.{set|long}jmp intrinsics calls get translated to library
+; calls as expected.
+
+declare i32 @llvm.nacl.setjmp(i8*)
+declare void @llvm.nacl.longjmp(i8*, i32)
+
+define void @foo(i8* %arg) {
+ %num = call i32 @llvm.nacl.setjmp(i8* %arg)
+; ARM: bl setjmp
+
+ call void @llvm.nacl.longjmp(i8* %arg, i32 %num)
+; ARM: bl longjmp
+
+ ret void
+}
+
diff --git a/test/NaCl/X86/nacl-setlongjmp-intrinsics.ll b/test/NaCl/X86/nacl-setlongjmp-intrinsics.ll
new file mode 100644
index 0000000000..fa827a2758
--- /dev/null
+++ b/test/NaCl/X86/nacl-setlongjmp-intrinsics.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple=i386-unknown-nacl -filetype=asm %s -o - \
+; RUN: | FileCheck %s --check-prefix=X86
+; Test that @llvm.nacl.{set|long}jmp intrinsics calls get translated to library
+; calls as expected.
+
+declare i32 @llvm.nacl.setjmp(i8*)
+declare void @llvm.nacl.longjmp(i8*, i32)
+
+define void @foo(i8* %arg) {
+ %num = call i32 @llvm.nacl.setjmp(i8* %arg)
+; X86: naclcall setjmp
+
+ call void @llvm.nacl.longjmp(i8* %arg, i32 %num)
+; X86: naclcall longjmp
+
+ ret void
+}
+