1 ; This tests parsing NaCl intrinsics not related to atomic operations. 2 3 ; RUN: %p2i -i %s --insts --args -allow-externally-defined-symbols \ 4 ; RUN: | FileCheck %s 5 ; RUN: %p2i -i %s --args -notranslate -timing \ 6 ; RUN: -allow-externally-defined-symbols | \ 7 ; RUN: FileCheck --check-prefix=NOIR %s 8 9 declare i8* @llvm.nacl.read.tp() 10 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) 11 declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) 12 declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1) 13 declare void @llvm.nacl.longjmp(i8*, i32) 14 declare i32 @llvm.nacl.setjmp(i8*) 15 declare float @llvm.sqrt.f32(float) 16 declare double @llvm.sqrt.f64(double) 17 declare float @llvm.fabs.f32(float) 18 declare double @llvm.fabs.f64(double) 19 declare <4 x float> @llvm.fabs.v4f32(<4 x float>) 20 declare void @llvm.trap() 21 declare i16 @llvm.bswap.i16(i16) 22 declare i32 @llvm.bswap.i32(i32) 23 declare i64 @llvm.bswap.i64(i64) 24 declare i32 @llvm.ctlz.i32(i32, i1) 25 declare i64 @llvm.ctlz.i64(i64, i1) 26 declare i32 @llvm.cttz.i32(i32, i1) 27 declare i64 @llvm.cttz.i64(i64, i1) 28 declare i32 @llvm.ctpop.i32(i32) 29 declare i64 @llvm.ctpop.i64(i64) 30 declare i8* @llvm.stacksave() 31 declare void @llvm.stackrestore(i8*) 32 33 define internal i32 @test_nacl_read_tp() { 34 entry: 35 %ptr = call i8* @llvm.nacl.read.tp() 36 %__1 = ptrtoint i8* %ptr to i32 37 ret i32 %__1 38 } 39 40 ; CHECK: define internal i32 @test_nacl_read_tp() { 41 ; CHECK-NEXT: entry: 42 ; CHECK-NEXT: %ptr = call i32 @llvm.nacl.read.tp() 43 ; CHECK-NEXT: ret i32 %ptr 44 ; CHECK-NEXT: } 45 46 define internal void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) { 47 entry: 48 %dst = inttoptr i32 %iptr_dst to i8* 49 %src = inttoptr i32 %iptr_src to i8* 50 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, 51 i32 %len, i32 1, i1 false) 52 ret void 53 } 54 55 ; CHECK-NEXT: define internal void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) { 56 ; CHECK-NEXT: entry: 57 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i32 %iptr_dst, i32 %iptr_src, i32 %len, i32 1, i1 false) 58 ; CHECK-NEXT: ret void 59 ; CHECK-NEXT: } 60 61 define internal void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) { 62 entry: 63 %dst = inttoptr i32 %iptr_dst to i8* 64 %src = inttoptr i32 %iptr_src to i8* 65 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, 66 i32 %len, i32 1, i1 false) 67 ret void 68 } 69 70 ; CHECK-NEXT: define internal void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) { 71 ; CHECK-NEXT: entry: 72 ; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i32 %iptr_dst, i32 %iptr_src, i32 %len, i32 1, i1 false) 73 ; CHECK-NEXT: ret void 74 ; CHECK-NEXT: } 75 76 define internal void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) { 77 entry: 78 %val = trunc i32 %wide_val to i8 79 %dst = inttoptr i32 %iptr_dst to i8* 80 call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, 81 i32 %len, i32 1, i1 false) 82 ret void 83 } 84 85 ; CHECK-NEXT: define internal void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) { 86 ; CHECK-NEXT: entry: 87 ; CHECK-NEXT: %val = trunc i32 %wide_val to i8 88 ; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i32 %iptr_dst, i8 %val, i32 %len, i32 1, i1 false) 89 ; CHECK-NEXT: ret void 90 ; CHECK-NEXT: } 91 92 define internal i32 @test_setjmplongjmp(i32 %iptr_env) { 93 entry: 94 %env = inttoptr i32 %iptr_env to i8* 95 %i = call i32 @llvm.nacl.setjmp(i8* %env) 96 %r1 = icmp eq i32 %i, 0 97 br i1 %r1, label %Zero, label %NonZero 98 Zero: 99 ; Redundant inttoptr, to make --pnacl cast-eliding/re-insertion happy. 100 %env2 = inttoptr i32 %iptr_env to i8* 101 call void @llvm.nacl.longjmp(i8* %env2, i32 1) 102 ret i32 0 103 NonZero: 104 ret i32 1 105 } 106 107 ; CHECK-NEXT: define internal i32 @test_setjmplongjmp(i32 %iptr_env) { 108 ; CHECK-NEXT: entry: 109 ; CHECK-NEXT: %i = call i32 @llvm.nacl.setjmp(i32 %iptr_env) 110 ; CHECK-NEXT: %r1 = icmp eq i32 %i, 0 111 ; CHECK-NEXT: br i1 %r1, label %Zero, label %NonZero 112 ; CHECK-NEXT: Zero: 113 ; CHECK-NEXT: call void @llvm.nacl.longjmp(i32 %iptr_env, i32 1) 114 ; CHECK-NEXT: ret i32 0 115 ; CHECK-NEXT: NonZero: 116 ; CHECK-NEXT: ret i32 1 117 ; CHECK-NEXT: } 118 119 define internal float @test_sqrt_float(float %x, i32 %iptr) { 120 entry: 121 %r = call float @llvm.sqrt.f32(float %x) 122 %r2 = call float @llvm.sqrt.f32(float %r) 123 %r3 = call float @llvm.sqrt.f32(float -0.0) 124 %r4 = fadd float %r2, %r3 125 ret float %r4 126 } 127 128 ; CHECK-NEXT: define internal float @test_sqrt_float(float %x, i32 %iptr) { 129 ; CHECK-NEXT: entry: 130 ; CHECK-NEXT: %r = call float @llvm.sqrt.f32(float %x) 131 ; CHECK-NEXT: %r2 = call float @llvm.sqrt.f32(float %r) 132 ; CHECK-NEXT: %r3 = call float @llvm.sqrt.f32(float -0.000000e+00) 133 ; CHECK-NEXT: %r4 = fadd float %r2, %r3 134 ; CHECK-NEXT: ret float %r4 135 ; CHECK-NEXT: } 136 137 define internal double @test_sqrt_double(double %x, i32 %iptr) { 138 entry: 139 %r = call double @llvm.sqrt.f64(double %x) 140 %r2 = call double @llvm.sqrt.f64(double %r) 141 %r3 = call double @llvm.sqrt.f64(double -0.0) 142 %r4 = fadd double %r2, %r3 143 ret double %r4 144 } 145 146 ; CHECK-NEXT: define internal double @test_sqrt_double(double %x, i32 %iptr) { 147 ; CHECK-NEXT: entry: 148 ; CHECK-NEXT: %r = call double @llvm.sqrt.f64(double %x) 149 ; CHECK-NEXT: %r2 = call double @llvm.sqrt.f64(double %r) 150 ; CHECK-NEXT: %r3 = call double @llvm.sqrt.f64(double -0.000000e+00) 151 ; CHECK-NEXT: %r4 = fadd double %r2, %r3 152 ; CHECK-NEXT: ret double %r4 153 ; CHECK-NEXT: } 154 155 define internal float @test_fabs_float(float %x) { 156 entry: 157 %r = call float @llvm.fabs.f32(float %x) 158 %r2 = call float @llvm.fabs.f32(float %r) 159 %r3 = call float @llvm.fabs.f32(float -0.0) 160 %r4 = fadd float %r2, %r3 161 ret float %r4 162 } 163 164 ; CHECK-NEXT: define internal float @test_fabs_float(float %x) { 165 ; CHECK-NEXT: entry: 166 ; CHECK-NEXT: %r = call float @llvm.fabs.f32(float %x) 167 ; CHECK-NEXT: %r2 = call float @llvm.fabs.f32(float %r) 168 ; CHECK-NEXT: %r3 = call float @llvm.fabs.f32(float -0.000000e+00) 169 ; CHECK-NEXT: %r4 = fadd float %r2, %r3 170 ; CHECK-NEXT: ret float %r4 171 ; CHECK-NEXT: } 172 173 define internal double @test_fabs_double(double %x) { 174 entry: 175 %r = call double @llvm.fabs.f64(double %x) 176 %r2 = call double @llvm.fabs.f64(double %r) 177 %r3 = call double @llvm.fabs.f64(double -0.0) 178 %r4 = fadd double %r2, %r3 179 ret double %r4 180 } 181 182 ; CHECK-NEXT: define internal double @test_fabs_double(double %x) { 183 ; CHECK-NEXT: entry: 184 ; CHECK-NEXT: %r = call double @llvm.fabs.f64(double %x) 185 ; CHECK-NEXT: %r2 = call double @llvm.fabs.f64(double %r) 186 ; CHECK-NEXT: %r3 = call double @llvm.fabs.f64(double -0.000000e+00) 187 ; CHECK-NEXT: %r4 = fadd double %r2, %r3 188 ; CHECK-NEXT: ret double %r4 189 ; CHECK-NEXT: } 190 191 define internal <4 x float> @test_fabs_v4f32(<4 x float> %x) { 192 entry: 193 %r = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x) 194 %r2 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %r) 195 %r3 = call <4 x float> @llvm.fabs.v4f32(<4 x float> undef) 196 %r4 = fadd <4 x float> %r2, %r3 197 ret <4 x float> %r4 198 } 199 200 ; CHECK-NEXT: define internal <4 x float> @test_fabs_v4f32(<4 x float> %x) { 201 ; CHECK-NEXT: entry: 202 ; CHECK-NEXT: %r = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x) 203 ; CHECK-NEXT: %r2 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %r) 204 ; CHECK-NEXT: %r3 = call <4 x float> @llvm.fabs.v4f32(<4 x float> undef) 205 ; CHECK-NEXT: %r4 = fadd <4 x float> %r2, %r3 206 ; CHECK-NEXT: ret <4 x float> %r4 207 ; CHECK-NEXT: } 208 209 define internal i32 @test_trap(i32 %br) { 210 entry: 211 %r1 = icmp eq i32 %br, 0 212 br i1 %r1, label %Zero, label %NonZero 213 Zero: 214 call void @llvm.trap() 215 unreachable 216 NonZero: 217 ret i32 1 218 } 219 220 ; CHECK-NEXT: define internal i32 @test_trap(i32 %br) { 221 ; CHECK-NEXT: entry: 222 ; CHECK-NEXT: %r1 = icmp eq i32 %br, 0 223 ; CHECK-NEXT: br i1 %r1, label %Zero, label %NonZero 224 ; CHECK-NEXT: Zero: 225 ; CHECK-NEXT: call void @llvm.trap() 226 ; CHECK-NEXT: unreachable 227 ; CHECK-NEXT: NonZero: 228 ; CHECK-NEXT: ret i32 1 229 ; CHECK-NEXT: } 230 231 define internal i32 @test_bswap_16(i32 %x) { 232 entry: 233 %x_trunc = trunc i32 %x to i16 234 %r = call i16 @llvm.bswap.i16(i16 %x_trunc) 235 %r_zext = zext i16 %r to i32 236 ret i32 %r_zext 237 } 238 239 ; CHECK-NEXT: define internal i32 @test_bswap_16(i32 %x) { 240 ; CHECK-NEXT: entry: 241 ; CHECK-NEXT: %x_trunc = trunc i32 %x to i16 242 ; CHECK-NEXT: %r = call i16 @llvm.bswap.i16(i16 %x_trunc) 243 ; CHECK-NEXT: %r_zext = zext i16 %r to i32 244 ; CHECK-NEXT: ret i32 %r_zext 245 ; CHECK-NEXT: } 246 247 define internal i32 @test_bswap_32(i32 %x) { 248 entry: 249 %r = call i32 @llvm.bswap.i32(i32 %x) 250 ret i32 %r 251 } 252 253 ; CHECK-NEXT: define internal i32 @test_bswap_32(i32 %x) { 254 ; CHECK-NEXT: entry: 255 ; CHECK-NEXT: %r = call i32 @llvm.bswap.i32(i32 %x) 256 ; CHECK-NEXT: ret i32 %r 257 ; CHECK-NEXT: } 258 259 define internal i64 @test_bswap_64(i64 %x) { 260 entry: 261 %r = call i64 @llvm.bswap.i64(i64 %x) 262 ret i64 %r 263 } 264 265 ; CHECK-NEXT: define internal i64 @test_bswap_64(i64 %x) { 266 ; CHECK-NEXT: entry: 267 ; CHECK-NEXT: %r = call i64 @llvm.bswap.i64(i64 %x) 268 ; CHECK-NEXT: ret i64 %r 269 ; CHECK-NEXT: } 270 271 define internal i32 @test_ctlz_32(i32 %x) { 272 entry: 273 %r = call i32 @llvm.ctlz.i32(i32 %x, i1 false) 274 ret i32 %r 275 } 276 277 ; CHECK-NEXT: define internal i32 @test_ctlz_32(i32 %x) { 278 ; CHECK-NEXT: entry: 279 ; CHECK-NEXT: %r = call i32 @llvm.ctlz.i32(i32 %x, i1 false) 280 ; CHECK-NEXT: ret i32 %r 281 ; CHECK-NEXT: } 282 283 define internal i64 @test_ctlz_64(i64 %x) { 284 entry: 285 %r = call i64 @llvm.ctlz.i64(i64 %x, i1 false) 286 ret i64 %r 287 } 288 289 ; CHECK-NEXT: define internal i64 @test_ctlz_64(i64 %x) { 290 ; CHECK-NEXT: entry: 291 ; CHECK-NEXT: %r = call i64 @llvm.ctlz.i64(i64 %x, i1 false) 292 ; CHECK-NEXT: ret i64 %r 293 ; CHECK-NEXT: } 294 295 define internal i32 @test_cttz_32(i32 %x) { 296 entry: 297 %r = call i32 @llvm.cttz.i32(i32 %x, i1 false) 298 ret i32 %r 299 } 300 301 ; CHECK-NEXT: define internal i32 @test_cttz_32(i32 %x) { 302 ; CHECK-NEXT: entry: 303 ; CHECK-NEXT: %r = call i32 @llvm.cttz.i32(i32 %x, i1 false) 304 ; CHECK-NEXT: ret i32 %r 305 ; CHECK-NEXT: } 306 307 define internal i64 @test_cttz_64(i64 %x) { 308 entry: 309 %r = call i64 @llvm.cttz.i64(i64 %x, i1 false) 310 ret i64 %r 311 } 312 313 ; CHECK-NEXT: define internal i64 @test_cttz_64(i64 %x) { 314 ; CHECK-NEXT: entry: 315 ; CHECK-NEXT: %r = call i64 @llvm.cttz.i64(i64 %x, i1 false) 316 ; CHECK-NEXT: ret i64 %r 317 ; CHECK-NEXT: } 318 319 define internal i32 @test_popcount_32(i32 %x) { 320 entry: 321 %r = call i32 @llvm.ctpop.i32(i32 %x) 322 ret i32 %r 323 } 324 325 ; CHECK-NEXT: define internal i32 @test_popcount_32(i32 %x) { 326 ; CHECK-NEXT: entry: 327 ; CHECK-NEXT: %r = call i32 @llvm.ctpop.i32(i32 %x) 328 ; CHECK-NEXT: ret i32 %r 329 ; CHECK-NEXT: } 330 331 define internal i64 @test_popcount_64(i64 %x) { 332 entry: 333 %r = call i64 @llvm.ctpop.i64(i64 %x) 334 ret i64 %r 335 } 336 337 ; CHECK-NEXT: define internal i64 @test_popcount_64(i64 %x) { 338 ; CHECK-NEXT: entry: 339 ; CHECK-NEXT: %r = call i64 @llvm.ctpop.i64(i64 %x) 340 ; CHECK-NEXT: ret i64 %r 341 ; CHECK-NEXT: } 342 343 define internal void @test_stacksave_noalloca() { 344 entry: 345 %sp = call i8* @llvm.stacksave() 346 call void @llvm.stackrestore(i8* %sp) 347 ret void 348 } 349 350 ; CHECK-NEXT: define internal void @test_stacksave_noalloca() { 351 ; CHECK-NEXT: entry: 352 ; CHECK-NEXT: %sp = call i32 @llvm.stacksave() 353 ; CHECK-NEXT: call void @llvm.stackrestore(i32 %sp) 354 ; CHECK-NEXT: ret void 355 ; CHECK-NEXT: } 356 357 declare i32 @foo(i32 %x) 358 359 define internal void @test_stacksave_multiple(i32 %x) { 360 entry: 361 %x_4 = mul i32 %x, 4 362 %sp1 = call i8* @llvm.stacksave() 363 %tmp1 = alloca i8, i32 %x_4, align 4 364 365 %sp2 = call i8* @llvm.stacksave() 366 %tmp2 = alloca i8, i32 %x_4, align 4 367 368 %y = call i32 @foo(i32 %x) 369 370 %sp3 = call i8* @llvm.stacksave() 371 %tmp3 = alloca i8, i32 %x_4, align 4 372 373 %__9 = bitcast i8* %tmp1 to i32* 374 store i32 %y, i32* %__9, align 1 375 376 %__10 = bitcast i8* %tmp2 to i32* 377 store i32 %x, i32* %__10, align 1 378 379 %__11 = bitcast i8* %tmp3 to i32* 380 store i32 %x, i32* %__11, align 1 381 382 call void @llvm.stackrestore(i8* %sp1) 383 ret void 384 } 385 386 ; CHECK-NEXT: define internal void @test_stacksave_multiple(i32 %x) { 387 ; CHECK-NEXT: entry: 388 ; CHECK-NEXT: %x_4 = mul i32 %x, 4 389 ; CHECK-NEXT: %sp1 = call i32 @llvm.stacksave() 390 ; CHECK-NEXT: %tmp1 = alloca i8, i32 %x_4, align 4 391 ; CHECK-NEXT: %sp2 = call i32 @llvm.stacksave() 392 ; CHECK-NEXT: %tmp2 = alloca i8, i32 %x_4, align 4 393 ; CHECK-NEXT: %y = call i32 @foo(i32 %x) 394 ; CHECK-NEXT: %sp3 = call i32 @llvm.stacksave() 395 ; CHECK-NEXT: %tmp3 = alloca i8, i32 %x_4, align 4 396 ; CHECK-NEXT: store i32 %y, i32* %tmp1, align 1 397 ; CHECK-NEXT: store i32 %x, i32* %tmp2, align 1 398 ; CHECK-NEXT: store i32 %x, i32* %tmp3, align 1 399 ; CHECK-NEXT: call void @llvm.stackrestore(i32 %sp1) 400 ; CHECK-NEXT: ret void 401 ; CHECK-NEXT: } 402 403 ; NOIR: Total across all functions 404