This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Remove hasNoInfs check for pow(C,y) -> exp2(log2(C)*y)
ClosedPublic

Authored by foad on May 5 2020, 5:10 AM.

Details

Summary

We already check hasNoNaNs and that x is finite and strictly positive.
That only leaves the following special cases (taken from the Linux man
page for pow):

If the absolute value of x is less than 1, and y is negative infinity, the result is positive infinity.
If the absolute value of x is greater than 1, and y is negative infinity, the result is +0.
If the absolute value of x is less than 1, and y is positive infinity, the result is +0.
If the absolute value of x is greater than 1, and y is positive infinity, the result is positive infinity.

The transformation preserves all of these, so there is no need to limit
it to hasNoInfs.

Diff Detail

Event Timeline

foad created this revision.May 5 2020, 5:10 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 5 2020, 5:10 AM
foad added a reviewer: arsenm.May 5 2020, 8:23 AM

pow(∞, y) → 0 if y < 0 or ∞ if y > 0
exp2(log2(∞) * y)exp2(∞ * y)exp2(∞) → 0 if y < 0 or ∞ if y > 0

foad added a comment.May 6 2020, 1:35 PM

pow(∞, y) → 0 if y < 0 or ∞ if y > 0
exp2(log2(∞) * y)exp2(∞ * y)exp2(∞) → 0 if y < 0 or ∞ if y > 0

We check that x is a finite constant before doing the transformation. It's only y that could be infinite.

pow(x, -∞) → ∞ if |x| < 1 or 0 if |x| > 1
pow(x, +∞) → 0 if |x| < 1 or ∞ if |x| > 1
exp2(log2(x) * -∞)exp2(±∞) → ∞ if x < 2 or 0 if x > 2
exp2(log2(x) * +∞)exp2(±∞) → 0 if x < 2 or ∞ if x > 2

foad added a comment.May 6 2020, 2:13 PM

exp2(log2(x) * -∞)exp2(±∞) → ∞ if x < 2 or 0 if x > 2
exp2(log2(x) * +∞)exp2(±∞) → 0 if x < 2 or ∞ if x > 2

No, the sign of log2(x) depends on whether x is less or greater than 1, not less or greater than 2.

No, the sign of log2(x) depends on whether x is less or greater than 1, not less or greater than 2.

You're right.

pow(x, -∞) → ∞ if x < 1 or 0 if x > 1
pow(x, +∞) → 0 if x < 1 or ∞ if x > 1

exp2(log2(x) * -∞)exp2(±∞) → ∞ if x < 1 or 0 if x > 1
exp2(log2(x) * +∞)exp2(±∞) → 0 if x < 1 or ∞ if x > 1

Therefore the identity holds.

foad added a comment.May 7 2020, 1:52 AM

Thanks for the careful checking. Actually there is one problematic case:
pow(1, ±∞)1
exp2(log2(1) * ±∞)exp2(0 * ±∞)exp2(NaN)NaN
I guess we never hit this case in practice because it will have been simplified elsewhere, but I will add something to the patch to handle it.

foad updated this revision to Diff 262606.May 7 2020, 4:02 AM

Rebase. Check for x == 1.

spatel added inline comments.May 7 2020, 5:06 AM
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
1690–1691

There's no way for Base to be 1.0 after here, so we can use an assert rather than 'if' clause in the new code.

foad updated this revision to Diff 262623.May 7 2020, 5:42 AM

Assert.

foad updated this revision to Diff 262625.May 7 2020, 5:45 AM

Fix silly mistake in last revision.

foad marked an inline comment as done.May 7 2020, 5:57 AM
evandro added inline comments.May 8 2020, 1:50 PM
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
1569

This comment makes more sense immediately before the assert(). Personally, it could also be shorter.

foad updated this revision to Diff 263015.May 9 2020, 5:59 AM

Move and shorten the comment.

spatel accepted this revision.May 19 2020, 6:36 AM

LGTM

This revision is now accepted and ready to land.May 19 2020, 6:36 AM
This revision was automatically updated to reflect the committed changes.