blob: 15f9a6576d15e422cbed8b0967d1c74d6292a39c [file] [log] [blame]
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001; This tests the NaCl intrinsics not related to atomic operations.
2
3; RUN: %llvm2ice -O2 --verbose none %s | FileCheck %s
4; RUN: %llvm2ice -O2 --verbose none %s | FileCheck %s --check-prefix=CHECKO2REM
5; RUN: %llvm2ice -Om1 --verbose none %s | FileCheck %s
6; RUN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s
7
8; RUN: %llvm2iceinsts %s | %szdiff %s | FileCheck --check-prefix=DUMP %s
9; RUN: %llvm2iceinsts --pnacl %s | %szdiff %s \
10; RUN: | FileCheck --check-prefix=DUMP %s
11
12declare i8* @llvm.nacl.read.tp()
13declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
14declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
15declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1)
16declare void @llvm.nacl.longjmp(i8*, i32)
17declare i32 @llvm.nacl.setjmp(i8*)
18declare void @llvm.trap()
19
20define i32 @test_nacl_read_tp() {
21entry:
22 %ptr = call i8* @llvm.nacl.read.tp()
23 %__1 = ptrtoint i8* %ptr to i32
24 ret i32 %__1
25}
26; CHECK-LABEL: test_nacl_read_tp
27; CHECK: mov e{{.*}}, dword ptr gs:[0]
28; CHECKO2REM-LABEL: test_nacl_read_tp
29; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0]
30
31define i32 @test_nacl_read_tp_more_addressing() {
32entry:
33 %ptr = call i8* @llvm.nacl.read.tp()
34 %__1 = ptrtoint i8* %ptr to i32
35 %x = add i32 %__1, %__1
36 %__3 = inttoptr i32 %x to i32*
37 %v = load i32* %__3, align 1
38 %ptr2 = call i8* @llvm.nacl.read.tp()
39 %__6 = ptrtoint i8* %ptr2 to i32
40 %y = add i32 %__6, 4
41 %__8 = inttoptr i32 %y to i32*
42 store i32 %v, i32* %__8, align 1
43 ret i32 %v
44}
45; CHECK-LABEL: test_nacl_read_tp_more_addressing
46; CHECK: mov e{{.*}}, dword ptr gs:[0]
47; CHECK: mov e{{.*}}, dword ptr gs:[0]
48; CHECKO2REM-LABEL: test_nacl_read_tp_more_addressing
49; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0]
50; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0]
51
52define i32 @test_nacl_read_tp_dead(i32 %a) {
53entry:
54 %ptr = call i8* @llvm.nacl.read.tp()
55 ; Not actually using the result of nacl read tp call.
56 ; In O2 mode this should be DCE'ed.
57 ret i32 %a
58}
59; Consider nacl.read.tp side-effect free, so it can be eliminated.
60; CHECKO2REM-LABEL: test_nacl_read_tp_dead
61; CHECKO2REM-NOT: mov e{{.*}}, dword ptr gs:[0]
62
63define void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) {
64entry:
65 %dst = inttoptr i32 %iptr_dst to i8*
66 %src = inttoptr i32 %iptr_src to i8*
67 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src,
68 i32 %len, i32 1, i1 0)
69 ret void
70}
71; CHECK-LABEL: test_memcpy
72; CHECK: call memcpy
73
74; TODO(jvoung) -- if we want to be clever, we can do this and the memmove,
75; memset without a function call.
76define void @test_memcpy_const_len_align(i32 %iptr_dst, i32 %iptr_src) {
77entry:
78 %dst = inttoptr i32 %iptr_dst to i8*
79 %src = inttoptr i32 %iptr_src to i8*
80 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src,
81 i32 8, i32 1, i1 0)
82 ret void
83}
84; CHECK-LABEL: test_memcpy_const_len_align
85; CHECK: call memcpy
86
87define void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) {
88entry:
89 %dst = inttoptr i32 %iptr_dst to i8*
90 %src = inttoptr i32 %iptr_src to i8*
91 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src,
92 i32 %len, i32 1, i1 0)
93 ret void
94}
95; CHECK-LABEL: test_memmove
96; CHECK: call memmove
97
98define void @test_memmove_const_len_align(i32 %iptr_dst, i32 %iptr_src) {
99entry:
100 %dst = inttoptr i32 %iptr_dst to i8*
101 %src = inttoptr i32 %iptr_src to i8*
102 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src,
103 i32 8, i32 1, i1 0)
104 ret void
105}
106; CHECK-LABEL: test_memmove_const_len_align
107; CHECK: call memmove
108
109define void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) {
110entry:
111 %val = trunc i32 %wide_val to i8
112 %dst = inttoptr i32 %iptr_dst to i8*
113 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val,
114 i32 %len, i32 1, i1 0)
115 ret void
116}
117; CHECK-LABEL: test_memset
118; CHECK: call memset
119
120define void @test_memset_const_len_align(i32 %iptr_dst, i32 %wide_val) {
121entry:
122 %val = trunc i32 %wide_val to i8
123 %dst = inttoptr i32 %iptr_dst to i8*
124 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val,
125 i32 8, i32 1, i1 0)
126 ret void
127}
128; CHECK-LABEL: test_memset_const_len_align
129; CHECK: call memset
130
131define i32 @test_setjmplongjmp(i32 %iptr_env) {
132entry:
133 %env = inttoptr i32 %iptr_env to i8*
134 %i = call i32 @llvm.nacl.setjmp(i8* %env)
135 %r1 = icmp eq i32 %i, 0
136 br i1 %r1, label %Zero, label %NonZero
137Zero:
138 ; Redundant inttoptr, to make --pnacl cast-eliding/re-insertion happy.
139 %env2 = inttoptr i32 %iptr_env to i8*
140 call void @llvm.nacl.longjmp(i8* %env2, i32 1)
141 ret i32 0
142NonZero:
143 ret i32 1
144}
145; CHECK-LABEL: test_setjmplongjmp
146; CHECK: call setjmp
147; CHECK: call longjmp
148; CHECKO2REM-LABEL: test_setjmplongjmp
149; CHECKO2REM: call setjmp
150; CHECKO2REM: call longjmp
151
152define i32 @test_setjmp_unused(i32 %iptr_env, i32 %i_other) {
153entry:
154 %env = inttoptr i32 %iptr_env to i8*
155 %i = call i32 @llvm.nacl.setjmp(i8* %env)
156 ret i32 %i_other
157}
158; Don't consider setjmp side-effect free, so it's not eliminated if
159; result unused.
160; CHECKO2REM-LABEL: test_setjmp_unused
161; CHECKO2REM: call setjmp
162
163define i32 @test_trap(i32 %br) {
164entry:
165 %r1 = icmp eq i32 %br, 0
166 br i1 %r1, label %Zero, label %NonZero
167Zero:
168 call void @llvm.trap()
169 unreachable
170NonZero:
171 ret i32 1
172}
173; CHECK-LABEL: test_trap
174; CHECK: ud2
175
176; ERRORS-NOT: ICE translation error
177; DUMP-NOT: SZ