| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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, {{.*}} |
| OLD | NEW |