<html>
    <head>
      <base href="http://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 --- - loop vectorizer ops lose 'fast' flag"
   href="http://llvm.org/bugs/show_bug.cgi?id=19045">19045</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>loop vectorizer ops lose 'fast' flag
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

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

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

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>Loop Optimizer
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>hfinkel@anl.gov
          </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>If I compile this with clang -O3 -ffast-math on x86_64:

float foo(float *restrict s) {
  float q = 0;
  for (int i = 0; i < 1600; ++i)
    q += s[i];

  return q;
}

we get this:

define float @foo(float* noalias nocapture readonly %s) #0 {
entry:
  br label %for.body

for.body:                                         ; preds = %for.body, %entry
  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  %q.04 = phi float [ 0.000000e+00, %entry ], [ %add, %for.body ]
  %arrayidx = getelementptr inbounds float* %s, i64 %indvars.iv
  %0 = load float* %arrayidx, align 4
  %add = fadd fast float %q.04, %0
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  %exitcond = icmp eq i64 %indvars.iv.next, 1600
  br i1 %exitcond, label %for.end, label %for.body

for.end:                                          ; preds = %for.body
  %add.lcssa = phi float [ %add, %for.body ]
  ret float %add.lcssa
}

attributes #0 = { nounwind readonly uwtable }

vectorizing this gives the following:

...
  %8 = fadd <4 x float> %vec.phi, %wide.load
  %9 = fadd <4 x float> %vec.phi9, %wide.load12
...

and for the reduction:

middle.block:                                     ; preds = %vector.body
  %.lcssa14 = phi <4 x float> [ %5, %vector.body ]
  %.lcssa = phi <4 x float> [ %4, %vector.body ]
  %bin.rdx = fadd <4 x float> %.lcssa14, %.lcssa
  %rdx.shuf = shufflevector <4 x float> %bin.rdx, <4 x float> undef, <4 x i32>
<i32 2, i32 3, i32 undef, i32 undef>
  %bin.rdx10 = fadd <4 x float> %bin.rdx, %rdx.shuf
  %rdx.shuf11 = shufflevector <4 x float> %bin.rdx10, <4 x float> undef, <4 x
i32> <i32 1, i32 undef, i32 undef, i32 undef>
  %bin.rdx12 = fadd <4 x float> %bin.rdx10, %rdx.shuf11
  %7 = extractelement <4 x float> %bin.rdx12, i32 0
  ret float %7

note that these 'fadd' instructions are missing the 'fast' flag, even though
the original reduction operation had the 'fast' flag. So this flag is missing
both on the reduction from the unrolling and on the actual horizontal piece (in
addition to in the loop body).</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>