<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 --- - [Thumb2] Rebase ld/st to avoid negative offsets"
   href="https://llvm.org/bugs/show_bug.cgi?id=31232">31232</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[Thumb2] Rebase ld/st to avoid negative offsets
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </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>new bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>weimingz@codeaurora.org
          </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>given test.c:

typedef struct
{
 unsigned char* Src;
 unsigned char* Dst;
 unsigned int Len;
} ContextType;

void test(ContextType* pContext)
{
   unsigned char* Src = (pContext->Src) - 26;
   unsigned int Offset = (pContext->Len) - 26;
   unsigned char* pDst = pContext->Dst;
   unsigned int dest_p1 = *((unsigned int*)(&Src[4]));
   unsigned short dest_p2 = *((unsigned short*)(&Src[8]));
   unsigned short src_p1 = *((unsigned short*)(&Src[10]));
   unsigned int src_p2 = *((unsigned int*)(&Src[12]));
   unsigned short EType = *((unsigned short*)(&Src[24]));
   *((unsigned int*)(&pDst[4+Offset])) = dest_p1;
   *((unsigned short*)(&pDst[8+Offset])) = dest_p2;
   *((unsigned short*)(&pDst[10+Offset])) = src_p1;
   *((unsigned int*)(&pDst[12+Offset])) = src_p2;
   *((unsigned short*)(&pDst[24+Offset])) = EType;
}

clang -Os -mcpu=cortex-m3 test.c -o llvm.s generates:

@ BB#0:                                 @ %entry
    .save    {r4, r6, r7, lr}
    push    {r4, r6, r7, lr}
    .setfp    r7, sp, #8
    add    r7, sp, #8
    ldrd    r1, lr, [r0]
    ldr    r0, [r0, #8]
    ldrh    r12, [r1, #-2]
    ldrh    r3, [r1, #-16]
    ldrh    r2, [r1, #-18]
    ldr    r4, [r1, #-22]
    ldr    r1, [r1, #-14]
    add    r0, lr
    str    r4, [r0, #-22]
    strh    r2, [r0, #-18]
    strh    r3, [r0, #-16]
    str    r1, [r0, #-14]
    strh    r12, [r0, #-2]
    pop    {r4, r6, r7, pc}

Since the offset are all negative, the ld/st are wide instructions. The
expected code are like:
        subs r1, #26
        subs r0, #26

            ldrh    r12, [r1, #-2]
    ldrh    r3, [r1, #10]
    ldrh    r2, [r1, #8]
    ldr    r4, [r1, #4]
    ldr    r1, [r1, #12]

    str    r4, [r0, #4]
    strh    r2, [r0, #8]
    strh    r3, [r0, #10]
    str    r1, [r0, #12]</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>