[llvm-bugs] [Bug 27153] New: InstCombine

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Mar 30 20:23:07 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=27153

            Bug ID: 27153
           Summary: InstCombine
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: davemm at cs.rutgers.edu
                CC: llvm-bugs at lists.llvm.org,
                    santosh.nagarakatte at gmail.com
    Classification: Unclassified

LLVM optimizes this code:

define float @foo(i32 %x) #0 {
entry:
  %y = and i32 %x, 268435455
  %a = sitofp i32 %y to float
  %b = fadd float %a, -8388608.0
  ret float %b
}

to:

define float @foo(i32 %x) #0 {
entry:
  %y = and i32 %x, 268435455
  %addconv = add nsw i32 %y, -8388608
  %b = sitofp i32 %addconv to float
  ret float %b
}



This program calls foo and prints the result:

#include "stdio.h"

float foo(int x);

int main(int args, char** argv) {
  float y = foo(33554434);
  printf("%f\n",y);
  return 0;
}

Without optimizations, this yields 25165824.000000
With optimizations, this yields 25165826.000000


This arises because 33554434 cannot be precisely represented as a float, so the
sitofp is constrained to return 33554432 or 33554436. This yields 25165824 or
25165828 when added to -8388608.

In the optimized code, the addition is performed in i32, yielding the exact
answer 25165826, which can be represented exactly as a float. Note that this is
different from both of the possible return values given above.


Here is the relevant code from InstCombineAddSub.cpp:


  // Check for (fadd double (sitofp x), y), see if we can merge this into an
  // integer add followed by a promotion.
  if (SIToFPInst *LHSConv = dyn_cast<SIToFPInst>(LHS)) {
    // (fadd double (sitofp x), fpcst) --> (sitofp (add int x, intcst))
    // ... if the constant fits in the integer value.  This is useful for
things
    // like (double)(x & 1234) + 4.0 -> (double)((X & 1234)+4) which no longer
    // requires a constant pool load, and generally allows the add to be better
    // instcombined.
    if (ConstantFP *CFP = dyn_cast<ConstantFP>(RHS)) {
      Constant *CI =
      ConstantExpr::getFPToSI(CFP, LHSConv->getOperand(0)->getType());
      if (LHSConv->hasOneUse() &&
          ConstantExpr::getSIToFP(CI, I.getType()) == CFP &&
          WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI, I)) {
        // Insert the new integer add.
        Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
                                              CI, "addconv");
        return new SIToFPInst(NewAdd, I.getType());
      }
    }

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160331/69e07839/attachment.html>


More information about the llvm-bugs mailing list