| 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: %llvm2ice -O2 --verbose none -sandbox %s | FileCheck %s | 3 ; TODO(jvoung): fix extra "CALLTARGETS" run. The llvm-objdump symbolizer |
| 4 ; RUN: %llvm2ice -Om1 --verbose none -sandbox %s | FileCheck %s | 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: %llvm2ice -O2 --verbose none %s \ |
| 8 ; RUN: | FileCheck --check-prefix=CALLTARGETS %s |
| 9 ; RUN: %llvm2ice -O2 --verbose none -sandbox %s \ |
| 10 ; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \ |
| 11 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s |
| 12 ; RUN: %llvm2ice -Om1 --verbose none -sandbox %s \ |
| 13 ; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \ |
| 14 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s |
| 5 | 15 |
| 6 ; Do another run w/ O2 and a different check-prefix (otherwise O2 and Om1 | 16 ; Do another run w/ O2 and a different check-prefix (otherwise O2 and Om1 |
| 7 ; share the same "CHECK" prefix). This separate run helps check that | 17 ; share the same "CHECK" prefix). This separate run helps check that |
| 8 ; some code is optimized out. | 18 ; some code is optimized out. |
| 9 ; RUN: %llvm2ice -O2 --verbose none -sandbox %s \ | 19 ; RUN: %llvm2ice -O2 --verbose none -sandbox %s \ |
| 10 ; RUN: | FileCheck %s --check-prefix=CHECKO2REM | 20 ; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \ |
| 21 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \ |
| 22 ; RUN: | FileCheck --check-prefix=CHECKO2REM %s |
| 11 | 23 |
| 12 ; Do O2 runs without -sandbox to make sure llvm.nacl.read.tp gets | 24 ; Do O2 runs without -sandbox to make sure llvm.nacl.read.tp gets |
| 13 ; lowered to __nacl_read_tp instead of gs:[0x0]. | 25 ; lowered to __nacl_read_tp instead of gs:[0x0]. |
| 26 ; We also know that because it's O2, it'll have the O2REM optimizations. |
| 14 ; RUN: %llvm2ice -O2 --verbose none %s \ | 27 ; RUN: %llvm2ice -O2 --verbose none %s \ |
| 15 ; RUN: | FileCheck --check-prefix=CHECKO2UNSANDBOXED %s | 28 ; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \ |
| 16 ; RUN: %llvm2ice -O2 --verbose none %s \ | 29 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \ |
| 17 ; RUN: | FileCheck --check-prefix=CHECKO2UNSANDBOXEDREM %s | 30 ; RUN: | FileCheck --check-prefix=CHECKO2UNSANDBOXEDREM %s |
| 18 | 31 |
| 19 ; RUN: %llvm2ice -O2 --verbose none %s \ | |
| 20 ; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj | |
| 21 ; RUN: %llvm2ice -Om1 --verbose none %s \ | |
| 22 ; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj | |
| 23 ; RUN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s | 32 ; RUN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s |
| 24 ; RUN: %llvm2iceinsts %s | %szdiff %s | FileCheck --check-prefix=DUMP %s | 33 ; RUN: %llvm2iceinsts %s | %szdiff %s | FileCheck --check-prefix=DUMP %s |
| 25 ; RUN: %llvm2iceinsts --pnacl %s | %szdiff %s \ | 34 ; RUN: %llvm2iceinsts --pnacl %s | %szdiff %s \ |
| 26 ; RUN: | FileCheck --check-prefix=DUMP %s | 35 ; RUN: | FileCheck --check-prefix=DUMP %s |
| 27 | 36 |
| 28 declare i8* @llvm.nacl.read.tp() | 37 declare i8* @llvm.nacl.read.tp() |
| 29 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) | 38 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) |
| 30 declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) | 39 declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) |
| 31 declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1) | 40 declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1) |
| 32 declare void @llvm.nacl.longjmp(i8*, i32) | 41 declare void @llvm.nacl.longjmp(i8*, i32) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 49 define i32 @test_nacl_read_tp() { | 58 define i32 @test_nacl_read_tp() { |
| 50 entry: | 59 entry: |
| 51 %ptr = call i8* @llvm.nacl.read.tp() | 60 %ptr = call i8* @llvm.nacl.read.tp() |
| 52 %__1 = ptrtoint i8* %ptr to i32 | 61 %__1 = ptrtoint i8* %ptr to i32 |
| 53 ret i32 %__1 | 62 ret i32 %__1 |
| 54 } | 63 } |
| 55 ; CHECK-LABEL: test_nacl_read_tp | 64 ; CHECK-LABEL: test_nacl_read_tp |
| 56 ; CHECK: mov e{{.*}}, dword ptr gs:[0] | 65 ; CHECK: mov e{{.*}}, dword ptr gs:[0] |
| 57 ; CHECKO2REM-LABEL: test_nacl_read_tp | 66 ; CHECKO2REM-LABEL: test_nacl_read_tp |
| 58 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] | 67 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] |
| 59 ; CHECKO2UNSANDBOXED-LABEL: test_nacl_read_tp | |
| 60 ; CHECKO2UNSANDBOXED: call __nacl_read_tp | |
| 61 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp | 68 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp |
| 62 ; CHECKO2UNSANDBOXEDREM: call __nacl_read_tp | 69 ; CHECKO2UNSANDBOXEDREM: call -4 |
| 70 ; CALLTARGETS-LABEL: test_nacl_read_tp |
| 71 ; CALLTARGETS: call __nacl_read_tp |
| 63 | 72 |
| 64 define i32 @test_nacl_read_tp_more_addressing() { | 73 define i32 @test_nacl_read_tp_more_addressing() { |
| 65 entry: | 74 entry: |
| 66 %ptr = call i8* @llvm.nacl.read.tp() | 75 %ptr = call i8* @llvm.nacl.read.tp() |
| 67 %__1 = ptrtoint i8* %ptr to i32 | 76 %__1 = ptrtoint i8* %ptr to i32 |
| 68 %x = add i32 %__1, %__1 | 77 %x = add i32 %__1, %__1 |
| 69 %__3 = inttoptr i32 %x to i32* | 78 %__3 = inttoptr i32 %x to i32* |
| 70 %v = load i32* %__3, align 1 | 79 %v = load i32* %__3, align 1 |
| 71 %ptr2 = call i8* @llvm.nacl.read.tp() | 80 %ptr2 = call i8* @llvm.nacl.read.tp() |
| 72 %__6 = ptrtoint i8* %ptr2 to i32 | 81 %__6 = ptrtoint i8* %ptr2 to i32 |
| 73 %y = add i32 %__6, 4 | 82 %y = add i32 %__6, 4 |
| 74 %__8 = inttoptr i32 %y to i32* | 83 %__8 = inttoptr i32 %y to i32* |
| 75 store i32 %v, i32* %__8, align 1 | 84 store i32 %v, i32* %__8, align 1 |
| 76 ret i32 %v | 85 ret i32 %v |
| 77 } | 86 } |
| 78 ; CHECK-LABEL: test_nacl_read_tp_more_addressing | 87 ; CHECK-LABEL: test_nacl_read_tp_more_addressing |
| 79 ; CHECK: mov e{{.*}}, dword ptr gs:[0] | 88 ; CHECK: mov e{{.*}}, dword ptr gs:[0] |
| 80 ; CHECK: mov e{{.*}}, dword ptr gs:[0] | 89 ; CHECK: mov e{{.*}}, dword ptr gs:[0] |
| 81 ; CHECKO2REM-LABEL: test_nacl_read_tp_more_addressing | 90 ; CHECKO2REM-LABEL: test_nacl_read_tp_more_addressing |
| 82 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] | 91 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] |
| 83 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] | 92 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0] |
| 84 ; CHECKO2UNSANDBOXED-LABEL: test_nacl_read_tp_more_addressing | |
| 85 ; CHECKO2UNSANDBOXED: call __nacl_read_tp | |
| 86 ; CHECKO2UNSANDBOXED: call __nacl_read_tp | |
| 87 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp_more_addressing | 93 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp_more_addressing |
| 88 ; CHECKO2UNSANDBOXEDREM: call __nacl_read_tp | 94 ; CHECKO2UNSANDBOXEDREM: call -4 |
| 89 ; CHECKO2UNSANDBOXEDREM: call __nacl_read_tp | 95 ; CHECKO2UNSANDBOXEDREM: call -4 |
| 96 ; CALLTARGETS-LABEL: test_nacl_read_tp_more_addressing |
| 97 ; CALLTARGETS: call __nacl_read_tp |
| 98 ; CALLTARGETS: call __nacl_read_tp |
| 90 | 99 |
| 91 define i32 @test_nacl_read_tp_dead(i32 %a) { | 100 define i32 @test_nacl_read_tp_dead(i32 %a) { |
| 92 entry: | 101 entry: |
| 93 %ptr = call i8* @llvm.nacl.read.tp() | 102 %ptr = call i8* @llvm.nacl.read.tp() |
| 94 ; Not actually using the result of nacl read tp call. | 103 ; Not actually using the result of nacl read tp call. |
| 95 ; In O2 mode this should be DCE'ed. | 104 ; In O2 mode this should be DCE'ed. |
| 96 ret i32 %a | 105 ret i32 %a |
| 97 } | 106 } |
| 98 ; Consider nacl.read.tp side-effect free, so it can be eliminated. | 107 ; Consider nacl.read.tp side-effect free, so it can be eliminated. |
| 99 ; CHECKO2REM-LABEL: test_nacl_read_tp_dead | 108 ; CHECKO2REM-LABEL: test_nacl_read_tp_dead |
| 100 ; CHECKO2REM-NOT: mov e{{.*}}, dword ptr gs:[0] | 109 ; CHECKO2REM-NOT: mov e{{.*}}, dword ptr gs:[0] |
| 101 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp_dead | 110 ; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp_dead |
| 102 ; CHECKO2UNSANDBOXEDREM-NOT: call __nacl_read_tp | 111 ; CHECKO2UNSANDBOXEDREM-NOT: call -4 |
| 112 ; CALLTARGETS-LABEL: test_nacl_read_tp_dead |
| 113 ; CALLTARGETS-NOT: call __nacl_read_tp |
| 103 | 114 |
| 104 define void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) { | 115 define void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) { |
| 105 entry: | 116 entry: |
| 106 %dst = inttoptr i32 %iptr_dst to i8* | 117 %dst = inttoptr i32 %iptr_dst to i8* |
| 107 %src = inttoptr i32 %iptr_src to i8* | 118 %src = inttoptr i32 %iptr_src to i8* |
| 108 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, | 119 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, |
| 109 i32 %len, i32 1, i1 0) | 120 i32 %len, i32 1, i1 0) |
| 110 ret void | 121 ret void |
| 111 } | 122 } |
| 112 ; CHECK-LABEL: test_memcpy | 123 ; CHECK-LABEL: test_memcpy |
| 113 ; CHECK: call memcpy | 124 ; CHECK: call -4 |
| 125 ; CALLTARGETS-LABEL: test_memcpy |
| 126 ; CALLTARGETS: call memcpy |
| 114 ; CHECKO2REM-LABEL: test_memcpy | 127 ; CHECKO2REM-LABEL: test_memcpy |
| 115 ; CHECKO2UNSANDBOXEDREM-LABEL: test_memcpy | 128 ; CHECKO2UNSANDBOXEDREM-LABEL: test_memcpy |
| 116 | 129 |
| 117 ; TODO(jvoung) -- if we want to be clever, we can do this and the memmove, | 130 ; TODO(jvoung) -- if we want to be clever, we can do this and the memmove, |
| 118 ; memset without a function call. | 131 ; memset without a function call. |
| 119 define void @test_memcpy_const_len_align(i32 %iptr_dst, i32 %iptr_src) { | 132 define void @test_memcpy_const_len_align(i32 %iptr_dst, i32 %iptr_src) { |
| 120 entry: | 133 entry: |
| 121 %dst = inttoptr i32 %iptr_dst to i8* | 134 %dst = inttoptr i32 %iptr_dst to i8* |
| 122 %src = inttoptr i32 %iptr_src to i8* | 135 %src = inttoptr i32 %iptr_src to i8* |
| 123 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, | 136 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, |
| 124 i32 8, i32 1, i1 0) | 137 i32 8, i32 1, i1 0) |
| 125 ret void | 138 ret void |
| 126 } | 139 } |
| 127 ; CHECK-LABEL: test_memcpy_const_len_align | 140 ; CHECK-LABEL: test_memcpy_const_len_align |
| 128 ; CHECK: call memcpy | 141 ; CHECK: call -4 |
| 142 ; CALLTARGETS-LABEL: test_memcpy_const_len_align |
| 143 ; CALLTARGETS: call memcpy |
| 129 | 144 |
| 130 define void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) { | 145 define void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) { |
| 131 entry: | 146 entry: |
| 132 %dst = inttoptr i32 %iptr_dst to i8* | 147 %dst = inttoptr i32 %iptr_dst to i8* |
| 133 %src = inttoptr i32 %iptr_src to i8* | 148 %src = inttoptr i32 %iptr_src to i8* |
| 134 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, | 149 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, |
| 135 i32 %len, i32 1, i1 0) | 150 i32 %len, i32 1, i1 0) |
| 136 ret void | 151 ret void |
| 137 } | 152 } |
| 138 ; CHECK-LABEL: test_memmove | 153 ; CHECK-LABEL: test_memmove |
| 139 ; CHECK: call memmove | 154 ; CHECK: call -4 |
| 155 ; CALLTARGETS-LABEL: test_memmove |
| 156 ; CALLTARGETS: call memmove |
| 140 | 157 |
| 141 define void @test_memmove_const_len_align(i32 %iptr_dst, i32 %iptr_src) { | 158 define void @test_memmove_const_len_align(i32 %iptr_dst, i32 %iptr_src) { |
| 142 entry: | 159 entry: |
| 143 %dst = inttoptr i32 %iptr_dst to i8* | 160 %dst = inttoptr i32 %iptr_dst to i8* |
| 144 %src = inttoptr i32 %iptr_src to i8* | 161 %src = inttoptr i32 %iptr_src to i8* |
| 145 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, | 162 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, |
| 146 i32 8, i32 1, i1 0) | 163 i32 8, i32 1, i1 0) |
| 147 ret void | 164 ret void |
| 148 } | 165 } |
| 149 ; CHECK-LABEL: test_memmove_const_len_align | 166 ; CHECK-LABEL: test_memmove_const_len_align |
| 150 ; CHECK: call memmove | 167 ; CHECK: call -4 |
| 168 ; CALLTARGETS-LABEL: test_memmove_const_len_align |
| 169 ; CALLTARGETS: call memmove |
| 151 | 170 |
| 152 define void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) { | 171 define void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) { |
| 153 entry: | 172 entry: |
| 154 %val = trunc i32 %wide_val to i8 | 173 %val = trunc i32 %wide_val to i8 |
| 155 %dst = inttoptr i32 %iptr_dst to i8* | 174 %dst = inttoptr i32 %iptr_dst to i8* |
| 156 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, | 175 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, |
| 157 i32 %len, i32 1, i1 0) | 176 i32 %len, i32 1, i1 0) |
| 158 ret void | 177 ret void |
| 159 } | 178 } |
| 160 ; CHECK-LABEL: test_memset | 179 ; CHECK-LABEL: test_memset |
| 161 ; CHECK: movzx | 180 ; CHECK: movzx |
| 162 ; CHECK: call memset | 181 ; CHECK: call -4 |
| 182 ; CALLTARGETS-LABEL: test_memset |
| 183 ; CALLTARGETS: call memset |
| 163 | 184 |
| 164 define void @test_memset_const_len_align(i32 %iptr_dst, i32 %wide_val) { | 185 define void @test_memset_const_len_align(i32 %iptr_dst, i32 %wide_val) { |
| 165 entry: | 186 entry: |
| 166 %val = trunc i32 %wide_val to i8 | 187 %val = trunc i32 %wide_val to i8 |
| 167 %dst = inttoptr i32 %iptr_dst to i8* | 188 %dst = inttoptr i32 %iptr_dst to i8* |
| 168 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, | 189 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, |
| 169 i32 8, i32 1, i1 0) | 190 i32 8, i32 1, i1 0) |
| 170 ret void | 191 ret void |
| 171 } | 192 } |
| 172 ; CHECK-LABEL: test_memset_const_len_align | 193 ; CHECK-LABEL: test_memset_const_len_align |
| 173 ; CHECK: movzx | 194 ; CHECK: movzx |
| 174 ; CHECK: call memset | 195 ; CHECK: call -4 |
| 196 ; CALLTARGETS-LABEL: test_memset_const_len_align |
| 197 ; CALLTARGETS: call memset |
| 175 | 198 |
| 176 define void @test_memset_const_val(i32 %iptr_dst, i32 %len) { | 199 define void @test_memset_const_val(i32 %iptr_dst, i32 %len) { |
| 177 entry: | 200 entry: |
| 178 %dst = inttoptr i32 %iptr_dst to i8* | 201 %dst = inttoptr i32 %iptr_dst to i8* |
| 179 call void @llvm.memset.p0i8.i32(i8* %dst, i8 0, i32 %len, i32 1, i1 0) | 202 call void @llvm.memset.p0i8.i32(i8* %dst, i8 0, i32 %len, i32 1, i1 0) |
| 180 ret void | 203 ret void |
| 181 } | 204 } |
| 182 ; CHECK-LABEL: test_memset_const_val | 205 ; CHECK-LABEL: test_memset_const_val |
| 183 ; Make sure the argument is legalized (can't movzx reg, 0). | 206 ; Make sure the argument is legalized (can't movzx reg, 0). |
| 184 ; CHECK: movzx {{.*}}, {{[^0]}} | 207 ; CHECK: movzx {{.*}}, {{[^0]}} |
| 185 ; CHECK: call memset | 208 ; CHECK: call -4 |
| 209 ; CALLTARGETS-LABEL: test_memset_const_val |
| 210 ; CALLTARGETS: call memset |
| 211 |
| 186 | 212 |
| 187 define i32 @test_setjmplongjmp(i32 %iptr_env) { | 213 define i32 @test_setjmplongjmp(i32 %iptr_env) { |
| 188 entry: | 214 entry: |
| 189 %env = inttoptr i32 %iptr_env to i8* | 215 %env = inttoptr i32 %iptr_env to i8* |
| 190 %i = call i32 @llvm.nacl.setjmp(i8* %env) | 216 %i = call i32 @llvm.nacl.setjmp(i8* %env) |
| 191 %r1 = icmp eq i32 %i, 0 | 217 %r1 = icmp eq i32 %i, 0 |
| 192 br i1 %r1, label %Zero, label %NonZero | 218 br i1 %r1, label %Zero, label %NonZero |
| 193 Zero: | 219 Zero: |
| 194 ; Redundant inttoptr, to make --pnacl cast-eliding/re-insertion happy. | 220 ; Redundant inttoptr, to make --pnacl cast-eliding/re-insertion happy. |
| 195 %env2 = inttoptr i32 %iptr_env to i8* | 221 %env2 = inttoptr i32 %iptr_env to i8* |
| 196 call void @llvm.nacl.longjmp(i8* %env2, i32 1) | 222 call void @llvm.nacl.longjmp(i8* %env2, i32 1) |
| 197 ret i32 0 | 223 ret i32 0 |
| 198 NonZero: | 224 NonZero: |
| 199 ret i32 1 | 225 ret i32 1 |
| 200 } | 226 } |
| 201 ; CHECK-LABEL: test_setjmplongjmp | 227 ; CHECK-LABEL: test_setjmplongjmp |
| 202 ; CHECK: call setjmp | 228 ; CHECK: call -4 |
| 203 ; CHECK: call longjmp | 229 ; CHECK: call -4 |
| 204 ; CHECKO2REM-LABEL: test_setjmplongjmp | 230 ; CHECKO2REM-LABEL: test_setjmplongjmp |
| 205 ; CHECKO2REM: call setjmp | 231 ; CHECKO2REM: call -4 |
| 206 ; CHECKO2REM: call longjmp | 232 ; CHECKO2REM: call -4 |
| 233 ; CALLTARGETS-LABEL: test_setjmplongjmp |
| 234 ; CALLTARGETS: call setjmp |
| 235 ; CALLTARGETS: call longjmp |
| 207 | 236 |
| 208 define i32 @test_setjmp_unused(i32 %iptr_env, i32 %i_other) { | 237 define i32 @test_setjmp_unused(i32 %iptr_env, i32 %i_other) { |
| 209 entry: | 238 entry: |
| 210 %env = inttoptr i32 %iptr_env to i8* | 239 %env = inttoptr i32 %iptr_env to i8* |
| 211 %i = call i32 @llvm.nacl.setjmp(i8* %env) | 240 %i = call i32 @llvm.nacl.setjmp(i8* %env) |
| 212 ret i32 %i_other | 241 ret i32 %i_other |
| 213 } | 242 } |
| 214 ; Don't consider setjmp side-effect free, so it's not eliminated if | 243 ; Don't consider setjmp side-effect free, so it's not eliminated if |
| 215 ; result unused. | 244 ; result unused. |
| 216 ; CHECKO2REM-LABEL: test_setjmp_unused | 245 ; CHECKO2REM-LABEL: test_setjmp_unused |
| 217 ; CHECKO2REM: call setjmp | 246 ; CHECKO2REM: call -4 |
| 247 ; CALLTARGETS-LABEL: test_setjmp_unused |
| 248 ; CALLTARGETS: call setjmp |
| 218 | 249 |
| 219 define float @test_sqrt_float(float %x, i32 %iptr) { | 250 define float @test_sqrt_float(float %x, i32 %iptr) { |
| 220 entry: | 251 entry: |
| 221 %r = call float @llvm.sqrt.f32(float %x) | 252 %r = call float @llvm.sqrt.f32(float %x) |
| 222 %r2 = call float @llvm.sqrt.f32(float %r) | 253 %r2 = call float @llvm.sqrt.f32(float %r) |
| 223 %r3 = call float @llvm.sqrt.f32(float -0.0) | 254 %r3 = call float @llvm.sqrt.f32(float -0.0) |
| 224 %r4 = fadd float %r2, %r3 | 255 %r4 = fadd float %r2, %r3 |
| 225 br label %next | 256 ret float %r4 |
| 226 | |
| 227 next: | |
| 228 %__6 = inttoptr i32 %iptr to float* | |
| 229 %y = load float* %__6, align 4 | |
| 230 %r5 = call float @llvm.sqrt.f32(float %y) | |
| 231 %r6 = fadd float %r4, %r5 | |
| 232 ret float %r6 | |
| 233 } | 257 } |
| 234 ; CHECK-LABEL: test_sqrt_float | 258 ; CHECK-LABEL: test_sqrt_float |
| 235 ; CHECK: sqrtss xmm{{.*}} | 259 ; CHECK: sqrtss xmm{{.*}} |
| 236 ; CHECK: sqrtss xmm{{.*}} | 260 ; CHECK: sqrtss xmm{{.*}} |
| 237 ; CHECK: sqrtss xmm{{.*}}, dword ptr | 261 ; CHECK: sqrtss xmm{{.*}}, dword ptr |
| 238 ; CHECK-LABEL: .L{{.*}}next | 262 |
| 263 define float @test_sqrt_float_mergeable_load(float %x, i32 %iptr) { |
| 264 entry: |
| 265 %__2 = inttoptr i32 %iptr to float* |
| 266 %y = load float* %__2, align 4 |
| 267 %r5 = call float @llvm.sqrt.f32(float %y) |
| 268 %r6 = fadd float %x, %r5 |
| 269 ret float %r6 |
| 270 } |
| 271 ; CHECK-LABEL: test_sqrt_float_mergeable_load |
| 239 ; We could fold the load and the sqrt into one operation, but the | 272 ; We could fold the load and the sqrt into one operation, but the |
| 240 ; current folding only handles load + arithmetic op. The sqrt inst | 273 ; current folding only handles load + arithmetic op. The sqrt inst |
| 241 ; is considered an intrinsic call and not an arithmetic op. | 274 ; is considered an intrinsic call and not an arithmetic op. |
| 242 ; CHECK: sqrtss xmm{{.*}} | 275 ; CHECK: sqrtss xmm{{.*}} |
| 243 | 276 |
| 244 define double @test_sqrt_double(double %x, i32 %iptr) { | 277 define double @test_sqrt_double(double %x, i32 %iptr) { |
| 245 entry: | 278 entry: |
| 246 %r = call double @llvm.sqrt.f64(double %x) | 279 %r = call double @llvm.sqrt.f64(double %x) |
| 247 %r2 = call double @llvm.sqrt.f64(double %r) | 280 %r2 = call double @llvm.sqrt.f64(double %r) |
| 248 %r3 = call double @llvm.sqrt.f64(double -0.0) | 281 %r3 = call double @llvm.sqrt.f64(double -0.0) |
| 249 %r4 = fadd double %r2, %r3 | 282 %r4 = fadd double %r2, %r3 |
| 250 br label %next | 283 ret double %r4 |
| 251 | |
| 252 next: | |
| 253 %__6 = inttoptr i32 %iptr to double* | |
| 254 %y = load double* %__6, align 8 | |
| 255 %r5 = call double @llvm.sqrt.f64(double %y) | |
| 256 %r6 = fadd double %r4, %r5 | |
| 257 ret double %r6 | |
| 258 } | 284 } |
| 259 ; CHECK-LABEL: test_sqrt_double | 285 ; CHECK-LABEL: test_sqrt_double |
| 260 ; CHECK: sqrtsd xmm{{.*}} | 286 ; CHECK: sqrtsd xmm{{.*}} |
| 261 ; CHECK: sqrtsd xmm{{.*}} | 287 ; CHECK: sqrtsd xmm{{.*}} |
| 262 ; CHECK: sqrtsd xmm{{.*}}, qword ptr | 288 ; CHECK: sqrtsd xmm{{.*}}, qword ptr |
| 263 ; CHECK-LABEL: .L{{.*}}next | 289 |
| 290 define double @test_sqrt_double_mergeable_load(double %x, i32 %iptr) { |
| 291 entry: |
| 292 %__2 = inttoptr i32 %iptr to double* |
| 293 %y = load double* %__2, align 8 |
| 294 %r5 = call double @llvm.sqrt.f64(double %y) |
| 295 %r6 = fadd double %x, %r5 |
| 296 ret double %r6 |
| 297 } |
| 298 ; CHECK-LABEL: test_sqrt_double_mergeable_load |
| 264 ; CHECK: sqrtsd xmm{{.*}} | 299 ; CHECK: sqrtsd xmm{{.*}} |
| 265 | 300 |
| 266 define float @test_sqrt_ignored(float %x, double %y) { | 301 define float @test_sqrt_ignored(float %x, double %y) { |
| 267 entry: | 302 entry: |
| 268 %ignored1 = call float @llvm.sqrt.f32(float %x) | 303 %ignored1 = call float @llvm.sqrt.f32(float %x) |
| 269 %ignored2 = call double @llvm.sqrt.f64(double %y) | 304 %ignored2 = call double @llvm.sqrt.f64(double %y) |
| 270 ret float 0.0 | 305 ret float 0.0 |
| 271 } | 306 } |
| 272 ; CHECKO2REM-LABEL: test_sqrt_ignored | 307 ; CHECKO2REM-LABEL: test_sqrt_ignored |
| 273 ; CHECKO2REM-NOT: sqrtss | 308 ; CHECKO2REM-NOT: sqrtss |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 ; CHECK: test [[REG_LOWER]], [[REG_LOWER]] | 442 ; CHECK: test [[REG_LOWER]], [[REG_LOWER]] |
| 408 ; CHECK: cmove [[REG_RES2]], [[REG_RES1]] | 443 ; CHECK: cmove [[REG_RES2]], [[REG_RES1]] |
| 409 ; CHECK: mov {{.*}}, 0 | 444 ; CHECK: mov {{.*}}, 0 |
| 410 | 445 |
| 411 define i32 @test_popcount_32(i32 %x) { | 446 define i32 @test_popcount_32(i32 %x) { |
| 412 entry: | 447 entry: |
| 413 %r = call i32 @llvm.ctpop.i32(i32 %x) | 448 %r = call i32 @llvm.ctpop.i32(i32 %x) |
| 414 ret i32 %r | 449 ret i32 %r |
| 415 } | 450 } |
| 416 ; CHECK-LABEL: test_popcount_32 | 451 ; CHECK-LABEL: test_popcount_32 |
| 417 ; CHECK: call __popcountsi2 | 452 ; CHECK: call -4 |
| 453 ; CALLTARGETS-LABEL: test_popcount_32 |
| 454 ; CALLTARGETS: call __popcountsi2 |
| 418 | 455 |
| 419 define i64 @test_popcount_64(i64 %x) { | 456 define i64 @test_popcount_64(i64 %x) { |
| 420 entry: | 457 entry: |
| 421 %r = call i64 @llvm.ctpop.i64(i64 %x) | 458 %r = call i64 @llvm.ctpop.i64(i64 %x) |
| 422 ret i64 %r | 459 ret i64 %r |
| 423 } | 460 } |
| 424 ; CHECK-LABEL: test_popcount_64 | 461 ; CHECK-LABEL: test_popcount_64 |
| 425 ; CHECK: call __popcountdi2 | 462 ; CHECK: call -4 |
| 426 ; __popcountdi2 only returns a 32-bit result, so clear the upper bits of | 463 ; __popcountdi2 only returns a 32-bit result, so clear the upper bits of |
| 427 ; the return value just in case. | 464 ; the return value just in case. |
| 428 ; CHECK: mov {{.*}}, 0 | 465 ; CHECK: mov {{.*}}, 0 |
| 466 ; CALLTARGETS-LABEL: test_popcount_64 |
| 467 ; CALLTARGETS: call __popcountdi2 |
| 468 |
| 429 | 469 |
| 430 define i32 @test_popcount_64_ret_i32(i64 %x) { | 470 define i32 @test_popcount_64_ret_i32(i64 %x) { |
| 431 entry: | 471 entry: |
| 432 %r_i64 = call i64 @llvm.ctpop.i64(i64 %x) | 472 %r_i64 = call i64 @llvm.ctpop.i64(i64 %x) |
| 433 %r = trunc i64 %r_i64 to i32 | 473 %r = trunc i64 %r_i64 to i32 |
| 434 ret i32 %r | 474 ret i32 %r |
| 435 } | 475 } |
| 436 ; If there is a trunc, then the mov {{.*}}, 0 is dead and gets optimized out. | 476 ; If there is a trunc, then the mov {{.*}}, 0 is dead and gets optimized out. |
| 437 ; CHECKO2REM-LABEL: test_popcount_64_ret_i32 | 477 ; CHECKO2REM-LABEL: test_popcount_64_ret_i32 |
| 438 ; CHECKO2REM: call __popcountdi2 | 478 ; CHECKO2REM: call -4 |
| 439 ; CHECKO2REM-NOT: mov {{.*}}, 0 | 479 ; CHECKO2REM-NOT: mov {{.*}}, 0 |
| 480 ; CALLTARGETS-LABEL: test_popcount_64_ret_i32 |
| 481 ; CALLTARGETS: call __popcountdi2 |
| 440 | 482 |
| 441 define void @test_stacksave_noalloca() { | 483 define void @test_stacksave_noalloca() { |
| 442 entry: | 484 entry: |
| 443 %sp = call i8* @llvm.stacksave() | 485 %sp = call i8* @llvm.stacksave() |
| 444 call void @llvm.stackrestore(i8* %sp) | 486 call void @llvm.stackrestore(i8* %sp) |
| 445 ret void | 487 ret void |
| 446 } | 488 } |
| 447 ; CHECK-LABEL: test_stacksave_noalloca | 489 ; CHECK-LABEL: test_stacksave_noalloca |
| 448 ; CHECK: mov {{.*}}, esp | 490 ; CHECK: mov {{.*}}, esp |
| 449 ; CHECK: mov esp, {{.*}} | 491 ; CHECK: mov esp, {{.*}} |
| (...skipping 28 matching lines...) Expand all Loading... |
| 478 } | 520 } |
| 479 ; CHECK-LABEL: test_stacksave_multiple | 521 ; CHECK-LABEL: test_stacksave_multiple |
| 480 ; At least 3 copies of esp, but probably more from having to do the allocas. | 522 ; At least 3 copies of esp, but probably more from having to do the allocas. |
| 481 ; CHECK: mov {{.*}}, esp | 523 ; CHECK: mov {{.*}}, esp |
| 482 ; CHECK: mov {{.*}}, esp | 524 ; CHECK: mov {{.*}}, esp |
| 483 ; CHECK: mov {{.*}}, esp | 525 ; CHECK: mov {{.*}}, esp |
| 484 ; CHECK: mov esp, {{.*}} | 526 ; CHECK: mov esp, {{.*}} |
| 485 | 527 |
| 486 ; ERRORS-NOT: ICE translation error | 528 ; ERRORS-NOT: ICE translation error |
| 487 ; DUMP-NOT: SZ | 529 ; DUMP-NOT: SZ |
| OLD | NEW |