| 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 ; TODO(jvoung): fix extra "CALLTARGETS" run. The llvm-objdump symbolizer | |
| 4 ; doesn't know how to symbolize non-section-local functions. | |
| 5 ; The newer LLVM 3.6 one does work, but watch out for other bugs. | |
| 6 | |
| 7 ; RUN: %p2i -i %s --args -O2 --verbose none \ | |
| 8 ; RUN: | FileCheck --check-prefix=CALLTARGETS %s | |
| 9 ; RUN: %p2i -i %s --args -O2 --verbose none -sandbox \ | 3 ; RUN: %p2i -i %s --args -O2 --verbose none -sandbox \ |
| 10 ; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \ | 4 ; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \ |
| 11 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s | 5 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s |
| 12 ; RUN: %p2i -i %s --args -Om1 --verbose none -sandbox \ | 6 ; RUN: %p2i -i %s --args -Om1 --verbose none -sandbox \ |
| 13 ; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \ | 7 ; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \ |
| 14 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s | 8 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s |
| 15 | 9 |
| 16 ; 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 |
| 17 ; share the same "CHECK" prefix). This separate run helps check that | 11 ; share the same "CHECK" prefix). This separate run helps check that |
| 18 ; some code is optimized out. | 12 ; some code is optimized out. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 entry: | 48 entry: |
| 55 %ptr = call i8* @llvm.nacl.read.tp() | 49 %ptr = call i8* @llvm.nacl.read.tp() |
| 56 %__1 = ptrtoint i8* %ptr to i32 | 50 %__1 = ptrtoint i8* %ptr to i32 |
| 57 ret i32 %__1 | 51 ret i32 %__1 |
| 58 } | 52 } |
| 59 ; CHECK-LABEL: test_nacl_read_tp | 53 ; CHECK-LABEL: test_nacl_read_tp |
| 60 ; CHECK: mov e{{.*}}, dword ptr gs:[0] | 54 ; CHECK: mov e{{.*}}, dword ptr gs:[0] |
| 61 ; CHECKO2REM-LABEL: test_nacl_read_tp | 55 ; CHECKO2REM-LABEL: test_nacl_read_tp |
| 62 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] | 56 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] |
| 63 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp | 57 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp |
| 64 ; CHECKO2UNSANDBOXEDREM: call -4 | 58 ; CHECKO2UNSANDBOXEDREM: call __nacl_read_tp |
| 65 ; CALLTARGETS-LABEL: test_nacl_read_tp | |
| 66 ; CALLTARGETS: .long __nacl_read_tp | |
| 67 | 59 |
| 68 define i32 @test_nacl_read_tp_more_addressing() { | 60 define i32 @test_nacl_read_tp_more_addressing() { |
| 69 entry: | 61 entry: |
| 70 %ptr = call i8* @llvm.nacl.read.tp() | 62 %ptr = call i8* @llvm.nacl.read.tp() |
| 71 %__1 = ptrtoint i8* %ptr to i32 | 63 %__1 = ptrtoint i8* %ptr to i32 |
| 72 %x = add i32 %__1, %__1 | 64 %x = add i32 %__1, %__1 |
| 73 %__3 = inttoptr i32 %x to i32* | 65 %__3 = inttoptr i32 %x to i32* |
| 74 %v = load i32* %__3, align 1 | 66 %v = load i32* %__3, align 1 |
| 75 %v_add = add i32 %v, 1 | 67 %v_add = add i32 %v, 1 |
| 76 | 68 |
| 77 %ptr2 = call i8* @llvm.nacl.read.tp() | 69 %ptr2 = call i8* @llvm.nacl.read.tp() |
| 78 %__6 = ptrtoint i8* %ptr2 to i32 | 70 %__6 = ptrtoint i8* %ptr2 to i32 |
| 79 %y = add i32 %__6, 4 | 71 %y = add i32 %__6, 4 |
| 80 %__8 = inttoptr i32 %y to i32* | 72 %__8 = inttoptr i32 %y to i32* |
| 81 %v_add2 = add i32 %v, 4 | 73 %v_add2 = add i32 %v, 4 |
| 82 store i32 %v_add2, i32* %__8, align 1 | 74 store i32 %v_add2, i32* %__8, align 1 |
| 83 ret i32 %v | 75 ret i32 %v |
| 84 } | 76 } |
| 85 ; CHECK-LABEL: test_nacl_read_tp_more_addressing | 77 ; CHECK-LABEL: test_nacl_read_tp_more_addressing |
| 86 ; CHECK: mov e{{.*}}, dword ptr gs:[0] | 78 ; CHECK: mov e{{.*}}, dword ptr gs:[0] |
| 87 ; CHECK: mov e{{.*}}, dword ptr gs:[0] | 79 ; CHECK: mov e{{.*}}, dword ptr gs:[0] |
| 88 ; CHECKO2REM-LABEL: test_nacl_read_tp_more_addressing | 80 ; CHECKO2REM-LABEL: test_nacl_read_tp_more_addressing |
| 89 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] | 81 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] |
| 90 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] | 82 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] |
| 91 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp_more_addressing | 83 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp_more_addressing |
| 92 ; CHECKO2UNSANDBOXEDREM: call -4 | 84 ; CHECKO2UNSANDBOXEDREM: call __nacl_read_tp |
| 93 ; CHECKO2UNSANDBOXEDREM: call -4 | 85 ; CHECKO2UNSANDBOXEDREM: call __nacl_read_tp |
| 94 ; CALLTARGETS-LABEL: test_nacl_read_tp_more_addressing | |
| 95 ; CALLTARGETS: .long __nacl_read_tp | |
| 96 ; CALLTARGETS: .long __nacl_read_tp | |
| 97 | 86 |
| 98 define i32 @test_nacl_read_tp_dead(i32 %a) { | 87 define i32 @test_nacl_read_tp_dead(i32 %a) { |
| 99 entry: | 88 entry: |
| 100 %ptr = call i8* @llvm.nacl.read.tp() | 89 %ptr = call i8* @llvm.nacl.read.tp() |
| 101 ; Not actually using the result of nacl read tp call. | 90 ; Not actually using the result of nacl read tp call. |
| 102 ; In O2 mode this should be DCE'ed. | 91 ; In O2 mode this should be DCE'ed. |
| 103 ret i32 %a | 92 ret i32 %a |
| 104 } | 93 } |
| 105 ; Consider nacl.read.tp side-effect free, so it can be eliminated. | 94 ; Consider nacl.read.tp side-effect free, so it can be eliminated. |
| 106 ; CHECKO2REM-LABEL: test_nacl_read_tp_dead | 95 ; CHECKO2REM-LABEL: test_nacl_read_tp_dead |
| 107 ; CHECKO2REM-NOT: mov e{{.*}}, dword ptr gs:[0] | 96 ; CHECKO2REM-NOT: mov e{{.*}}, dword ptr gs:[0] |
| 108 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp_dead | 97 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp_dead |
| 109 ; CHECKO2UNSANDBOXEDREM-NOT: call -4 | 98 ; CHECKO2UNSANDBOXEDREM-NOT: call __nacl_read_tp |
| 110 ; CALLTARGETS-LABEL: test_nacl_read_tp_dead | |
| 111 ; CALLTARGETS-NOT: call __nacl_read_tp | |
| 112 | 99 |
| 113 define void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) { | 100 define void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) { |
| 114 entry: | 101 entry: |
| 115 %dst = inttoptr i32 %iptr_dst to i8* | 102 %dst = inttoptr i32 %iptr_dst to i8* |
| 116 %src = inttoptr i32 %iptr_src to i8* | 103 %src = inttoptr i32 %iptr_src to i8* |
| 117 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, | 104 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, |
| 118 i32 %len, i32 1, i1 false) | 105 i32 %len, i32 1, i1 false) |
| 119 ret void | 106 ret void |
| 120 } | 107 } |
| 121 ; CHECK-LABEL: test_memcpy | 108 ; CHECK-LABEL: test_memcpy |
| 122 ; CHECK: call -4 | 109 ; CHECK: call memcpy |
| 123 ; CALLTARGETS-LABEL: test_memcpy | |
| 124 ; CALLTARGETS: .long memcpy | |
| 125 ; CHECKO2REM-LABEL: test_memcpy | 110 ; CHECKO2REM-LABEL: test_memcpy |
| 126 ; CHECKO2UNSANDBOXEDREM-LABEL: test_memcpy | 111 ; CHECKO2UNSANDBOXEDREM-LABEL: test_memcpy |
| 127 | 112 |
| 128 ; TODO(jvoung) -- if we want to be clever, we can do this and the memmove, | 113 ; TODO(jvoung) -- if we want to be clever, we can do this and the memmove, |
| 129 ; memset without a function call. | 114 ; memset without a function call. |
| 130 define void @test_memcpy_const_len_align(i32 %iptr_dst, i32 %iptr_src) { | 115 define void @test_memcpy_const_len_align(i32 %iptr_dst, i32 %iptr_src) { |
| 131 entry: | 116 entry: |
| 132 %dst = inttoptr i32 %iptr_dst to i8* | 117 %dst = inttoptr i32 %iptr_dst to i8* |
| 133 %src = inttoptr i32 %iptr_src to i8* | 118 %src = inttoptr i32 %iptr_src to i8* |
| 134 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, | 119 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, |
| 135 i32 8, i32 1, i1 false) | 120 i32 8, i32 1, i1 false) |
| 136 ret void | 121 ret void |
| 137 } | 122 } |
| 138 ; CHECK-LABEL: test_memcpy_const_len_align | 123 ; CHECK-LABEL: test_memcpy_const_len_align |
| 139 ; CHECK: call -4 | 124 ; CHECK: call memcpy |
| 140 ; CALLTARGETS-LABEL: test_memcpy_const_len_align | |
| 141 ; CALLTARGETS: .long memcpy | |
| 142 | 125 |
| 143 define void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) { | 126 define void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) { |
| 144 entry: | 127 entry: |
| 145 %dst = inttoptr i32 %iptr_dst to i8* | 128 %dst = inttoptr i32 %iptr_dst to i8* |
| 146 %src = inttoptr i32 %iptr_src to i8* | 129 %src = inttoptr i32 %iptr_src to i8* |
| 147 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, | 130 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, |
| 148 i32 %len, i32 1, i1 false) | 131 i32 %len, i32 1, i1 false) |
| 149 ret void | 132 ret void |
| 150 } | 133 } |
| 151 ; CHECK-LABEL: test_memmove | 134 ; CHECK-LABEL: test_memmove |
| 152 ; CHECK: call -4 | 135 ; CHECK: call memmove |
| 153 ; CALLTARGETS-LABEL: test_memmove | |
| 154 ; CALLTARGETS: .long memmove | |
| 155 | 136 |
| 156 define void @test_memmove_const_len_align(i32 %iptr_dst, i32 %iptr_src) { | 137 define void @test_memmove_const_len_align(i32 %iptr_dst, i32 %iptr_src) { |
| 157 entry: | 138 entry: |
| 158 %dst = inttoptr i32 %iptr_dst to i8* | 139 %dst = inttoptr i32 %iptr_dst to i8* |
| 159 %src = inttoptr i32 %iptr_src to i8* | 140 %src = inttoptr i32 %iptr_src to i8* |
| 160 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, | 141 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, |
| 161 i32 8, i32 1, i1 false) | 142 i32 8, i32 1, i1 false) |
| 162 ret void | 143 ret void |
| 163 } | 144 } |
| 164 ; CHECK-LABEL: test_memmove_const_len_align | 145 ; CHECK-LABEL: test_memmove_const_len_align |
| 165 ; CHECK: call -4 | 146 ; CHECK: call memmove |
| 166 ; CALLTARGETS-LABEL: test_memmove_const_len_align | |
| 167 ; CALLTARGETS: .long memmove | |
| 168 | 147 |
| 169 define void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) { | 148 define void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) { |
| 170 entry: | 149 entry: |
| 171 %val = trunc i32 %wide_val to i8 | 150 %val = trunc i32 %wide_val to i8 |
| 172 %dst = inttoptr i32 %iptr_dst to i8* | 151 %dst = inttoptr i32 %iptr_dst to i8* |
| 173 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, | 152 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, |
| 174 i32 %len, i32 1, i1 false) | 153 i32 %len, i32 1, i1 false) |
| 175 ret void | 154 ret void |
| 176 } | 155 } |
| 177 ; CHECK-LABEL: test_memset | 156 ; CHECK-LABEL: test_memset |
| 178 ; CHECK: movzx | 157 ; CHECK: movzx |
| 179 ; CHECK: call -4 | 158 ; CHECK: call memset |
| 180 ; CALLTARGETS-LABEL: test_memset | |
| 181 ; CALLTARGETS: .long memset | |
| 182 | 159 |
| 183 define void @test_memset_const_len_align(i32 %iptr_dst, i32 %wide_val) { | 160 define void @test_memset_const_len_align(i32 %iptr_dst, i32 %wide_val) { |
| 184 entry: | 161 entry: |
| 185 %val = trunc i32 %wide_val to i8 | 162 %val = trunc i32 %wide_val to i8 |
| 186 %dst = inttoptr i32 %iptr_dst to i8* | 163 %dst = inttoptr i32 %iptr_dst to i8* |
| 187 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, | 164 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, |
| 188 i32 8, i32 1, i1 false) | 165 i32 8, i32 1, i1 false) |
| 189 ret void | 166 ret void |
| 190 } | 167 } |
| 191 ; CHECK-LABEL: test_memset_const_len_align | 168 ; CHECK-LABEL: test_memset_const_len_align |
| 192 ; CHECK: movzx | 169 ; CHECK: movzx |
| 193 ; CHECK: call -4 | 170 ; CHECK: call memset |
| 194 ; CALLTARGETS-LABEL: test_memset_const_len_align | |
| 195 ; CALLTARGETS: .long memset | |
| 196 | 171 |
| 197 define void @test_memset_const_val(i32 %iptr_dst, i32 %len) { | 172 define void @test_memset_const_val(i32 %iptr_dst, i32 %len) { |
| 198 entry: | 173 entry: |
| 199 %dst = inttoptr i32 %iptr_dst to i8* | 174 %dst = inttoptr i32 %iptr_dst to i8* |
| 200 call void @llvm.memset.p0i8.i32(i8* %dst, i8 0, i32 %len, i32 1, i1 false) | 175 call void @llvm.memset.p0i8.i32(i8* %dst, i8 0, i32 %len, i32 1, i1 false) |
| 201 ret void | 176 ret void |
| 202 } | 177 } |
| 203 ; CHECK-LABEL: test_memset_const_val | 178 ; CHECK-LABEL: test_memset_const_val |
| 204 ; Make sure the argument is legalized (can't movzx reg, 0). | 179 ; Make sure the argument is legalized (can't movzx reg, 0). |
| 205 ; CHECK: movzx {{.*}}, {{[^0]}} | 180 ; CHECK: movzx {{.*}}, {{[^0]}} |
| 206 ; CHECK: call -4 | 181 ; CHECK: call memset |
| 207 ; CALLTARGETS-LABEL: test_memset_const_val | |
| 208 ; CALLTARGETS: .long memset | |
| 209 | 182 |
| 210 | 183 |
| 211 define i32 @test_setjmplongjmp(i32 %iptr_env) { | 184 define i32 @test_setjmplongjmp(i32 %iptr_env) { |
| 212 entry: | 185 entry: |
| 213 %env = inttoptr i32 %iptr_env to i8* | 186 %env = inttoptr i32 %iptr_env to i8* |
| 214 %i = call i32 @llvm.nacl.setjmp(i8* %env) | 187 %i = call i32 @llvm.nacl.setjmp(i8* %env) |
| 215 %r1 = icmp eq i32 %i, 0 | 188 %r1 = icmp eq i32 %i, 0 |
| 216 br i1 %r1, label %Zero, label %NonZero | 189 br i1 %r1, label %Zero, label %NonZero |
| 217 Zero: | 190 Zero: |
| 218 ; Redundant inttoptr, to make --pnacl cast-eliding/re-insertion happy. | 191 ; Redundant inttoptr, to make --pnacl cast-eliding/re-insertion happy. |
| 219 %env2 = inttoptr i32 %iptr_env to i8* | 192 %env2 = inttoptr i32 %iptr_env to i8* |
| 220 call void @llvm.nacl.longjmp(i8* %env2, i32 1) | 193 call void @llvm.nacl.longjmp(i8* %env2, i32 1) |
| 221 ret i32 0 | 194 ret i32 0 |
| 222 NonZero: | 195 NonZero: |
| 223 ret i32 1 | 196 ret i32 1 |
| 224 } | 197 } |
| 225 ; CHECK-LABEL: test_setjmplongjmp | 198 ; CHECK-LABEL: test_setjmplongjmp |
| 226 ; CHECK: call -4 | 199 ; CHECK: call setjmp |
| 227 ; CHECK: call -4 | 200 ; CHECK: call longjmp |
| 228 ; CHECKO2REM-LABEL: test_setjmplongjmp | 201 ; CHECKO2REM-LABEL: test_setjmplongjmp |
| 229 ; CHECKO2REM: call -4 | 202 ; CHECKO2REM: call setjmp |
| 230 ; CHECKO2REM: call -4 | 203 ; CHECKO2REM: call longjmp |
| 231 ; CALLTARGETS-LABEL: test_setjmplongjmp | |
| 232 ; CALLTARGETS: .long setjmp | |
| 233 ; CALLTARGETS: .long longjmp | |
| 234 | 204 |
| 235 define i32 @test_setjmp_unused(i32 %iptr_env, i32 %i_other) { | 205 define i32 @test_setjmp_unused(i32 %iptr_env, i32 %i_other) { |
| 236 entry: | 206 entry: |
| 237 %env = inttoptr i32 %iptr_env to i8* | 207 %env = inttoptr i32 %iptr_env to i8* |
| 238 %i = call i32 @llvm.nacl.setjmp(i8* %env) | 208 %i = call i32 @llvm.nacl.setjmp(i8* %env) |
| 239 ret i32 %i_other | 209 ret i32 %i_other |
| 240 } | 210 } |
| 241 ; Don't consider setjmp side-effect free, so it's not eliminated if | 211 ; Don't consider setjmp side-effect free, so it's not eliminated if |
| 242 ; result unused. | 212 ; result unused. |
| 243 ; CHECKO2REM-LABEL: test_setjmp_unused | 213 ; CHECKO2REM-LABEL: test_setjmp_unused |
| 244 ; CHECKO2REM: call -4 | 214 ; CHECKO2REM: call setjmp |
| 245 ; CALLTARGETS-LABEL: test_setjmp_unused | |
| 246 ; CALLTARGETS: .long setjmp | |
| 247 | 215 |
| 248 define float @test_sqrt_float(float %x, i32 %iptr) { | 216 define float @test_sqrt_float(float %x, i32 %iptr) { |
| 249 entry: | 217 entry: |
| 250 %r = call float @llvm.sqrt.f32(float %x) | 218 %r = call float @llvm.sqrt.f32(float %x) |
| 251 %r2 = call float @llvm.sqrt.f32(float %r) | 219 %r2 = call float @llvm.sqrt.f32(float %r) |
| 252 %r3 = call float @llvm.sqrt.f32(float -0.0) | 220 %r3 = call float @llvm.sqrt.f32(float -0.0) |
| 253 %r4 = fadd float %r2, %r3 | 221 %r4 = fadd float %r2, %r3 |
| 254 ret float %r4 | 222 ret float %r4 |
| 255 } | 223 } |
| 256 ; CHECK-LABEL: test_sqrt_float | 224 ; CHECK-LABEL: test_sqrt_float |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 ; CHECK: test [[REG_LOWER]], [[REG_LOWER]] | 410 ; CHECK: test [[REG_LOWER]], [[REG_LOWER]] |
| 443 ; CHECK: cmove [[REG_RES2]], [[REG_RES1]] | 411 ; CHECK: cmove [[REG_RES2]], [[REG_RES1]] |
| 444 ; CHECK: mov {{.*}}, 0 | 412 ; CHECK: mov {{.*}}, 0 |
| 445 | 413 |
| 446 define i32 @test_popcount_32(i32 %x) { | 414 define i32 @test_popcount_32(i32 %x) { |
| 447 entry: | 415 entry: |
| 448 %r = call i32 @llvm.ctpop.i32(i32 %x) | 416 %r = call i32 @llvm.ctpop.i32(i32 %x) |
| 449 ret i32 %r | 417 ret i32 %r |
| 450 } | 418 } |
| 451 ; CHECK-LABEL: test_popcount_32 | 419 ; CHECK-LABEL: test_popcount_32 |
| 452 ; CHECK: call -4 | 420 ; CHECK: call __popcountsi2 |
| 453 ; CALLTARGETS-LABEL: test_popcount_32 | |
| 454 ; CALLTARGETS: .long __popcountsi2 | |
| 455 | 421 |
| 456 define i64 @test_popcount_64(i64 %x) { | 422 define i64 @test_popcount_64(i64 %x) { |
| 457 entry: | 423 entry: |
| 458 %r = call i64 @llvm.ctpop.i64(i64 %x) | 424 %r = call i64 @llvm.ctpop.i64(i64 %x) |
| 459 ret i64 %r | 425 ret i64 %r |
| 460 } | 426 } |
| 461 ; CHECK-LABEL: test_popcount_64 | 427 ; CHECK-LABEL: test_popcount_64 |
| 462 ; CHECK: call -4 | 428 ; CHECK: call __popcountdi2 |
| 463 ; __popcountdi2 only returns a 32-bit result, so clear the upper bits of | 429 ; __popcountdi2 only returns a 32-bit result, so clear the upper bits of |
| 464 ; the return value just in case. | 430 ; the return value just in case. |
| 465 ; CHECK: mov {{.*}}, 0 | 431 ; CHECK: mov {{.*}}, 0 |
| 466 ; CALLTARGETS-LABEL: test_popcount_64 | |
| 467 ; CALLTARGETS: .long __popcountdi2 | |
| 468 | 432 |
| 469 | 433 |
| 470 define i32 @test_popcount_64_ret_i32(i64 %x) { | 434 define i32 @test_popcount_64_ret_i32(i64 %x) { |
| 471 entry: | 435 entry: |
| 472 %r_i64 = call i64 @llvm.ctpop.i64(i64 %x) | 436 %r_i64 = call i64 @llvm.ctpop.i64(i64 %x) |
| 473 %r = trunc i64 %r_i64 to i32 | 437 %r = trunc i64 %r_i64 to i32 |
| 474 ret i32 %r | 438 ret i32 %r |
| 475 } | 439 } |
| 476 ; If there is a trunc, then the mov {{.*}}, 0 is dead and gets optimized out. | 440 ; If there is a trunc, then the mov {{.*}}, 0 is dead and gets optimized out. |
| 477 ; CHECKO2REM-LABEL: test_popcount_64_ret_i32 | 441 ; CHECKO2REM-LABEL: test_popcount_64_ret_i32 |
| 478 ; CHECKO2REM: call -4 | 442 ; CHECKO2REM: call __popcountdi2 |
| 479 ; CHECKO2REM-NOT: mov {{.*}}, 0 | 443 ; CHECKO2REM-NOT: mov {{.*}}, 0 |
| 480 ; CALLTARGETS-LABEL: test_popcount_64_ret_i32 | |
| 481 ; CALLTARGETS: .long __popcountdi2 | |
| 482 | 444 |
| 483 define void @test_stacksave_noalloca() { | 445 define void @test_stacksave_noalloca() { |
| 484 entry: | 446 entry: |
| 485 %sp = call i8* @llvm.stacksave() | 447 %sp = call i8* @llvm.stacksave() |
| 486 call void @llvm.stackrestore(i8* %sp) | 448 call void @llvm.stackrestore(i8* %sp) |
| 487 ret void | 449 ret void |
| 488 } | 450 } |
| 489 ; CHECK-LABEL: test_stacksave_noalloca | 451 ; CHECK-LABEL: test_stacksave_noalloca |
| 490 ; CHECK: mov {{.*}}, esp | 452 ; CHECK: mov {{.*}}, esp |
| 491 ; CHECK: mov esp, {{.*}} | 453 ; CHECK: mov esp, {{.*}} |
| (...skipping 25 matching lines...) Expand all Loading... |
| 517 | 479 |
| 518 call void @llvm.stackrestore(i8* %sp1) | 480 call void @llvm.stackrestore(i8* %sp1) |
| 519 ret void | 481 ret void |
| 520 } | 482 } |
| 521 ; CHECK-LABEL: test_stacksave_multiple | 483 ; CHECK-LABEL: test_stacksave_multiple |
| 522 ; At least 3 copies of esp, but probably more from having to do the allocas. | 484 ; At least 3 copies of esp, but probably more from having to do the allocas. |
| 523 ; CHECK: mov {{.*}}, esp | 485 ; CHECK: mov {{.*}}, esp |
| 524 ; CHECK: mov {{.*}}, esp | 486 ; CHECK: mov {{.*}}, esp |
| 525 ; CHECK: mov {{.*}}, esp | 487 ; CHECK: mov {{.*}}, esp |
| 526 ; CHECK: mov esp, {{.*}} | 488 ; CHECK: mov esp, {{.*}} |
| OLD | NEW |