Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(944)

Side by Side Diff: tests_lit/llvm2ice_tests/nacl-other-intrinsics.ll

Issue 1222943003: ARM32: Lower more integer intrinsics and test. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: move to TargetLowering Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringX86BaseImpl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 ; This tests the NaCl intrinsics not related to atomic operations. 1 ; This tests the NaCl intrinsics not related to atomic operations.
2 2
3 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 -sandbox \ 3 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
4 ; RUN: | FileCheck %s 4 ; RUN: --target x8632 -i %s --args -O2 -sandbox \
5 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 -sandbox \ 5 ; RUN: | %if --need=target_X8632 --command FileCheck %s
6 ; RUN: | FileCheck %s 6 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
7 ; RUN: --target x8632 -i %s --args -Om1 -sandbox \
8 ; RUN: | %if --need=target_X8632 --command FileCheck %s
7 9
8 ; Do another run w/ O2 and a different check-prefix (otherwise O2 and Om1 10 ; Do another run w/ O2 and a different check-prefix (otherwise O2 and Om1
9 ; share the same "CHECK" prefix). This separate run helps check that 11 ; share the same "CHECK" prefix). This separate run helps check that
10 ; some code is optimized out. 12 ; some code is optimized out.
11 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 -sandbox \ 13 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
12 ; RUN: | FileCheck --check-prefix=CHECKO2REM %s 14 ; RUN: --target x8632 -i %s --args -O2 -sandbox \
15 ; RUN: | %if --need=target_X8632 \
16 ; RUN: --command FileCheck --check-prefix=CHECKO2REM %s
13 17
14 ; Do O2 runs without -sandbox to make sure llvm.nacl.read.tp gets 18 ; Do O2 runs without -sandbox to make sure llvm.nacl.read.tp gets
15 ; lowered to __nacl_read_tp instead of gs:0x0. 19 ; lowered to __nacl_read_tp instead of gs:0x0.
16 ; We also know that because it's O2, it'll have the O2REM optimizations. 20 ; We also know that because it's O2, it'll have the O2REM optimizations.
17 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ 21 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
18 ; RUN: | FileCheck --check-prefix=CHECKO2UNSANDBOXEDREM %s 22 ; RUN: --target x8632 -i %s --args -O2 \
23 ; RUN: | %if --need=target_X8632 \
24 ; RUN: --command FileCheck --check-prefix=CHECKO2UNSANDBOXEDREM %s
25
26 ; RUN: %if --need=target_ARM32 --need=allow_dump \
27 ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \
28 ; RUN: -i %s --args -O2 --skip-unimplemented \
29 ; RUN: | %if --need=target_ARM32 --need=allow_dump \
30 ; RUN: --command FileCheck --check-prefix ARM32 %s
31
19 32
20 declare i8* @llvm.nacl.read.tp() 33 declare i8* @llvm.nacl.read.tp()
21 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) 34 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
22 declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) 35 declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
23 declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1) 36 declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1)
24 declare void @llvm.nacl.longjmp(i8*, i32) 37 declare void @llvm.nacl.longjmp(i8*, i32)
25 declare i32 @llvm.nacl.setjmp(i8*) 38 declare i32 @llvm.nacl.setjmp(i8*)
26 declare float @llvm.sqrt.f32(float) 39 declare float @llvm.sqrt.f32(float)
27 declare double @llvm.sqrt.f64(double) 40 declare double @llvm.sqrt.f64(double)
28 declare float @llvm.fabs.f32(float) 41 declare float @llvm.fabs.f32(float)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 %dst = inttoptr i32 %iptr_dst to i8* 112 %dst = inttoptr i32 %iptr_dst to i8*
100 %src = inttoptr i32 %iptr_src to i8* 113 %src = inttoptr i32 %iptr_src to i8*
101 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, 114 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src,
102 i32 %len, i32 1, i1 false) 115 i32 %len, i32 1, i1 false)
103 ret void 116 ret void
104 } 117 }
105 ; CHECK-LABEL: test_memcpy 118 ; CHECK-LABEL: test_memcpy
106 ; CHECK: call {{.*}} R_{{.*}} memcpy 119 ; CHECK: call {{.*}} R_{{.*}} memcpy
107 ; CHECKO2REM-LABEL: test_memcpy 120 ; CHECKO2REM-LABEL: test_memcpy
108 ; CHECKO2UNSANDBOXEDREM-LABEL: test_memcpy 121 ; CHECKO2UNSANDBOXEDREM-LABEL: test_memcpy
122 ; ARM32-LABEL: test_memcpy
123 ; ARM32: bl {{.*}} memcpy
109 124
110 ; TODO(jvoung) -- if we want to be clever, we can do this and the memmove, 125 ; TODO(jvoung) -- if we want to be clever, we can do this and the memmove,
111 ; memset without a function call. 126 ; memset without a function call.
112 define void @test_memcpy_const_len_align(i32 %iptr_dst, i32 %iptr_src) { 127 define void @test_memcpy_const_len_align(i32 %iptr_dst, i32 %iptr_src) {
113 entry: 128 entry:
114 %dst = inttoptr i32 %iptr_dst to i8* 129 %dst = inttoptr i32 %iptr_dst to i8*
115 %src = inttoptr i32 %iptr_src to i8* 130 %src = inttoptr i32 %iptr_src to i8*
116 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, 131 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src,
117 i32 8, i32 1, i1 false) 132 i32 32, i32 1, i1 false)
118 ret void 133 ret void
119 } 134 }
120 ; CHECK-LABEL: test_memcpy_const_len_align 135 ; CHECK-LABEL: test_memcpy_const_len_align
121 ; CHECK: call {{.*}} R_{{.*}} memcpy 136 ; CHECK: call {{.*}} R_{{.*}} memcpy
137 ; ARM32-LABEL: test_memcpy_const_len_align
138 ; ARM32: bl {{.*}} memcpy
122 139
123 define void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) { 140 define void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) {
124 entry: 141 entry:
125 %dst = inttoptr i32 %iptr_dst to i8* 142 %dst = inttoptr i32 %iptr_dst to i8*
126 %src = inttoptr i32 %iptr_src to i8* 143 %src = inttoptr i32 %iptr_src to i8*
127 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, 144 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src,
128 i32 %len, i32 1, i1 false) 145 i32 %len, i32 1, i1 false)
129 ret void 146 ret void
130 } 147 }
131 ; CHECK-LABEL: test_memmove 148 ; CHECK-LABEL: test_memmove
132 ; CHECK: call {{.*}} R_{{.*}} memmove 149 ; CHECK: call {{.*}} R_{{.*}} memmove
150 ; ARM32-LABEL: test_memmove
151 ; ARM32: bl {{.*}} memmove
133 152
134 define void @test_memmove_const_len_align(i32 %iptr_dst, i32 %iptr_src) { 153 define void @test_memmove_const_len_align(i32 %iptr_dst, i32 %iptr_src) {
135 entry: 154 entry:
136 %dst = inttoptr i32 %iptr_dst to i8* 155 %dst = inttoptr i32 %iptr_dst to i8*
137 %src = inttoptr i32 %iptr_src to i8* 156 %src = inttoptr i32 %iptr_src to i8*
138 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, 157 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src,
139 i32 8, i32 1, i1 false) 158 i32 32, i32 1, i1 false)
140 ret void 159 ret void
141 } 160 }
142 ; CHECK-LABEL: test_memmove_const_len_align 161 ; CHECK-LABEL: test_memmove_const_len_align
143 ; CHECK: call {{.*}} R_{{.*}} memmove 162 ; CHECK: call {{.*}} R_{{.*}} memmove
163 ; ARM32-LABEL: test_memmove_const_len_align
164 ; ARM32: bl {{.*}} memmove
144 165
145 define void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) { 166 define void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) {
146 entry: 167 entry:
147 %val = trunc i32 %wide_val to i8 168 %val = trunc i32 %wide_val to i8
148 %dst = inttoptr i32 %iptr_dst to i8* 169 %dst = inttoptr i32 %iptr_dst to i8*
149 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, 170 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val,
150 i32 %len, i32 1, i1 false) 171 i32 %len, i32 1, i1 false)
151 ret void 172 ret void
152 } 173 }
153 ; CHECK-LABEL: test_memset 174 ; CHECK-LABEL: test_memset
154 ; CHECK: movzx 175 ; CHECK: movzx
155 ; CHECK: call {{.*}} R_{{.*}} memset 176 ; CHECK: call {{.*}} R_{{.*}} memset
177 ; ARM32-LABEL: test_memset
178 ; ARM32: uxtb
179 ; ARM32: bl {{.*}} memset
156 180
157 define void @test_memset_const_len_align(i32 %iptr_dst, i32 %wide_val) { 181 define void @test_memset_const_len_align(i32 %iptr_dst, i32 %wide_val) {
158 entry: 182 entry:
159 %val = trunc i32 %wide_val to i8 183 %val = trunc i32 %wide_val to i8
160 %dst = inttoptr i32 %iptr_dst to i8* 184 %dst = inttoptr i32 %iptr_dst to i8*
161 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, 185 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val,
162 i32 8, i32 1, i1 false) 186 i32 32, i32 1, i1 false)
163 ret void 187 ret void
164 } 188 }
165 ; CHECK-LABEL: test_memset_const_len_align 189 ; CHECK-LABEL: test_memset_const_len_align
166 ; CHECK: movzx 190 ; CHECK: movzx
167 ; CHECK: call {{.*}} R_{{.*}} memset 191 ; CHECK: call {{.*}} R_{{.*}} memset
192 ; ARM32-LABEL: test_memset_const_len_align
193 ; ARM32: uxtb
194 ; ARM32: bl {{.*}} memset
168 195
169 define void @test_memset_const_val(i32 %iptr_dst, i32 %len) { 196 define void @test_memset_const_val(i32 %iptr_dst, i32 %len) {
170 entry: 197 entry:
171 %dst = inttoptr i32 %iptr_dst to i8* 198 %dst = inttoptr i32 %iptr_dst to i8*
172 call void @llvm.memset.p0i8.i32(i8* %dst, i8 0, i32 %len, i32 1, i1 false) 199 call void @llvm.memset.p0i8.i32(i8* %dst, i8 0, i32 %len, i32 1, i1 false)
173 ret void 200 ret void
174 } 201 }
175 ; CHECK-LABEL: test_memset_const_val 202 ; CHECK-LABEL: test_memset_const_val
176 ; Make sure the argument is legalized (can't movzx reg, 0). 203 ; Make sure the argument is legalized (can't movzx reg, 0).
177 ; CHECK: movzx {{.*}},{{[^0]}} 204 ; CHECK: movzx {{.*}},{{[^0]}}
178 ; CHECK: call {{.*}} R_{{.*}} memset 205 ; CHECK: call {{.*}} R_{{.*}} memset
179 206 ; ARM32-LABEL: test_memset_const_val
207 ; ARM32: uxtb
208 ; ARM32: bl {{.*}} memset
180 209
181 define i32 @test_setjmplongjmp(i32 %iptr_env) { 210 define i32 @test_setjmplongjmp(i32 %iptr_env) {
182 entry: 211 entry:
183 %env = inttoptr i32 %iptr_env to i8* 212 %env = inttoptr i32 %iptr_env to i8*
184 %i = call i32 @llvm.nacl.setjmp(i8* %env) 213 %i = call i32 @llvm.nacl.setjmp(i8* %env)
185 %r1 = icmp eq i32 %i, 0 214 %r1 = icmp eq i32 %i, 0
186 br i1 %r1, label %Zero, label %NonZero 215 br i1 %r1, label %Zero, label %NonZero
187 Zero: 216 Zero:
188 ; Redundant inttoptr, to make --pnacl cast-eliding/re-insertion happy. 217 ; Redundant inttoptr, to make --pnacl cast-eliding/re-insertion happy.
189 %env2 = inttoptr i32 %iptr_env to i8* 218 %env2 = inttoptr i32 %iptr_env to i8*
190 call void @llvm.nacl.longjmp(i8* %env2, i32 1) 219 call void @llvm.nacl.longjmp(i8* %env2, i32 1)
191 ret i32 0 220 ret i32 0
192 NonZero: 221 NonZero:
193 ret i32 1 222 ret i32 1
194 } 223 }
195 ; CHECK-LABEL: test_setjmplongjmp 224 ; CHECK-LABEL: test_setjmplongjmp
196 ; CHECK: call {{.*}} R_{{.*}} setjmp 225 ; CHECK: call {{.*}} R_{{.*}} setjmp
197 ; CHECK: call {{.*}} R_{{.*}} longjmp 226 ; CHECK: call {{.*}} R_{{.*}} longjmp
198 ; CHECKO2REM-LABEL: test_setjmplongjmp 227 ; CHECKO2REM-LABEL: test_setjmplongjmp
199 ; CHECKO2REM: call {{.*}} R_{{.*}} setjmp 228 ; CHECKO2REM: call {{.*}} R_{{.*}} setjmp
200 ; CHECKO2REM: call {{.*}} R_{{.*}} longjmp 229 ; CHECKO2REM: call {{.*}} R_{{.*}} longjmp
230 ; ARM32-LABEL: test_setjmplongjmp
231 ; ARM32: bl {{.*}} setjmp
232 ; ARM32: bl {{.*}} longjmp
201 233
202 define i32 @test_setjmp_unused(i32 %iptr_env, i32 %i_other) { 234 define i32 @test_setjmp_unused(i32 %iptr_env, i32 %i_other) {
203 entry: 235 entry:
204 %env = inttoptr i32 %iptr_env to i8* 236 %env = inttoptr i32 %iptr_env to i8*
205 %i = call i32 @llvm.nacl.setjmp(i8* %env) 237 %i = call i32 @llvm.nacl.setjmp(i8* %env)
206 ret i32 %i_other 238 ret i32 %i_other
207 } 239 }
208 ; Don't consider setjmp side-effect free, so it's not eliminated if 240 ; Don't consider setjmp side-effect free, so it's not eliminated if
209 ; result unused. 241 ; result unused.
210 ; CHECKO2REM-LABEL: test_setjmp_unused 242 ; CHECKO2REM-LABEL: test_setjmp_unused
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 %r1 = icmp eq i32 %br, 0 369 %r1 = icmp eq i32 %br, 0
338 br i1 %r1, label %Zero, label %NonZero 370 br i1 %r1, label %Zero, label %NonZero
339 Zero: 371 Zero:
340 call void @llvm.trap() 372 call void @llvm.trap()
341 unreachable 373 unreachable
342 NonZero: 374 NonZero:
343 ret i32 1 375 ret i32 1
344 } 376 }
345 ; CHECK-LABEL: test_trap 377 ; CHECK-LABEL: test_trap
346 ; CHECK: ud2 378 ; CHECK: ud2
379 ; ARM32-LABEL: test_trap
380 ; ARM32: .word 0xe7fedef0
347 381
348 define i32 @test_bswap_16(i32 %x) { 382 define i32 @test_bswap_16(i32 %x) {
349 entry: 383 entry:
350 %x_trunc = trunc i32 %x to i16 384 %x_trunc = trunc i32 %x to i16
351 %r = call i16 @llvm.bswap.i16(i16 %x_trunc) 385 %r = call i16 @llvm.bswap.i16(i16 %x_trunc)
352 %r_zext = zext i16 %r to i32 386 %r_zext = zext i16 %r to i32
353 ret i32 %r_zext 387 ret i32 %r_zext
354 } 388 }
355 ; CHECK-LABEL: test_bswap_16 389 ; CHECK-LABEL: test_bswap_16
356 ; Make sure this is the right operand size so that the most significant bit 390 ; Make sure this is the right operand size so that the most significant bit
357 ; to least significant bit rotation happens at the right boundary. 391 ; to least significant bit rotation happens at the right boundary.
358 ; CHECK: rol {{[abcd]x|si|di|bp|word ptr}},0x8 392 ; CHECK: rol {{[abcd]x|si|di|bp|word ptr}},0x8
393 ; ARM32-LABEL: test_bswap_16
394 ; ARM32: rev
395 ; ARM32: lsr {{.*}} #16
359 396
360 define i32 @test_bswap_32(i32 %x) { 397 define i32 @test_bswap_32(i32 %x) {
361 entry: 398 entry:
362 %r = call i32 @llvm.bswap.i32(i32 %x) 399 %r = call i32 @llvm.bswap.i32(i32 %x)
363 ret i32 %r 400 ret i32 %r
364 } 401 }
365 ; CHECK-LABEL: test_bswap_32 402 ; CHECK-LABEL: test_bswap_32
366 ; CHECK: bswap e{{.*}} 403 ; CHECK: bswap e{{.*}}
404 ; ARM32-LABEL: test_bswap_32
405 ; ARM32: rev
367 406
368 define i64 @test_bswap_64(i64 %x) { 407 define i64 @test_bswap_64(i64 %x) {
369 entry: 408 entry:
370 %r = call i64 @llvm.bswap.i64(i64 %x) 409 %r = call i64 @llvm.bswap.i64(i64 %x)
371 ret i64 %r 410 ret i64 %r
372 } 411 }
373 ; CHECK-LABEL: test_bswap_64 412 ; CHECK-LABEL: test_bswap_64
374 ; CHECK: bswap e{{.*}} 413 ; CHECK: bswap e{{.*}}
375 ; CHECK: bswap e{{.*}} 414 ; CHECK: bswap e{{.*}}
415 ; ARM32-LABEL: test_bswap_64
416 ; ARM32: rev
417 ; ARM32: rev
376 418
377 define i32 @test_ctlz_32(i32 %x) { 419 define i32 @test_ctlz_32(i32 %x) {
378 entry: 420 entry:
379 %r = call i32 @llvm.ctlz.i32(i32 %x, i1 false) 421 %r = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
380 ret i32 %r 422 ret i32 %r
381 } 423 }
382 ; CHECK-LABEL: test_ctlz_32 424 ; CHECK-LABEL: test_ctlz_32
383 ; TODO(jvoung): If we detect that LZCNT is supported, then use that 425 ; TODO(jvoung): If we detect that LZCNT is supported, then use that
384 ; and avoid the need to do the cmovne and xor stuff to guarantee that 426 ; and avoid the need to do the cmovne and xor stuff to guarantee that
385 ; the result is well-defined w/ input == 0. 427 ; the result is well-defined w/ input == 0.
386 ; CHECK: bsr [[REG_TMP:e.*]],{{.*}} 428 ; CHECK: bsr [[REG_TMP:e.*]],{{.*}}
387 ; CHECK: mov [[REG_RES:e.*]],0x3f 429 ; CHECK: mov [[REG_RES:e.*]],0x3f
388 ; CHECK: cmovne [[REG_RES]],[[REG_TMP]] 430 ; CHECK: cmovne [[REG_RES]],[[REG_TMP]]
389 ; CHECK: xor [[REG_RES]],0x1f 431 ; CHECK: xor [[REG_RES]],0x1f
432 ; ARM32-LABEL: test_ctlz_32
433 ; ARM32: clz
390 434
391 define i32 @test_ctlz_32_const() { 435 define i32 @test_ctlz_32_const() {
392 entry: 436 entry:
393 %r = call i32 @llvm.ctlz.i32(i32 123456, i1 false) 437 %r = call i32 @llvm.ctlz.i32(i32 123456, i1 false)
394 ret i32 %r 438 ret i32 %r
395 } 439 }
396 ; Could potentially constant fold this, but the front-end should have done that. 440 ; Could potentially constant fold this, but the front-end should have done that.
397 ; The dest operand must be a register and the source operand must be a register 441 ; The dest operand must be a register and the source operand must be a register
398 ; or memory. 442 ; or memory.
399 ; CHECK-LABEL: test_ctlz_32_const 443 ; CHECK-LABEL: test_ctlz_32_const
400 ; CHECK: bsr e{{.*}},{{.*}}e{{.*}} 444 ; CHECK: bsr e{{.*}},{{.*}}e{{.*}}
445 ; ARM32-LABEL: test_ctlz_32_const
446 ; ARM32: clz
401 447
402 define i32 @test_ctlz_32_ignored(i32 %x) { 448 define i32 @test_ctlz_32_ignored(i32 %x) {
403 entry: 449 entry:
404 %ignored = call i32 @llvm.ctlz.i32(i32 %x, i1 false) 450 %ignored = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
405 ret i32 1 451 ret i32 1
406 } 452 }
407 ; CHECKO2REM-LABEL: test_ctlz_32_ignored 453 ; CHECKO2REM-LABEL: test_ctlz_32_ignored
408 ; CHECKO2REM-NOT: bsr 454 ; CHECKO2REM-NOT: bsr
409 455
410 define i64 @test_ctlz_64(i64 %x) { 456 define i64 @test_ctlz_64(i64 %x) {
411 entry: 457 entry:
412 %r = call i64 @llvm.ctlz.i64(i64 %x, i1 false) 458 %r = call i64 @llvm.ctlz.i64(i64 %x, i1 false)
413 ret i64 %r 459 ret i64 %r
414 } 460 }
415 ; CHECKO2REM-LABEL: test_ctlz_64 461 ; CHECKO2REM-LABEL: test_ctlz_64
416 ; CHECK-LABEL: test_ctlz_64 462 ; CHECK-LABEL: test_ctlz_64
417 ; CHECK: bsr [[REG_TMP1:e.*]],{{.*}} 463 ; CHECK: bsr [[REG_TMP1:e.*]],{{.*}}
418 ; CHECK: mov [[REG_RES1:e.*]],0x3f 464 ; CHECK: mov [[REG_RES1:e.*]],0x3f
419 ; CHECK: cmovne [[REG_RES1]],[[REG_TMP1]] 465 ; CHECK: cmovne [[REG_RES1]],[[REG_TMP1]]
420 ; CHECK: xor [[REG_RES1]],0x1f 466 ; CHECK: xor [[REG_RES1]],0x1f
421 ; CHECK: add [[REG_RES1]],0x20 467 ; CHECK: add [[REG_RES1]],0x20
422 ; CHECK: bsr [[REG_RES2:e.*]],{{.*}} 468 ; CHECK: bsr [[REG_RES2:e.*]],{{.*}}
423 ; CHECK: xor [[REG_RES2]],0x1f 469 ; CHECK: xor [[REG_RES2]],0x1f
424 ; CHECK: test [[REG_UPPER:.*]],[[REG_UPPER]] 470 ; CHECK: test [[REG_UPPER:.*]],[[REG_UPPER]]
425 ; CHECK: cmove [[REG_RES2]],[[REG_RES1]] 471 ; CHECK: cmove [[REG_RES2]],[[REG_RES1]]
426 ; CHECK: mov {{.*}},0x0 472 ; CHECK: mov {{.*}},0x0
473 ; ARM32-LABEL: test_ctlz_64
474 ; ARM32: clz
475 ; ARM32: cmp {{.*}}, #0
476 ; ARM32: add {{.*}}, #32
477 ; ARM32: clzne
478 ; ARM32: mov {{.*}}, #0
427 479
428 define i32 @test_ctlz_64_const(i64 %x) { 480 define i32 @test_ctlz_64_const(i64 %x) {
429 entry: 481 entry:
430 %r = call i64 @llvm.ctlz.i64(i64 123456789012, i1 false) 482 %r = call i64 @llvm.ctlz.i64(i64 123456789012, i1 false)
431 %r2 = trunc i64 %r to i32 483 %r2 = trunc i64 %r to i32
432 ret i32 %r2 484 ret i32 %r2
433 } 485 }
434 ; CHECK-LABEL: test_ctlz_64_const 486 ; CHECK-LABEL: test_ctlz_64_const
435 ; CHECK: bsr e{{.*}},{{.*}}e{{.*}} 487 ; CHECK: bsr e{{.*}},{{.*}}e{{.*}}
436 ; CHECK: bsr e{{.*}},{{.*}}e{{.*}} 488 ; CHECK: bsr e{{.*}},{{.*}}e{{.*}}
437 489 ; ARM32-LABEL: test_ctlz_64
490 ; ARM32: clz
491 ; ARM32: clzne
438 492
439 define i32 @test_ctlz_64_ignored(i64 %x) { 493 define i32 @test_ctlz_64_ignored(i64 %x) {
440 entry: 494 entry:
441 %ignored = call i64 @llvm.ctlz.i64(i64 1234567890, i1 false) 495 %ignored = call i64 @llvm.ctlz.i64(i64 1234567890, i1 false)
442 ret i32 2 496 ret i32 2
443 } 497 }
444 ; CHECKO2REM-LABEL: test_ctlz_64_ignored 498 ; CHECKO2REM-LABEL: test_ctlz_64_ignored
445 ; CHECKO2REM-NOT: bsr 499 ; CHECKO2REM-NOT: bsr
446 500
447 define i32 @test_cttz_32(i32 %x) { 501 define i32 @test_cttz_32(i32 %x) {
448 entry: 502 entry:
449 %r = call i32 @llvm.cttz.i32(i32 %x, i1 false) 503 %r = call i32 @llvm.cttz.i32(i32 %x, i1 false)
450 ret i32 %r 504 ret i32 %r
451 } 505 }
452 ; CHECK-LABEL: test_cttz_32 506 ; CHECK-LABEL: test_cttz_32
453 ; CHECK: bsf [[REG_IF_NOTZERO:e.*]],{{.*}} 507 ; CHECK: bsf [[REG_IF_NOTZERO:e.*]],{{.*}}
454 ; CHECK: mov [[REG_IF_ZERO:e.*]],0x20 508 ; CHECK: mov [[REG_IF_ZERO:e.*]],0x20
455 ; CHECK: cmovne [[REG_IF_ZERO]],[[REG_IF_NOTZERO]] 509 ; CHECK: cmovne [[REG_IF_ZERO]],[[REG_IF_NOTZERO]]
510 ; ARM32-LABEL: test_cttz_32
511 ; ARM32: rbit
512 ; ARM32: clz
456 513
457 define i64 @test_cttz_64(i64 %x) { 514 define i64 @test_cttz_64(i64 %x) {
458 entry: 515 entry:
459 %r = call i64 @llvm.cttz.i64(i64 %x, i1 false) 516 %r = call i64 @llvm.cttz.i64(i64 %x, i1 false)
460 ret i64 %r 517 ret i64 %r
461 } 518 }
462 ; CHECK-LABEL: test_cttz_64 519 ; CHECK-LABEL: test_cttz_64
463 ; CHECK: bsf [[REG_IF_NOTZERO:e.*]],{{.*}} 520 ; CHECK: bsf [[REG_IF_NOTZERO:e.*]],{{.*}}
464 ; CHECK: mov [[REG_RES1:e.*]],0x20 521 ; CHECK: mov [[REG_RES1:e.*]],0x20
465 ; CHECK: cmovne [[REG_RES1]],[[REG_IF_NOTZERO]] 522 ; CHECK: cmovne [[REG_RES1]],[[REG_IF_NOTZERO]]
466 ; CHECK: add [[REG_RES1]],0x20 523 ; CHECK: add [[REG_RES1]],0x20
467 ; CHECK: bsf [[REG_RES2:e.*]],[[REG_LOWER:.*]] 524 ; CHECK: bsf [[REG_RES2:e.*]],[[REG_LOWER:.*]]
468 ; CHECK: test [[REG_LOWER]],[[REG_LOWER]] 525 ; CHECK: test [[REG_LOWER]],[[REG_LOWER]]
469 ; CHECK: cmove [[REG_RES2]],[[REG_RES1]] 526 ; CHECK: cmove [[REG_RES2]],[[REG_RES1]]
470 ; CHECK: mov {{.*}},0x0 527 ; CHECK: mov {{.*}},0x0
528 ; ARM32-LABEL: test_cttz_64
529 ; ARM32: rbit
530 ; ARM32: rbit
531 ; ARM32: clz
532 ; ARM32: cmp {{.*}}, #0
533 ; ARM32: add {{.*}}, #32
534 ; ARM32: clzne
535 ; ARM32: mov {{.*}}, #0
471 536
472 define i32 @test_popcount_32(i32 %x) { 537 define i32 @test_popcount_32(i32 %x) {
473 entry: 538 entry:
474 %r = call i32 @llvm.ctpop.i32(i32 %x) 539 %r = call i32 @llvm.ctpop.i32(i32 %x)
475 ret i32 %r 540 ret i32 %r
476 } 541 }
477 ; CHECK-LABEL: test_popcount_32 542 ; CHECK-LABEL: test_popcount_32
478 ; CHECK: call {{.*}} R_{{.*}} __popcountsi2 543 ; CHECK: call {{.*}} R_{{.*}} __popcountsi2
544 ; ARM32-LABEL: test_popcount_32
545 ; ARM32: bl {{.*}} __popcountsi2
479 546
480 define i64 @test_popcount_64(i64 %x) { 547 define i64 @test_popcount_64(i64 %x) {
481 entry: 548 entry:
482 %r = call i64 @llvm.ctpop.i64(i64 %x) 549 %r = call i64 @llvm.ctpop.i64(i64 %x)
483 ret i64 %r 550 ret i64 %r
484 } 551 }
485 ; CHECK-LABEL: test_popcount_64 552 ; CHECK-LABEL: test_popcount_64
486 ; CHECK: call {{.*}} R_{{.*}} __popcountdi2 553 ; CHECK: call {{.*}} R_{{.*}} __popcountdi2
487 ; __popcountdi2 only returns a 32-bit result, so clear the upper bits of 554 ; __popcountdi2 only returns a 32-bit result, so clear the upper bits of
488 ; the return value just in case. 555 ; the return value just in case.
489 ; CHECK: mov {{.*}},0x0 556 ; CHECK: mov {{.*}},0x0
490 557 ; ARM32-LABEL: test_popcount_64
558 ; ARM32: bl {{.*}} __popcountdi2
559 ; ARM32: mov {{.*}}, #0
491 560
492 define i32 @test_popcount_64_ret_i32(i64 %x) { 561 define i32 @test_popcount_64_ret_i32(i64 %x) {
493 entry: 562 entry:
494 %r_i64 = call i64 @llvm.ctpop.i64(i64 %x) 563 %r_i64 = call i64 @llvm.ctpop.i64(i64 %x)
495 %r = trunc i64 %r_i64 to i32 564 %r = trunc i64 %r_i64 to i32
496 ret i32 %r 565 ret i32 %r
497 } 566 }
498 ; If there is a trunc, then the mov {{.*}}, 0 is dead and gets optimized out. 567 ; If there is a trunc, then the mov {{.*}}, 0 is dead and gets optimized out.
499 ; CHECKO2REM-LABEL: test_popcount_64_ret_i32 568 ; CHECKO2REM-LABEL: test_popcount_64_ret_i32
500 ; CHECKO2REM: call {{.*}} R_{{.*}} __popcountdi2 569 ; CHECKO2REM: call {{.*}} R_{{.*}} __popcountdi2
501 ; CHECKO2REM-NOT: mov {{.*}}, 0 570 ; CHECKO2REM-NOT: mov {{.*}}, 0
502 571
503 define void @test_stacksave_noalloca() { 572 define void @test_stacksave_noalloca() {
504 entry: 573 entry:
505 %sp = call i8* @llvm.stacksave() 574 %sp = call i8* @llvm.stacksave()
506 call void @llvm.stackrestore(i8* %sp) 575 call void @llvm.stackrestore(i8* %sp)
507 ret void 576 ret void
508 } 577 }
509 ; CHECK-LABEL: test_stacksave_noalloca 578 ; CHECK-LABEL: test_stacksave_noalloca
510 ; CHECK: mov {{.*}},esp 579 ; CHECK: mov {{.*}},esp
511 ; CHECK: mov esp,{{.*}} 580 ; CHECK: mov esp,{{.*}}
581 ; ARM32-LABEL: test_stacksave_noalloca
582 ; ARM32: mov {{.*}}, sp
583 ; ARM32: mov sp, {{.*}}
512 584
513 declare i32 @foo(i32 %x) 585 declare i32 @foo(i32 %x)
514 586
515 define void @test_stacksave_multiple(i32 %x) { 587 define void @test_stacksave_multiple(i32 %x) {
516 entry: 588 entry:
517 %x_4 = mul i32 %x, 4 589 %x_4 = mul i32 %x, 4
518 %sp1 = call i8* @llvm.stacksave() 590 %sp1 = call i8* @llvm.stacksave()
519 %tmp1 = alloca i8, i32 %x_4, align 4 591 %tmp1 = alloca i8, i32 %x_4, align 4
520 592
521 %sp2 = call i8* @llvm.stacksave() 593 %sp2 = call i8* @llvm.stacksave()
(...skipping 15 matching lines...) Expand all
537 609
538 call void @llvm.stackrestore(i8* %sp1) 610 call void @llvm.stackrestore(i8* %sp1)
539 ret void 611 ret void
540 } 612 }
541 ; CHECK-LABEL: test_stacksave_multiple 613 ; CHECK-LABEL: test_stacksave_multiple
542 ; At least 3 copies of esp, but probably more from having to do the allocas. 614 ; At least 3 copies of esp, but probably more from having to do the allocas.
543 ; CHECK: mov {{.*}},esp 615 ; CHECK: mov {{.*}},esp
544 ; CHECK: mov {{.*}},esp 616 ; CHECK: mov {{.*}},esp
545 ; CHECK: mov {{.*}},esp 617 ; CHECK: mov {{.*}},esp
546 ; CHECK: mov esp,{{.*}} 618 ; CHECK: mov esp,{{.*}}
619 ; ARM32-LABEL: test_stacksave_multiple
620 ; ARM32: mov {{.*}}, sp
621 ; ARM32: mov {{.*}}, sp
622 ; ARM32: mov {{.*}}, sp
623 ; ARM32: mov sp, {{.*}}
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX86BaseImpl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698