<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW " title="NEW --- - After r228826, fdiv can be hoisted incorrectly on i386" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__llvm.org_bugs_show-5Fbug.cgi-3Fid-3D24343&d=AwMBaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=UjsiDHFMDWdc5bT3Yq69RDZtx9dnlU6KYjHwxlL0sj4&s=GHssC_9dnZhHStPlm44w3EMIc70z_4A3WEw_Lrq4DPo&e=">24343</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>After r228826, fdiv can be hoisted incorrectly on i386
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>dimitry@andric.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>During a mass test build of the FreeBSD ports collection with a recent clang
trunk snapshot, we ran into strange libpng failures on i386:

<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__package18.nyi.freebsd.org_data_headi386PR201377-2Ddefault_2015-2D07-2D31-5F12h04m22s_logs_errors_png-2D1.6.17-5F1.log&d=AwMBaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=UjsiDHFMDWdc5bT3Yq69RDZtx9dnlU6KYjHwxlL0sj4&s=8wEgguhyFYBdc74VAK7TtVpkjQls6tMouKW-Tn6w1qk&e=">http://package18.nyi.freebsd.org/data/headi386PR201377-default/2015-07-31_12h04m22s/logs/errors/png-1.6.17_1.log</a>

After some digging, it turned out that the failing tests get a 'division by
zero' floating point exception, when calling pow() with a 0 first argument. 
Note that all libpng tests enable such floating point exceptions using
feenableexcept(3).

The FPE occurs in the following part of pow()'s FreeBSD implementation, on line
166:

   161      /* special value of x */
   162          if(lx==0) {
   163              if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
   164                  z = ax;                 /*x is +-0,+-inf,+-1*/
   165                  if(hy<0)
   166                      z = 1.0/z;          /* z = (1/|x|) */
   167                  if(hx<0) {
   168                      if(((ix-0x3ff00000)|yisint)==0) {
   169                          z = (z-z)/(z-z); /* (-1)**non-int is NaN */
   170                      } else if(yisint==1)
   171                          z = -z;         /* (x<0)**odd = -(|x|**odd) */
   172                  }
   173                  return z;
   174              }
   175          }

However, for the particular tests, at line 165 'hy' is zero, so line 166 should
really have been skipped.  But inspection of the assembly (in this case
produced by trunk r241361) shows that the fdiv has been incorrectly hoisted
above the conditional jump (js .LBB_024):

.Ltmp96:
        #DEBUG_VALUE: pow:ix <- ESI
        #DEBUG_VALUE: pow:yisint <- 0
        #DEBUG_VALUE: pow:z <- FP3
        #DEBUG_VALUE: pow:ax <- FP3
        .loc    1 165 8 is_stmt 1       # e_pow.c:165:8
        cmpl    $0, 36(%esp)            # 4-byte Folded Reload
        .loc    1 166 14                # e_pow.c:166:14
        fld1
        fdiv    %st(1)
.Ltmp97:
        #DEBUG_VALUE: pow:z <- FP1
        js      .LBB0_24
.Ltmp98:
# BB#23:                                # %if.then.107
        fstp    %st(0)

Compare this with the correct output of clang 3.6.1, where the fdiv is only
done in case the conditional fails:

.Ltmp101:
        #DEBUG_VALUE: pow:ix <- ESI
        #DEBUG_VALUE: pow:yisint <- 0
        #DEBUG_VALUE: pow:z <- FP1
        #DEBUG_VALUE: pow:ax <- FP1
        .loc    1 165 6 is_stmt 1       # e_pow.c:165:6
        cmpl    $0, 36(%esp)            # 4-byte Folded Reload
        jns     .LBB0_24
.Ltmp102:
# BB#23:                                # %if.then108
        #DEBUG_VALUE: pow:ix <- ESI
        #DEBUG_VALUE: pow:yisint <- 0
        #DEBUG_VALUE: pow:z <- FP1
        #DEBUG_VALUE: pow:ax <- FP1
        fld1
        .loc    1 166 11                # e_pow.c:166:11
.Ltmp103:
        fdivp   %st(1)
.Ltmp104:
.LBB0_24:                               # %if.end110

Bisecting showed that this invalid hoisting has been introduced by r228826,
"[SimplifyCFG] Swap to using TargetTransformInfo for cost analysis".  I am
unsure why, though; it does not seem to touch i387 FP code directly?

Here is a minimal C test case to show the issue; it can also be run to show the
FPE:

#include <fenv.h>

__attribute__((__noinline__)) double foo(int n, double d)
{
  if (n > 0)
    d = 1.0 / d;
  return d;
}

int main(void)
{
  feenableexcept(FE_DIVBYZERO);
  return (int)foo(0, 0.0);
}

Compile this with:  clang -target i386-freebsd -O2 -S bad-hoist.c

Correct result with clang at r228825:

foo:                                    # @foo
# BB#0:                                 # %entry
    pushl    %ebp
    movl    %esp, %ebp
    fldl    12(%ebp)
    cmpl    $0, 8(%ebp)
    jle    .LBB0_2
# BB#1:                                 # %if.then
    fld1
    fdivp    %st(1)
.LBB0_2:                                # %if.end

Bad result with clang at r228826:

foo:                                    # @foo
# BB#0:                                 # %entry
    pushl    %ebp
    movl    %esp, %ebp
    fldl    12(%ebp)
    cmpl    $0, 8(%ebp)
    fld1
    fdiv    %st(1)
    jg    .LBB0_2
# BB#1:                                 # %entry
    fstp    %st(0)
    fldz
    fxch    %st(1)
.LBB0_2:                                # %entry</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>