# Trivial code change causes vectorization failure

**URL:** <https://discourse.julialang.org/t/trivial-code-change-causes-vectorization-failure/20299>\
**Category:** Performance\
**Created:** [January 31, 2019, 1:59am UTC](https://discourse.julialang.org/t/trivial-code-change-causes-vectorization-failure/20299 "2019-01-31T01:59:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)\
**Post date:** [January 31, 2019, 1:59am UTC](https://discourse.julialang.org/t/trivial-code-change-causes-vectorization-failure/20299/1 "2019-01-31T01:59:00Z")

</div>

I am porting a few approximate math functions that I’ve used before that vectorized well, but noticed that with Julia the direct translation fails to vectorize. However, a trivial change (expanding `s = f * f`) makes Julia produce nicely vectorized LLVM-IR.

Is Julia’s optimizer just that fragile? Or is there a reason why `fastexp1` is more difficult to optimize? As a comparison, Rust is able to optimize both versions. I’ve tried using explicit `muladd()`s, but the results are the same.

```julia
@fastmath function fastlog1(x::Float32)::Float32
    xi = reinterpret(Int32, x)
    e = (xi - Int32(1059760811)) & Int32(-8388608)
    m = reinterpret(Float32, xi - e)
    i = e * 1.19209290f-7
    f = m - 1f0
    s = f * f
    r = 0.230836749f0 * f + -0.279208571f0
    t = 0.331826031f0 * f + -0.498910338f0
    r = r * s + t
    r = r * s + f
    i * 0.693147182f0 + r
end

@fastmath function fastlog2(x::Float32)::Float32
    xi = reinterpret(Int32, x)
    e = (xi - Int32(1059760811)) & Int32(-8388608)
    m = reinterpret(Float32, xi - e)
    i = e * 1.19209290f-7
    f = m - 1f0
    #s = f * f
    r = 0.230836749f0 * f + -0.279208571f0
    t = 0.331826031f0 * f + -0.498910338f0
    r = r * (f*f) + t # replaced s here
    r = r * (f*f) + f # and here
    i * 0.693147182f0 + r
end

@fastmath function test(f)
    s = 0.0
    for i in Int32(1):Int32(1_000_000_000)
        s += f(Float32(i))
    end
    s
end

```

```julia
julia> @btime test(fastlog1)
  2.366 s (0 allocations: 0 bytes)
1.9723269760895107e10
julia> @btime test(fastlog2)
  524.180 ms (0 allocations: 0 bytes)
1.9723269761215004e10

```

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [January 31, 2019, 2:21am UTC](https://discourse.julialang.org/t/trivial-code-change-causes-vectorization-failure/20299/2 "2019-01-31T02:21:44Z")

</div>

Good question. ~~If nothing else, it seems like dead code elimination may be run too early.~~ Edit: I misunderstood the difference, thanks.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [January 31, 2019, 5:27pm UTC](https://discourse.julialang.org/t/trivial-code-change-causes-vectorization-failure/20299/3 "2019-01-31T17:27:57Z")

</div>

Absent any more comments, I’d file an issue about this.

---

<div class="post-metadata">

**Author:** ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)\
**Post date:** [February 1, 2019, 9:03am UTC](https://discourse.julialang.org/t/trivial-code-change-causes-vectorization-failure/20299/4 "2019-02-01T09:03:11Z")

</div>

Filed:  
[https://github.com/JuliaLang/julia/issues/30933](https://github.com/JuliaLang/julia/issues/30933)
