# Can constant propagation transform integer powers of -1 to an if/else?

**URL:** <https://discourse.julialang.org/t/can-constant-propagation-transform-integer-powers-of-1-to-an-if-else/100462>\
**Category:** Performance\
**Tags:** math\
**Created:** [June 16, 2023, 6:13pm UTC](https://discourse.julialang.org/t/can-constant-propagation-transform-integer-powers-of-1-to-an-if-else/100462 "2023-06-16T18:13:53Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [June 16, 2023, 6:13pm UTC](https://discourse.julialang.org/t/can-constant-propagation-transform-integer-powers-of-1-to-an-if-else/100462/1 "2023-06-16T18:13:53Z")

</div>

```julia
julia> @btime (n -> [iseven(k) ? 1 : (-1) for k in 1:n])(500);
  890.571 ns (1 allocation: 4.06 KiB)

julia> @btime (n -> [(-1)^k for k in 1:n])(500);
  6.170 μs (1 allocation: 4.06 KiB)

```

It would be great if the latter could be transformed into the former through constant propagation. I wonder if there are edge cases where this won’t hold?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 16, 2023, 8:14pm UTC](https://discourse.julialang.org/t/can-constant-propagation-transform-integer-powers-of-1-to-an-if-else/100462/2 "2023-06-16T20:14:17Z")

</div>

I think you should be able to add a special case here:

> <https://github.com/JuliaLang/julia/blob/631d187b741ae0f391ba1bd067c32382f3122473/base/intfuncs.jl#L277-L287>

But, optimizing for special cases like this is detrimental for the performance of the general case, so I’m not sure this would be a good idea.

Another possibility would be using parser tricks like with `literal_pow`, but that has its own issues.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 16, 2023, 8:26pm UTC](https://discourse.julialang.org/t/can-constant-propagation-transform-integer-powers-of-1-to-an-if-else/100462/3 "2023-06-16T20:26:57Z")

</div>

The [FastPow.jl](https://github.com/JuliaMath/FastPow.jl) package will do this transformation.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 16, 2023, 8:37pm UTC](https://discourse.julialang.org/t/can-constant-propagation-transform-integer-powers-of-1-to-an-if-else/100462/4 "2023-06-16T20:37:42Z")

</div>

`k` is not a constant here so it’s something other than constant propagation. I’m not sure where a `-1` branch should be put if that’s the way to do it. It also occurs to me, the branch shouldn’t just be for `-1`, right; any negative value to the power of a `k::Integer` can check `k` for evenness to calculate the sign and compute the absolute value to that power, and so `(-1)^k` should boil down to `1^k` with its own `1` branch.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [June 16, 2023, 8:55pm UTC](https://discourse.julialang.org/t/can-constant-propagation-transform-integer-powers-of-1-to-an-if-else/100462/5 "2023-06-16T20:55:01Z")

</div>

I sometimes like to define `^` on the function `-` so that I can write `(-)^n` instead of `(-1)^n` and have it be efficient

```julia
julia> Base.:(^)(::typeof(-), n::Int) = iseven(n) ? 1 : (-1);

julia> Base.literal_pow(::typeof(^), ::typeof(-), ::Val{n}) where {n} = (-)^n;

julia> (-)^-1
-1

julia> (-)^-2
1

julia> (-)^100
1

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [June 16, 2023, 10:01pm UTC](https://discourse.julialang.org/t/can-constant-propagation-transform-integer-powers-of-1-to-an-if-else/100462/6 "2023-06-16T22:01:11Z")

</div>

```julia
Base.:(^)(::Val{-1},n)=(-1)^mod(n,2)
Base.:(^)(::Val{-1},n)=(-1)^(n & 1)

```
