<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 - 16-bit loads produce incorrect code on AVR"
   href="https://bugs.llvm.org/show_bug.cgi?id=37143">37143</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>16-bit loads produce incorrect code on AVR
          </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>normal
          </td>
        </tr>

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

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

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

        <tr>
          <th>Reporter</th>
          <td>keshav.kini@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Here is a .ll file:

  target triple = "avr-atmel-none"

  define void @foo(i16* %x) {
  entry:
    %0 = load i16, i16* %x
    %neg = xor i16 %0, -1
    store i16 %neg, i16* %x
    ret void
  }

llc from trunk today, with no command line options, compiles it to the
following assembly code (after removing comments and directives):

  foo:
    mov r30, r24
    mov r31, r25
    ld  r24, Z+
    ld  r25, Z
    com r24
    com r25
    st  Z, r24
    std Z+1, r25
    ret

I believe this is incorrect.  When loading %x from Z+1:Z into r25:r24,
Z is incremented, and it is not decremented again before storing the
complemented r25:r24 back into memory at Z+1:Z.  Therefore the program
writes to a pair of memory locations which are off by one from where
it should be writing.

Here's an altered assembly listing which corrects the issue:

  foo:
    mov  r30, r24
    mov  r31, r25
    ld   r24, Z
    ldd  r25, Z+1
    com  r24
    com  r25
    st   Z, r24
    std  Z+1, r25
    ret

By the way, are LDD and STD part of the core set of instructions which
all AVR devices must support?  (I assumed that since I didn't pass
"-mcpu" to llc, its instruction selection would be limited to that
core instruction set.)  The AVR ISA manual says "Not all variants of
this instruction is available in all devices. Refer to the device
specific instruction set summary." in the sections for the LD X, LD(D)
Y, LD(D) Z, ST X, ST(D) Y, and ST(D) Z instructions; but I wasn't able
to find out whether any of the variants *are* guaranteed to be
available in all devices.

Of course, even when LDD and STD are supported on a given device, it
may be advantageous not to use them since on some devices they take
more cycles to execute than other load/store variants, if I'm not
mistaken.

About the title of this bug -- I don't really know anything about the
internals of LLVM, but I notice that in
:/lib/Target/AVR/AVRInstrInfo.td , the definitions of STPtrPiRr,
STWPtrPiRr, STPtrPdRr, and STWPtrPdRr contain references to
"post_store" and "pre_store", while the corresponding definitions
LDRdPtrPi, LDWRdPtrPi, LDRdPtrPd, and LDWRdPtrPd don't seem to have
any similar references, so I've somewhat arbitrarily blamed the load
for causing the problem.  Maybe the problem is somewhere else
entirely, though.

Thanks,
    Keshav</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>