<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/69629>69629</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [clang][linker] .rodata items are not word aligned for embedded Arm
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          jprofeta-rea
      </td>
    </tr>
</table>

<pre>
    ## Issue
Accessing some `const` data triggers an "UNALIGNED" UsageFault. 

Armv8-M specifies that data in "Device memory" must be aligned for access. The `.rodata` section usually resides in Flash memory which qualifies as "Device memory". Accessing non-aligned members results in a hard fault.

## Expected behavior
Data marked `const` and emitted in `.rodata` is word (4-byte) aligned.

## Details
clang version: 17.0.1

Gcc, armcc, and iar all align these items on word boundaries. 

### Demo code
```
#include <stdint.h>
#include <stdlib.h>

const uint8_t data1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
const uint8_t data2[] = {
        0x10, 0x11, 0x12, 0x13,
 0x10, 0x11, 0x12, 0x13,
        0x10, 0x11, 0x12, 0x13,
 0x10, 0x11, 0x12, 0x13,
        0x10, 0x11, 0x12, 0x13,
        0x10, 0x11, 0x12, 0x13,
        0x10, 0x11, 0x12, 0x13,
        0x10, 0x11, 0x12, 0x13,
        0x10, 0x11, 0x12, 0x13,
        0x10, 0x11, 0x12, 0x13,
        0x10, 0x11, 0x12, 0x13,
        0x10, 0x11, 0x12, 0x13,
};

static uint64_t out_data[(sizeof(data2) + sizeof(uint64_t) - 1)/sizeof(uint64_t)] = {0};

/* This function is similar to the operation performed on the target MCU. For the destination memory being written, it is required to occur in 64-bit accesses. */
void copy(uint8_t * p_dest, uint8_t * p_src, size_t len)
{
        uint64_t * p64_dest = (uint64_t *)p_dest;
        uint64_t * p64_src = (uint64_t *)p_src;

        while (len > 0)
        {
 *p64_dest = *p64_src;
                p64_dest++;
 p64_src++;
                len -= sizeof(uint64_t);
 }
}

int main(void)
{
    copy((uint8_t *)out_data, (uint8_t *)data2, sizeof(data2));
}
```

Compiled using: 
```
clang -std=c99 -flax-vector-conversions -fshort-enums -fno-unroll-loops -mfloat-abi=hard -O2 -fsigned-char -ffunction-sections -fdata-sections -g3 -gdwarf-4 -mcpu=cortex-m33 --target=arm-none-eabi -mthumb -o demo.o -Wl,-Map,"demo.map" -save-temps=obj demo.c
```
```
arm-none-eabi-gcc -std=c99 -flax-vector-conversions -fshort-enums -fno-unroll-loops -mfloat-abi=hard -O2 -fsigned-char -ffunction-sections -fdata-sections -g3 -gdwarf-4 -mcpu=cortex-m85 -mthumb -o demo.o -Wl,-Map,"demo.map" -save-temps=obj demo.c
```

### Output
clang `.rodata` from demo.map
```
   100e4    100e4       36 1 .rodata
   100e4    100e4        6     1 demo.o:(.rodata.data1)
   100e4    100e4        6     1 data1
   100ea    100ea       30     1         demo.o:(.rodata.data2)
 100ea    100ea       30     1                 data2
```

