<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 --- - LoopSimplify canonicalization causes poor codegen"
   href="https://llvm.org/bugs/show_bug.cgi?id=28798">28798</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>LoopSimplify canonicalization causes poor codegen
          </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>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>Loop Optimizer
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>james.molloy@arm.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>In the attached testcase, there is one loop with two continues. LoopSimplify
converts this into three nested loops, which while correct makes the code
difficult to understand and causes extra MOVs to be generated, increasing
register pressure.

Is this the intended canonicalization for this loop, or is loopsimplify
canonicalizing incorrectly? I understand the underlying purpose for this
particular canonicalization, but don't know if it's right to apply it in this
case. Alternatively, are the lowering phases missing something? or perhaps the
canonicalization just needs to be undone at CGP time?

The testcase:

void test(char *value_pat, char *idx_pat, int *ptr, unsigned n) {
    int value_rpt = 0;
    int idx_rpt = 0;
    int value, idx;
    char *vpt = value_pat;
    char *ipt = idx_pat;
    while (n) {
    if (value_rpt == 0) {
        value_rpt = *value_pat++;
        value = *value_pat++;
        if (value_rpt == 0)
        value_pat = vpt;
        continue;
    }
    if (idx_rpt == 0) {
        idx_rpt = *idx_pat++;
        idx = *idx_pat++;
        if (idx_rpt == 0)
        idx_pat = ipt;
        continue;
    }
    *ptr = value;
    ptr += idx;
    --n;
    }
}

Compiling for ARM:

_Z4testPcS_Pij:
    .fnstart
@ BB#0:                                 @ %entry
    .save    {r4, r5, r6, r7, r8, r9, r10, r11, lr}
    push.w    {r4, r5, r6, r7, r8, r9, r10, r11, lr}
    mov.w    r12, #0
    mov.w    r8, #0
    mov    r10, r1
    mov    r11, r0
                                        @ implicit-def: %LR
                                        @ implicit-def: %R9
.LBB0_1:                                @ %while.cond.outer
                                        @ =>This Loop Header: Depth=1
                                        @     Child Loop BB0_2 Depth 2
                                        @       Child Loop BB0_3 Depth 3
    cbz    r3, .LBB0_8
.LBB0_2:                                @ %while.cond.outer30
                                        @   Parent Loop BB0_1 Depth=1
                                        @ =>  This Loop Header: Depth=2
                                        @       Child Loop BB0_3 Depth 3
***    mov    r4, r8  *** BAD - not needed!
***    mov    r6, r9  *** BAD
***    mov    r7, r10 *** BAD
.LBB0_3:                                @ %while.cond
                                        @   Parent Loop BB0_1 Depth=1
                                        @     Parent Loop BB0_2 Depth=2
                                        @ =>    This Inner Loop Header: Depth=3
    cmp.w    r12, #0
    bne    .LBB0_5
@ BB#4:                                 @ %if.then
                                        @   in Loop: Header=BB0_2 Depth=2
    ldrb.w    r12, [r11]
    ldrb.w    lr, [r11, #1]
    mov    r4, r0
    cmp.w    r12, #0
    it    ne
    addne.w    r4, r11, #2
    mov    r11, r4
    b    .LBB0_2
.LBB0_5:                                @ %if.end5
                                        @   in Loop: Header=BB0_3 Depth=3
    cbnz    r4, .LBB0_7
@ BB#6:                                 @ %if.then7
                                        @   in Loop: Header=BB0_3 Depth=3
    ldrb    r4, [r7]
    ldrb    r6, [r7, #1]
    mov    r5, r1
    cmp    r4, #0
    it    ne
    addne    r5, r7, #2
    mov    r7, r5
    b    .LBB0_3
.LBB0_7:                                @ %if.end15
                                        @   in Loop: Header=BB0_1 Depth=1
    str.w    lr, [r2]
    add.w    r2, r2, r6, lsl #2
    subs    r3, #1
    mov    r8, r4
    mov    r9, r6
    mov    r10, r7
    b    .LBB0_1
.LBB0_8:                                @ %while.end.split
    pop.w    {r4, r5, r6, r7, r8, r9, r10, r11, pc}
.Lfunc_end0:
    .size    _Z4testPcS_Pij, .Lfunc_end0-_Z4testPcS_Pij
    .cantunwind
    .fnend</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>