<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 condition left after removal of branch that used it"
   href="https://bugs.llvm.org/show_bug.cgi?id=37535">37535</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Dead condition left after removal of branch that used it
          </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>I have been looking into some code compiled for ARM32 using LLVM and I noticed
that in some cases -O3 and -Os optimizations leave excess instructions. I have
made a mini example where that can be seen:

typedef union df_union {
        int    *set;
        int     state;
} df;

int n;
df *d;

int foo1(int index){
        if ((n && !d[index].set) || (!n && !d[index].state)) {
                return --index;                 
        }                       
        return 0;       
}


For this clang generated: 

00000000 <foo1>:
   0:   e59f1024        ldr     r1, [pc, #36]   ; 2c <foo1+0x2c>
   4:   e59f2024        ldr     r2, [pc, #36]   ; 30 <foo1+0x30>
   8:   e5922000        ldr     r2, [r2]
   c:   e5911000        ldr     r1, [r1]
  10:   e3520000        cmp     r2, #0
  14:   e7912100        ldr     r2, [r1, r0, lsl #2]
  18:   e3a01000        mov     r1, #0
  1c:   e3520000        cmp     r2, #0
  20:   02401001        subeq   r1, r0, #1
  24:   e1a00001        mov     r0, r1
  28:   e12fff1e        bx      lr


cmp and loads that it uses are excess and when removed function continues to
give expected result. 

I had a look into it and it appears to be caused by merging of basic blocks and
removal of conditional branch whose condition is computed using excess
instructions which are left behind. This happens in Control Flow Optimizes pass
in BranchFolding.cpp in function OptimizeBlock where ARM's removeBranch is
called, none of them removes condition calculation.</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>