gcc `.rodata` from demo.map
```
 .rodata.data2  0x0000949c       0x30 demo.o-demo.o
                0x0000949c                data2
 .rodata.data1  0x000094cc        0x6 demo.o-demo.o
 0x000094cc                data1
 *fill*         0x000094d2 0x2
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsV1tv2zoS_jX0y4CGRNmO9eAHJ46LAtv2pcU-BhQ5ttjy4pKUk-yvX1Cir3G23QMcHBzgCIZ14cw33wxnhiQPQW0t4oJM78l0NeJdbJ1ffN95t8HIqUc-apx8XRBWEVbBxxA6JMWKFMulEBiCslsIziCQWSGcDZHMCpA8cohebbfoA3ALhLFvn5f_-vjh8-OKMAbfAt_imnc6jmFAy5je7Of0E4QdCrVRGCC2PA54qodZ4V4JBIPG-dcEZboQoUHgOjkiYeM88J7aGL62Pa-xdwkhMQsoonIWutBxrV_BY1ASQwJfax7aDAzPrRIt_Oy4HmjwcMv4GE5BsM7SAweDpkmeewydjj06h5Z7CZve53OXc2AfX3YoIkposOV75fwwukqeG-5_oLyIMLcS0KiYNFJgLpxUAZ6dl0DYfEKb14iE1Yf43LK9wsiVDsM3obndwh59UM6Sagnl3bgYl-dqH4Qg7AG4N_nBSlDcA9d6MAOxxYCgIpoAzg5sGtdZyb3CcDnnA4mBh3EgnMwJRmZF_h3klBW6kwikeghRKhvHLake3xnWqjkfHpxL8YNO2Th_GtKqHBIfSLUCcncPxUtRJJ-Kl6LMd5bvVb5P8n0K5G5Fqvv3oNkl9CAG-SpeymynzHbKbKdMdrLw70n91ZD_CP9R4fMEGv5D5FGJPo9mk6cIrotPfV1P7wmbB_UfdBvC5kN-sRoIu4fj14NWGqBQElYTtr41epaWxVsOhK0JW8LXVgXYdHbomCpAUEZp7iG6VODgduh5P7ZDv3HeoEzFnoYi91uM8Onh2xjWzvffJIao7KCQu2yDqXM--9THbAqOismOx5-d8iiTISdE51OLm01oo2Ju7X0PYT3RnvHeKQnC7V6zm6kEkwu7p2Q1IV9-Db5vXCk0TxF0Ml4fZuSqUI8z0WvOJj3iELxTSAcydTZX_QoiePEuQqJ2OR0HmOdWaUw6Gi2Q6hGKI-uDyIk9Ycsrssts-Q29w3WQJ-w-_Y5iB72rz1dXIkWTpZv5dtRK2XZM_TMnlY1guLKEzdNk3p6PPMOXk0xYfSwS9gBvBnOpPMCb4jkndqJzter0_w_O7JRGCV1a69OqeFN4WDtpiJJUK1HXQDeav9A9iug8Fc7mZTUA3YTW-UjRdia9WUc7653WVDu3C0DNRjseKW8UqVb91oF-YUmtX8WpaLkHujlUJ837mgSVvDt731ZAt_KZ-w2dADVi1yVuzkd8oaaqgNKhWEm14t5Q6yxS5I0CamLbmQaoA4nGjR3Qf2vCHugnvksNjLH-s0lvDGjge6QRzS6QauWa74OSuB3Uy9cLu3QrxN8phPPpnxqpqy3Sly7uuniebZdbv413Bo7WbiECQFkUOIHzBwCoZlDCAel_SsKs_y-zs6RaEjbPmuNhT3XWl34B0Yufy3I4f0jEiix7uN4zy05mfw_oCNgrvx_-lJH_d5gvmEG_ryyKelKL4_6gKrIrNHt0s6--UbxF-8JaeVIS4gQzu2ntreQ5fHlaTTZK67R-XfOSDIqX6-iN5KKSdVXzES7KWX13NymmZTlqF2zC5uWkFkXDZ6zBWdPwuqrru0k1FXwznY7UghWsKouyLufVtCzG5VQ08_pOynpW1rIsyaRAw5Uea703Y-e3I5XOpItZPWP1SPMGdehPs4z1BUIYSwdbv0jytOm2gUwKrUIMJ4Soou6PwIPGdEWm91rZH-jTRinHNh9nuEewLg5nmvNDZzrzSYkSlt6MOq8XbYypxIft1HqrYts1Y-EMYetkOd_ozrvvKCJh696RQNi69-W_AQAA__-Co1qy">