This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Optimize (+0.0 - A) + B
Needs ReviewPublic

Authored by 4tXJ7f on Feb 29 2016, 1:26 PM.

Details

Reviewers
majnemer
Summary

Before, InstCombiner::visitFAdd() was only optimizing (-0.0 - A) + B and
not (+0.0 - A) + B because InstCombiner::dyn_castFNegVal() by default
only matches negative floating-point zeroes even though +/- 0.0 should
behave the same in this situation. This patch changes the check to
accept positive zeros and fixes a discrepancy between the names of the
optional parameter in the header and the source file for
InstCombiner::dyn_castFNegVal().

Diff Detail

Event Timeline

4tXJ7f updated this revision to Diff 49410.Feb 29 2016, 1:26 PM
4tXJ7f retitled this revision from to [InstCombine] Optimize (+0.0 - A) + B.
4tXJ7f updated this object.
4tXJ7f added a reviewer: majnemer.
4tXJ7f added a subscriber: llvm-commits.

Is this a counter-example, or am I misreading?

#include <stdio.h>

int main() {
  float a = 0.0;
  float b = -0.0;
  printf("a = %f, b = %f\n", a, b);
  printf("b - a = %f\n", b - a);
  printf("(-0.0f - a) + b = %f\n", (-0.0f - a) + b);
  printf("(+0.0f - a) + b = %f\n", (+0.0f - a) + b);
}

Ouch, I think you are right. I tested it with a = +/- 0.0 but not with zeroes for both values, sorry about that. Do you think that it would be a good idea to add a testcase to document this behavior (check that (+0.0 - A) + B does not get optimized and have a comment to explain why)? Would it be a good idea to do the optimization for +0.0 if nsz is set? The optimizer currently optimizes:

%t0 = fsub nsz float +0.000000e+00, %x
%t1 = fadd float %t0, %y

(looks like +0.000000e+00 gets turned into -0.000000e+00 and then the other optimization applies) but not:

%t0 = fsub float +0.000000e+00, %x
t1 = fadd nsz float %t0, %y

Thanks a lot!

Do you think that it would be a good idea to add a testcase to document this behavior (check that (+0.0 - A) + B does not get optimized and have a comment to explain why)?

Definitely. If you want to do that post-commit review would be fine. Commit away!

Would it be a good idea to do the optimization for +0.0 if nsz is set?

I think that would be fine, but I'm more of a dabbler in IEEE-754 than an expert. It's possible we have other canonicalizations that convert "fsub nsz 0.0, %x" into "fsub nsz -0.0, %x" (and then the usual case would take over). It's also possible that if we don't that would be a better approach anyway.

Cheers.

Tim.