Issue 1:
@NHDaly and I found this the day before juliacon, but forgot to open an issue.

I think @Keno's theory was that the literal_pow stuff broke this.

Basically constant folding stops for exponents greater than 4.

julia> @code_typed (()->10^4)()
CodeInfo(
1 ─ nothing::Nothing
2 ┄ %2 = φ (#1 => 10, #3 => %7)::Int64
│ %3 = φ (#1 => 3, #3 => %4)::Int64
│ %4 = Base.sub_int(%3, 1)::Int64
│ %5 = Base.slt_int(0, %4)::Bool
└── goto #4 if not %5
3 ─ %7 = Base.mul_int(%2, %2)::Int64
└── goto #2
4 ─ goto #5
5 ─ goto #6
6 ─ goto #7
7 ─ return %2
) => Int64

julia> @code_typed (()->10^3)()
CodeInfo(
1 ─ return 1000
) => Int64

julia> @code_typed (()->10^2)()
CodeInfo(
1 ─ return 100
) => Int64

julia> @code_typed (()->10^1)()
CodeInfo(
1 ─ return 10
) => Int64

julia> @code_typed (()->10^0)()
CodeInfo(
1 ─ return 1
) => Int64

julia> @code_typed (()->10^-1)()
CodeInfo(
1 ─ return 0.1
) => Float64

julia> @code_typed (()->10^-2)()
CodeInfo(
1 ─ return 0.010000000000000002
) => Float64

julia> @code_typed (()->10^-3)()
CodeInfo(
1 ─ return 0.0010000000000000002
) => Float64

julia> @code_typed (()->10^-4)()
CodeInfo(
1 ─ %1 = $(Expr(:foreigncall, "llvm.pow.f64", Float64, svec(Float64, Float64), 0, :(:llvmcall), 0.1, 4.0, 4.0, 0.1))::Float64
└── return %1
) => Float64

LLVM actually has our back here though.

It will constant fold for all negative integer powers I think.

julia> @code_llvm (()->10^-4)()

; @ REPL[15]:1 within `#35'
define double @"julia_#35_16849"() {
top:
ret double 0x3F1A36E2EB1C432E
}

julia> @code_llvm (()->10^-100)()

; @ REPL[19]:1 within `#43'
define double @"julia_#43_16854"() {
top:
ret double 0x2B2BFF2EE48E055C
}

But for positive powers it only does 1 extra: 10^4

julia> @code_llvm (()->10^4)()

; @ REPL[16]:1 within `#37'
define i64 @"julia_#37_16850"() {
top:
ret i64 10000
}

julia> @code_llvm (()->10^5)()

; @ REPL[17]:1 within `#39'
define i64 @"julia_#39_16851"() {
L21.lr.ph:
; ┌ @ none within `literal_pow'
; │┌ @ none within `macro expansion'
; ││┌ @ intfuncs.jl:221 within `^'
; │││┌ @ intfuncs.jl:208 within `power_by_squaring'
br label %L21

L21: ; preds = %L21.lr.ph, %L21
%0 = phi i64 [ 1, %L21.lr.ph ], [ %2, %L21 ]
%value_phi35 = phi i64 [ 10, %L21.lr.ph ], [ %1, %L21 ]
; ││││ @ intfuncs.jl:209 within `power_by_squaring'
; ││││┌ @ int.jl:54 within `*'
%1 = mul i64 %value_phi35, %value_phi35
; ││││└
; ││││ @ intfuncs.jl:208 within `power_by_squaring'
; ││││┌ @ int.jl:52 within `-'
%2 = add nsw i64 %0, -1
; ││││└
; ││││┌ @ operators.jl:341 within `>='
; │││││┌ @ int.jl:410 within `<='
%3 = icmp slt i64 %0, 1
; ││││└└
br i1 %3, label %L23, label %L21

L23: ; preds = %L21
%phitmp = mul i64 %1, 10
; └└└└
ret i64 %phitmp
}

Was reminded when this came up in https://discourse.julialang.org/t/no-constant-expression-elimination-for-e-g-2-24-1/30964/8

Issue 2:
Have a look at:

julia> f() = 2^5; @code_native f()
.text
; Function f {
; Location: none:1
; Function literal_pow; {
; Location: none
; Function macro expansion; {
; Location: none
; Function ^; {
; Location: none:1
pushq %rax
movabsq $power_by_squaring, %rax
movl $2, %edi
movl $5, %esi
callq *%rax
;}}}
popq %rcx
retq
nopl (%rax)
;}

This behaviour is weird. Since the result is completely fixed, shouldn't it compile all the way down to "return this predefined number" instead of requiring a new function call?

To make things weirder, the following functions do compile down to "return this number":

m() = 2^8; n() = 3^4; g() = 2.0^5; h() = 2^5.0, k() = 1<<5

In practice, this means that running k() is unnecessarily ~3x faster than f(). Is this a bug that should be fixed?

Environment:

julia> versioninfo()
Julia Version 1.0.0
Commit 5d4eaca0c9 (2018-08-08 20:58 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Core(TM) i5-4210H CPU @ 2.90GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.0 (ORCJIT, haswell)
Environment:
JULIA_EDITOR = atom -a
JULIA_NUM_THREADS = 2