<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 9/27/2016 11:57 AM, Matthew O'Connor
      via llvm-dev wrote:<br>
    </div>
    <blockquote
cite="mid:CA+XmMRXXxjTAh2WmerhnQyL_=OCAeW4+aZL_09fKo_YPL_nJ4Q@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div>
          <div>
            <div>Hi,<br>
              <br>
            </div>
            I'm attempting to understand why in the following C++ code
            LLVM produes cycles in the IR (for `cycle1` and `cycle2`,
            that do not have data-dependent cycles), but `nocycle` is
            not. In the first two cases, `Count` has an undefined value
            when `Count + 1` is evaluated and the value is scoped to the
            body of the loop so can't (or shouldn't) hold values from
            one iteration to the next, but in `clang++ -std=c++11
            sample.cpp -S -emit-llvm -OX -o sample.ll` where X = any of
            0,1,2,3,s,z, a data-dependent cycle is created - like below:<br>
            <br>
          </div>
          <div style="margin-left:40px">%for.body:<br>
          </div>
          <div>
            <div style="margin-left:40px">  Count.012 = phi i32 [ undef,
              %entry ], [ %cond.i, %for.body ]<br>
                %add = add nsw i32 %Count.012, 1<br>
                %cond.i = select i1 %call, i32 %0, i32 %add<br>
            </div>
            <br>
          </div>
          Thanks,<br>
        </div>
        Matt<br>
        <div>
          <div><br>
            <div style="margin-left:40px">int select(bool P, int True,
              int False) { return P ? True : False; }<br>
              <br>
              bool random(void);<br>
              <br>
              void cycle1(int (&Input)[100], int (&Output)[100])
              {<br>
                for (int I = 0, N = 100; I < N; ++I) {<br>
                  int Count;<br>
              <br>
                  Count = select(random(), Input[I], Count + 1);<br>
              <br>
                  Output[I] = Count;<br>
                }<br>
              }<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    It's a missed optimization; LLVM doesn't really work with scopes the
    way you might expect.  If you turn off optimization and emit LLVM
    IR, you'll see that memory for "Count" is allocated with the
    "alloca" instruction in the entry block of the function.  When that
    gets converted to a register value, it's done in a way which isn't
    sensitive to the lifetime of the variable, as marked with lifetime
    intrinsics.  See lib/Transforms/Utils/PromoteMemoryToRegister.cpp
    for the actual algorithm.<br>
    <br>
    -Eli<br>
    <pre class="moz-signature" cols="72">-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project</pre>
  </body>
</html>