; This tests parsing NaCl intrinsics not related to atomic operations. ; RUN: %p2i -i %s --insts --args -allow-externally-defined-symbols \ ; RUN: | FileCheck %s ; RUN: %p2i -i %s --args -notranslate -timing \ ; RUN: -allow-externally-defined-symbols | \ ; RUN: FileCheck --check-prefix=NOIR %s declare i8* @llvm.nacl.read.tp() declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1) declare void @llvm.nacl.longjmp(i8*, i32) declare i32 @llvm.nacl.setjmp(i8*) declare float @llvm.sqrt.f32(float) declare double @llvm.sqrt.f64(double) declare float @llvm.fabs.f32(float) declare double @llvm.fabs.f64(double) declare <4 x float> @llvm.fabs.v4f32(<4 x float>) declare void @llvm.trap() declare i16 @llvm.bswap.i16(i16) declare i32 @llvm.bswap.i32(i32) declare i64 @llvm.bswap.i64(i64) declare i32 @llvm.ctlz.i32(i32, i1) declare i64 @llvm.ctlz.i64(i64, i1) declare i32 @llvm.cttz.i32(i32, i1) declare i64 @llvm.cttz.i64(i64, i1) declare i32 @llvm.ctpop.i32(i32) declare i64 @llvm.ctpop.i64(i64) declare i8* @llvm.stacksave() declare void @llvm.stackrestore(i8*) define internal i32 @test_nacl_read_tp() { entry: %ptr = call i8* @llvm.nacl.read.tp() %__1 = ptrtoint i8* %ptr to i32 ret i32 %__1 } ; CHECK: define internal i32 @test_nacl_read_tp() { ; CHECK-NEXT: entry: ; CHECK-NEXT: %ptr = call i32 @llvm.nacl.read.tp() ; CHECK-NEXT: ret i32 %ptr ; CHECK-NEXT: } define internal void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) { entry: %dst = inttoptr i32 %iptr_dst to i8* %src = inttoptr i32 %iptr_src to i8* call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %len, i32 1, i1 false) ret void } ; CHECK-NEXT: define internal void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) { ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i32 %iptr_dst, i32 %iptr_src, i32 %len, i32 1, i1 false) ; CHECK-NEXT: ret void ; CHECK-NEXT: } define internal void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) { entry: %dst = inttoptr i32 %iptr_dst to i8* %src = inttoptr i32 %iptr_src to i8* call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %len, i32 1, i1 false) ret void } ; CHECK-NEXT: define internal void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) { ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i32 %iptr_dst, i32 %iptr_src, i32 %len, i32 1, i1 false) ; CHECK-NEXT: ret void ; CHECK-NEXT: } define internal void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) { entry: %val = trunc i32 %wide_val to i8 %dst = inttoptr i32 %iptr_dst to i8* call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val, i32 %len, i32 1, i1 false) ret void } ; CHECK-NEXT: define internal void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %val = trunc i32 %wide_val to i8 ; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i32 %iptr_dst, i8 %val, i32 %len, i32 1, i1 false) ; CHECK-NEXT: ret void ; CHECK-NEXT: } define internal i32 @test_setjmplongjmp(i32 %iptr_env) { entry: %env = inttoptr i32 %iptr_env to i8* %i = call i32 @llvm.nacl.setjmp(i8* %env) %r1 = icmp eq i32 %i, 0 br i1 %r1, label %Zero, label %NonZero Zero: ; Redundant inttoptr, to make --pnacl cast-eliding/re-insertion happy. %env2 = inttoptr i32 %iptr_env to i8* call void @llvm.nacl.longjmp(i8* %env2, i32 1) ret i32 0 NonZero: ret i32 1 } ; CHECK-NEXT: define internal i32 @test_setjmplongjmp(i32 %iptr_env) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %i = call i32 @llvm.nacl.setjmp(i32 %iptr_env) ; CHECK-NEXT: %r1 = icmp eq i32 %i, 0 ; CHECK-NEXT: br i1 %r1, label %Zero, label %NonZero ; CHECK-NEXT: Zero: ; CHECK-NEXT: call void @llvm.nacl.longjmp(i32 %iptr_env, i32 1) ; CHECK-NEXT: ret i32 0 ; CHECK-NEXT: NonZero: ; CHECK-NEXT: ret i32 1 ; CHECK-NEXT: } define internal float @test_sqrt_float(float %x, i32 %iptr) { entry: %r = call float @llvm.sqrt.f32(float %x) %r2 = call float @llvm.sqrt.f32(float %r) %r3 = call float @llvm.sqrt.f32(float -0.0) %r4 = fadd float %r2, %r3 ret float %r4 } ; CHECK-NEXT: define internal float @test_sqrt_float(float %x, i32 %iptr) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call float @llvm.sqrt.f32(float %x) ; CHECK-NEXT: %r2 = call float @llvm.sqrt.f32(float %r) ; CHECK-NEXT: %r3 = call float @llvm.sqrt.f32(float -0.000000e+00) ; CHECK-NEXT: %r4 = fadd float %r2, %r3 ; CHECK-NEXT: ret float %r4 ; CHECK-NEXT: } define internal double @test_sqrt_double(double %x, i32 %iptr) { entry: %r = call double @llvm.sqrt.f64(double %x) %r2 = call double @llvm.sqrt.f64(double %r) %r3 = call double @llvm.sqrt.f64(double -0.0) %r4 = fadd double %r2, %r3 ret double %r4 } ; CHECK-NEXT: define internal double @test_sqrt_double(double %x, i32 %iptr) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call double @llvm.sqrt.f64(double %x) ; CHECK-NEXT: %r2 = call double @llvm.sqrt.f64(double %r) ; CHECK-NEXT: %r3 = call double @llvm.sqrt.f64(double -0.000000e+00) ; CHECK-NEXT: %r4 = fadd double %r2, %r3 ; CHECK-NEXT: ret double %r4 ; CHECK-NEXT: } define internal float @test_fabs_float(float %x) { entry: %r = call float @llvm.fabs.f32(float %x) %r2 = call float @llvm.fabs.f32(float %r) %r3 = call float @llvm.fabs.f32(float -0.0) %r4 = fadd float %r2, %r3 ret float %r4 } ; CHECK-NEXT: define internal float @test_fabs_float(float %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call float @llvm.fabs.f32(float %x) ; CHECK-NEXT: %r2 = call float @llvm.fabs.f32(float %r) ; CHECK-NEXT: %r3 = call float @llvm.fabs.f32(float -0.000000e+00) ; CHECK-NEXT: %r4 = fadd float %r2, %r3 ; CHECK-NEXT: ret float %r4 ; CHECK-NEXT: } define internal double @test_fabs_double(double %x) { entry: %r = call double @llvm.fabs.f64(double %x) %r2 = call double @llvm.fabs.f64(double %r) %r3 = call double @llvm.fabs.f64(double -0.0) %r4 = fadd double %r2, %r3 ret double %r4 } ; CHECK-NEXT: define internal double @test_fabs_double(double %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call double @llvm.fabs.f64(double %x) ; CHECK-NEXT: %r2 = call double @llvm.fabs.f64(double %r) ; CHECK-NEXT: %r3 = call double @llvm.fabs.f64(double -0.000000e+00) ; CHECK-NEXT: %r4 = fadd double %r2, %r3 ; CHECK-NEXT: ret double %r4 ; CHECK-NEXT: } define internal <4 x float> @test_fabs_v4f32(<4 x float> %x) { entry: %r = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x) %r2 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %r) %r3 = call <4 x float> @llvm.fabs.v4f32(<4 x float> undef) %r4 = fadd <4 x float> %r2, %r3 ret <4 x float> %r4 } ; CHECK-NEXT: define internal <4 x float> @test_fabs_v4f32(<4 x float> %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x) ; CHECK-NEXT: %r2 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %r) ; CHECK-NEXT: %r3 = call <4 x float> @llvm.fabs.v4f32(<4 x float> undef) ; CHECK-NEXT: %r4 = fadd <4 x float> %r2, %r3 ; CHECK-NEXT: ret <4 x float> %r4 ; CHECK-NEXT: } define internal i32 @test_trap(i32 %br) { entry: %r1 = icmp eq i32 %br, 0 br i1 %r1, label %Zero, label %NonZero Zero: call void @llvm.trap() unreachable NonZero: ret i32 1 } ; CHECK-NEXT: define internal i32 @test_trap(i32 %br) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r1 = icmp eq i32 %br, 0 ; CHECK-NEXT: br i1 %r1, label %Zero, label %NonZero ; CHECK-NEXT: Zero: ; CHECK-NEXT: call void @llvm.trap() ; CHECK-NEXT: unreachable ; CHECK-NEXT: NonZero: ; CHECK-NEXT: ret i32 1 ; CHECK-NEXT: } define internal i32 @test_bswap_16(i32 %x) { entry: %x_trunc = trunc i32 %x to i16 %r = call i16 @llvm.bswap.i16(i16 %x_trunc) %r_zext = zext i16 %r to i32 ret i32 %r_zext } ; CHECK-NEXT: define internal i32 @test_bswap_16(i32 %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %x_trunc = trunc i32 %x to i16 ; CHECK-NEXT: %r = call i16 @llvm.bswap.i16(i16 %x_trunc) ; CHECK-NEXT: %r_zext = zext i16 %r to i32 ; CHECK-NEXT: ret i32 %r_zext ; CHECK-NEXT: } define internal i32 @test_bswap_32(i32 %x) { entry: %r = call i32 @llvm.bswap.i32(i32 %x) ret i32 %r } ; CHECK-NEXT: define internal i32 @test_bswap_32(i32 %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call i32 @llvm.bswap.i32(i32 %x) ; CHECK-NEXT: ret i32 %r ; CHECK-NEXT: } define internal i64 @test_bswap_64(i64 %x) { entry: %r = call i64 @llvm.bswap.i64(i64 %x) ret i64 %r } ; CHECK-NEXT: define internal i64 @test_bswap_64(i64 %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call i64 @llvm.bswap.i64(i64 %x) ; CHECK-NEXT: ret i64 %r ; CHECK-NEXT: } define internal i32 @test_ctlz_32(i32 %x) { entry: %r = call i32 @llvm.ctlz.i32(i32 %x, i1 false) ret i32 %r } ; CHECK-NEXT: define internal i32 @test_ctlz_32(i32 %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call i32 @llvm.ctlz.i32(i32 %x, i1 false) ; CHECK-NEXT: ret i32 %r ; CHECK-NEXT: } define internal i64 @test_ctlz_64(i64 %x) { entry: %r = call i64 @llvm.ctlz.i64(i64 %x, i1 false) ret i64 %r } ; CHECK-NEXT: define internal i64 @test_ctlz_64(i64 %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call i64 @llvm.ctlz.i64(i64 %x, i1 false) ; CHECK-NEXT: ret i64 %r ; CHECK-NEXT: } define internal i32 @test_cttz_32(i32 %x) { entry: %r = call i32 @llvm.cttz.i32(i32 %x, i1 false) ret i32 %r } ; CHECK-NEXT: define internal i32 @test_cttz_32(i32 %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call i32 @llvm.cttz.i32(i32 %x, i1 false) ; CHECK-NEXT: ret i32 %r ; CHECK-NEXT: } define internal i64 @test_cttz_64(i64 %x) { entry: %r = call i64 @llvm.cttz.i64(i64 %x, i1 false) ret i64 %r } ; CHECK-NEXT: define internal i64 @test_cttz_64(i64 %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call i64 @llvm.cttz.i64(i64 %x, i1 false) ; CHECK-NEXT: ret i64 %r ; CHECK-NEXT: } define internal i32 @test_popcount_32(i32 %x) { entry: %r = call i32 @llvm.ctpop.i32(i32 %x) ret i32 %r } ; CHECK-NEXT: define internal i32 @test_popcount_32(i32 %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call i32 @llvm.ctpop.i32(i32 %x) ; CHECK-NEXT: ret i32 %r ; CHECK-NEXT: } define internal i64 @test_popcount_64(i64 %x) { entry: %r = call i64 @llvm.ctpop.i64(i64 %x) ret i64 %r } ; CHECK-NEXT: define internal i64 @test_popcount_64(i64 %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %r = call i64 @llvm.ctpop.i64(i64 %x) ; CHECK-NEXT: ret i64 %r ; CHECK-NEXT: } define internal void @test_stacksave_noalloca() { entry: %sp = call i8* @llvm.stacksave() call void @llvm.stackrestore(i8* %sp) ret void } ; CHECK-NEXT: define internal void @test_stacksave_noalloca() { ; CHECK-NEXT: entry: ; CHECK-NEXT: %sp = call i32 @llvm.stacksave() ; CHECK-NEXT: call void @llvm.stackrestore(i32 %sp) ; CHECK-NEXT: ret void ; CHECK-NEXT: } declare i32 @foo(i32 %x) define internal void @test_stacksave_multiple(i32 %x) { entry: %x_4 = mul i32 %x, 4 %sp1 = call i8* @llvm.stacksave() %tmp1 = alloca i8, i32 %x_4, align 4 %sp2 = call i8* @llvm.stacksave() %tmp2 = alloca i8, i32 %x_4, align 4 %y = call i32 @foo(i32 %x) %sp3 = call i8* @llvm.stacksave() %tmp3 = alloca i8, i32 %x_4, align 4 %__9 = bitcast i8* %tmp1 to i32* store i32 %y, i32* %__9, align 1 %__10 = bitcast i8* %tmp2 to i32* store i32 %x, i32* %__10, align 1 %__11 = bitcast i8* %tmp3 to i32* store i32 %x, i32* %__11, align 1 call void @llvm.stackrestore(i8* %sp1) ret void } ; CHECK-NEXT: define internal void @test_stacksave_multiple(i32 %x) { ; CHECK-NEXT: entry: ; CHECK-NEXT: %x_4 = mul i32 %x, 4 ; CHECK-NEXT: %sp1 = call i32 @llvm.stacksave() ; CHECK-NEXT: %tmp1 = alloca i8, i32 %x_4, align 4 ; CHECK-NEXT: %sp2 = call i32 @llvm.stacksave() ; CHECK-NEXT: %tmp2 = alloca i8, i32 %x_4, align 4 ; CHECK-NEXT: %y = call i32 @foo(i32 %x) ; CHECK-NEXT: %sp3 = call i32 @llvm.stacksave() ; CHECK-NEXT: %tmp3 = alloca i8, i32 %x_4, align 4 ; CHECK-NEXT: store i32 %y, i32* %tmp1, align 1 ; CHECK-NEXT: store i32 %x, i32* %tmp2, align 1 ; CHECK-NEXT: store i32 %x, i32* %tmp3, align 1 ; CHECK-NEXT: call void @llvm.stackrestore(i32 %sp1) ; CHECK-NEXT: ret void ; CHECK-NEXT: } ; NOIR: Total across all functions