<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - Dead movs are not eliminated"
   href="https://bugs.llvm.org/show_bug.cgi?id=37534">37534</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Dead movs are not eliminated
          </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>Keywords</th>
          <td>performance
          </td>
        </tr>

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

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

        <tr>
          <th>Component</th>
          <td>Backend: ARM
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>lidija.besker@rt-rk.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mips32r2@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>While I was going through some code compiled for ARM32 I noticed a number of
what seam to be unneeded movs in code. I will give an example:

typedef struct k
{
    int m;
    int n;
} str_k;

extern int bar2(str_k *, int);

int foo(str_k *a, int b){
        if(a == NULL && b < 0) return 0;
    bar2(a, b);
    return b-a->n; 
}

For this clang generated:

00000000 <foo>:
   0:   e92d4830        push    {r4, r5, fp, lr}
   4:   e28db008        add     fp, sp, #8
   8:   e1a04001        mov     r4, r1
   c:   e1a05000        mov     r5, r0
  10:   e3500000        cmp     r0, #0
  14:   1a000004        bne     2c <foo+0x2c>
  18:   e3a00000        mov     r0, #0
  1c:   e3540000        cmp     r4, #0
  20:   aa000001        bge     2c <foo+0x2c>
  24:   e8bd4830        pop     {r4, r5, fp, lr}
  28:   e12fff1e        bx      lr
  2c:   e1a00005        mov     r0, r5
  30:   e1a01004        mov     r1, r4
  34:   ebfffffe        bl      0 <bar2>
  38:   e5950004        ldr     r0, [r5, #4]
  3c:   e0440000        sub     r0, r4, r0
  40:   e8bd4830        pop     {r4, r5, fp, lr}
  44:   e12fff1e        bx      lr

Line: 
 30:    e1a01004        mov     r1, r4
is unneeded but is generated for both -O3 and -Os optimizations, when removed
tests give expected results.

I had a look further into this problem and think it has something to do with
Machine Copy Propagation Pass (MachineCopyPropagation.cpp to be more exact
function CopyPropagateBlock) where cases like this should be handled but are
not. Reason behind that appears to be that those copy instructions that become
movs are in different blocks and checking is done only on block bases.
Same function is making unneeded movs on the end of function when saving values
by moving it to other registers which are never used and poped at the end.</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>