When the visitSub method was split into visitSub and visitFSub, this xform was
authorBill Wendling <isanbard@gmail.com>
Wed, 13 Jan 2010 23:23:17 +0000 (23:23 +0000)
committerBill Wendling <isanbard@gmail.com>
Wed, 13 Jan 2010 23:23:17 +0000 (23:23 +0000)
commit22f3b9faaca03e3da987955bb75e867d3af7bffe
treeebb1bbc18a457e97dc7db787500a2e0f03a93cce
parentedd1cc78d2bc6e07679489278460bae2d56a501d
When the visitSub method was split into visitSub and visitFSub, this xform was
added to the FSub version. However, the original version of this xform guarded
against doing this for floating point (!Op0->getType()->isFPOrFPVector()).

This is causing LLVM to perform incorrect xforms for code like:

void func(double *rhi, double *rlo, double xh, double xl, double yh, double yl){
  double mh, ml;
  double c = 134217729.0;
  double up, u1, u2, vp, v1, v2;

  up = xh*c;
  u1 = (xh - up) + up;
  u2 = xh - u1;

  vp = yh*c;
  v1 = (yh - vp) + vp;
  v2 = yh - v1;

  mh = xh*yh;
  ml = (((u1*v1 - mh) + (u1*v2)) + (u2*v1)) + (u2*v2);
  ml += xh*yl + xl*yh;

  *rhi = mh + ml;
  *rlo = (mh - (*rhi)) + ml;
}

The last line was optimized away, but rl is intended to be the difference
between the infinitely precise result of mh + ml and after it has been rounded
to double precision.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93369 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Transforms/InstCombine/InstCombineAddSub.cpp
test/Transforms/InstCombine/fsub-fadd.ll [new file with mode: 0644]