Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Break type inference for log with unrelated module #20821

Closed
simonster opened this issue Feb 27, 2017 · 3 comments
Closed

Break type inference for log with unrelated module #20821

simonster opened this issue Feb 27, 2017 · 3 comments

Comments

@simonster
Copy link
Member

simonster commented Feb 27, 2017

julia> import Primes

julia> f(x) = log(x);

julia> @code_llvm f(1.0)

define double @julia_f_70658(double) #0 {
top:
  %ptls_i8 = call i8* asm "movq %fs:0, $0;\0Aaddq $$-2672, $0", "=r,~{dirflag},~{fpsr},~{flags}"() #2
  %ptls = bitcast i8* %ptls_i8 to %jl_value_t***
  %1 = alloca [4 x %jl_value_t*], align 8
  %.sub = getelementptr inbounds [4 x %jl_value_t*], [4 x %jl_value_t*]* %1, i64 0, i64 0
  %2 = getelementptr [4 x %jl_value_t*], [4 x %jl_value_t*]* %1, i64 0, i64 2
  %3 = bitcast %jl_value_t** %2 to i8*
  call void @llvm.memset.p0i8.i32(i8* %3, i8 0, i32 16, i32 8, i1 false)
  %4 = bitcast [4 x %jl_value_t*]* %1 to i64*
  store i64 4, i64* %4, align 8
  %5 = getelementptr [4 x %jl_value_t*], [4 x %jl_value_t*]* %1, i64 0, i64 1
  %6 = bitcast i8* %ptls_i8 to i64*
  %7 = load i64, i64* %6, align 8
  %8 = bitcast %jl_value_t** %5 to i64*
  store i64 %7, i64* %8, align 8
  store %jl_value_t** %.sub, %jl_value_t*** %ptls, align 8
  %9 = getelementptr [4 x %jl_value_t*], [4 x %jl_value_t*]* %1, i64 0, i64 3
  store %jl_value_t* inttoptr (i64 140530114606896 to %jl_value_t*), %jl_value_t** %2, align 8
  %10 = call %jl_value_t* @jl_gc_pool_alloc(i8* %ptls_i8, i32 1432, i32 16)
  %11 = getelementptr inbounds %jl_value_t, %jl_value_t* %10, i64 -1, i32 0
  store %jl_value_t* inttoptr (i64 140530057424720 to %jl_value_t*), %jl_value_t** %11, align 8
  %12 = bitcast %jl_value_t* %10 to double*
  store double %0, double* %12, align 8
  store %jl_value_t* %10, %jl_value_t** %9, align 8
  %13 = call %jl_value_t* @jl_invoke(%jl_value_t* inttoptr (i64 140530176032384 to %jl_value_t*), %jl_value_t** %2, i32 2)
  %14 = bitcast %jl_value_t* %13 to double*
  %15 = load double, double* %14, align 16
  %16 = load i64, i64* %8, align 8
  store i64 %16, i64* %6, align 8
  ret double %15
}

julia> Pkg.installed("Primes")
v"0.1.2"

julia> versioninfo()
Julia Version 0.5.1-pre+55
Commit 8d4ef37* (2017-02-13 09:11 UTC)
Platform Info:
  System: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i7-3930K CPU @ 3.20GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Sandybridge)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.7.1 (ORCJIT, sandybridge)

Compare to:

julia> f(x) = log(x);

julia> @code_llvm f(1.0)

define double @julia_f_70640(double) #0 {
top:
  %1 = call double @julia_log_70641(double %0) #0
  ret double %1
}

This does not happen if Julia is started with --compilecache=no. Maybe related to #18465? But @code_warntype f(1.0) looks fine regardless of whether Primes is loaded.

@simonster
Copy link
Member Author

simonster commented Feb 27, 2017

Also, for fun:

julia> import Primes

julia> f(x) = log(x);

julia> @code_llvm f(1.0)

define double @julia_f_70651(double) #0 {
top:
  %ptls_i8 = call i8* asm "movq %fs:0, $0;\0Aaddq $$-2672, $0", "=r,~{dirflag},~{fpsr},~{flags}"() #2
  %ptls = bitcast i8* %ptls_i8 to %jl_value_t***
  %1 = alloca [4 x %jl_value_t*], align 8
  %.sub = getelementptr inbounds [4 x %jl_value_t*], [4 x %jl_value_t*]* %1, i64 0, i64 0
  %2 = getelementptr [4 x %jl_value_t*], [4 x %jl_value_t*]* %1, i64 0, i64 2
  %3 = bitcast %jl_value_t** %2 to i8*
  call void @llvm.memset.p0i8.i32(i8* %3, i8 0, i32 16, i32 8, i1 false)
  %4 = bitcast [4 x %jl_value_t*]* %1 to i64*
  store i64 4, i64* %4, align 8
  %5 = getelementptr [4 x %jl_value_t*], [4 x %jl_value_t*]* %1, i64 0, i64 1
  %6 = bitcast i8* %ptls_i8 to i64*
  %7 = load i64, i64* %6, align 8
  %8 = bitcast %jl_value_t** %5 to i64*
  store i64 %7, i64* %8, align 8
  store %jl_value_t** %.sub, %jl_value_t*** %ptls, align 8
  %9 = getelementptr [4 x %jl_value_t*], [4 x %jl_value_t*]* %1, i64 0, i64 3
  store %jl_value_t* inttoptr (i64 140028128294704 to %jl_value_t*), %jl_value_t** %2, align 8
  %10 = call %jl_value_t* @jl_gc_pool_alloc(i8* %ptls_i8, i32 1432, i32 16)
  %11 = getelementptr inbounds %jl_value_t, %jl_value_t* %10, i64 -1, i32 0
  store %jl_value_t* inttoptr (i64 140028071112528 to %jl_value_t*), %jl_value_t** %11, align 8
  %12 = bitcast %jl_value_t* %10 to double*
  store double %0, double* %12, align 8
  store %jl_value_t* %10, %jl_value_t** %9, align 8
  %13 = call %jl_value_t* @jl_invoke(%jl_value_t* inttoptr (i64 140028189719904 to %jl_value_t*), %jl_value_t** %2, i32 2)
  %14 = bitcast %jl_value_t* %13 to double*
  %15 = load double, double* %14, align 16
  %16 = load i64, i64* %8, align 8
  store i64 %16, i64* %6, align 8
  ret double %15
}

julia> f(1.0)
0.0

julia> @code_llvm f(1.0)

define double @julia_f_70651(double) #0 {
top:
  %1 = call double @julia_log_70659(double %0) #0
  ret double %1
}

(and it's not just code_llvm that is showing the suboptimal calling convention; the code itself is allocating after importing Primes)

@simonster
Copy link
Member Author

Also, FWIW, this does not happen on master.

@yuyichao
Copy link
Contributor

Dup of #18465

@yuyichao yuyichao changed the title Break calling convention for log with unrelated module Break type inference for log with unrelated module Feb 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants