This is an archive of the discontinued LLVM Phabricator instance.

[SimplifyLibCalls] pow(x, 0.5) -> fabs(sqrt(x)) (finite-only-mode)
AbandonedPublic

Authored by davide on Jul 7 2016, 11:48 AM.

Details

Summary

This is a new version of http://reviews.llvm.org/D16833 as mgrang has no more time to work on the feature.
This patch substantially differ from the previous version. The original patch applied the transformation if:
if (Op1C->getValueAPF().isFinite())

I don't think this is the correct way of checking we're in finite-mode only. Instead, checked that the function has the attributes no-nans-fp-math and no-infs-fp-math both set to true. I hope I wasn't entirely wrong in my analysis. In any case, comments welcome.

Also, this adds a test (which wasn't included in the original revision).

cc:ing Steve Canon so that he can confirm/deny if this makes sense from a mathematical point of view.

Diff Detail

Event Timeline

davide updated this revision to Diff 63107.Jul 7 2016, 11:48 AM
davide retitled this revision from to [SimplifyLibCalls] pow(x, 0.5) -> fabs(sqrt(x)) (finite-only-mode).
davide updated this object.
davide added reviewers: majnemer, spatel, scanon.
davide added a subscriber: llvm-commits.
majnemer added inline comments.Jul 7 2016, 11:55 AM
lib/Transforms/Utils/SimplifyLibCalls.cpp
1071

Hmm. Why not check to see if the call-site is annotated with ninf nnan?

davide updated this revision to Diff 63120.Jul 7 2016, 1:01 PM

Like this or you meant something different?

Also, maybe we can do this separately, but after discussing with Sanjay I concluded that maybe it's a good idea to emit intrinsics instead of libcalls here as optimizeSqrt() does? David, what do you think?

davide planned changes to this revision.Jul 13 2016, 11:14 AM

This doesn't preserve FMF across calls, need to modify to take that in account (thanks to Sanjay for the suggestion offline)

spatel edited edge metadata.Jul 14 2016, 9:24 AM

Sorry - didn't mean to back-channel a review. I just noticed that the test case starts with an LLVM intrinsic and ends with libcalls. That means we've artificially (if it's ok for scalars, then it's ok for vectors) excluded the vector variant of an 'llvm.pow' from this transform. There was also a proposal to change all libcalls to intrinsics when possible, so I think we're just creating extra work for that pass if we create libcalls here.

Possible changes to make this transform more general:

  1. Switch the dyn_cast check for ConstantFP to "match(X, m_SpecificFP(0.5))" (this should work with a vector splat constant).
  2. Use llvm.fabs/sqrt intrinsics so the transform works with vectors.
  3. Check the 'nsz' FMF too; ie, for the case that James and Eli noted, 'nsz' should let us eliminate the fabs.
This revision was automatically updated to reflect the committed changes.
davide reopened this revision.Aug 7 2016, 1:37 PM
davide abandoned this revision.Dec 23 2016, 8:13 AM

It's not obvious this transformation buys something, abandoning for now.