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

    <tr>
        <th>Summary</th>
        <td>
            ARM64 (and other) assembler immediate arithmetic is broken, and evaluated too early
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          distorted-mdw
      </td>
    </tr>
</table>

<pre>
    GNU as accepts the following (https://gcc.godbolt.org/z/e1fed5vhM)
```assembler
 .text
proc:
        movz    x0, #thing
        add     x0, x0, #thing
        eor     x0, x0, #thing
        ldr     x0, [x1, #thing]
        ldp     x0, x1, [x2, #thing]
        ldr     q0, [x0, #thing]
        ldp     q0, q1, [x0, #thing]
        ret

 .balign 16
base:
        .skip   16
thing = . - base
 .skip   16
```
and produces
```
0000000000000000 <proc>:
   0: d2800200        mov     x0, #0x10                       // #16
   4: 91004000        add     x0, x0, #0x10
   8:   d27c0000        eor     x0, x0, #0x10
   c:   f9400820        ldr     x0, [x1, #16]
  10: a9410440        ldp     x0, x1, [x2, #16]
  14:   3dc00400        ldr q0, [x0, #16]
  18:   ad408400        ldp     q0, q1, [x0, #16]
  1c: d65f03c0        ret
```
as I expect.

Clang rejects this (https://gcc.godbolt.org/z/W8PTq9aqG), reporting
```
t.S:3:11: error: immediate must be an integer in range [0, 65535].
 movz x0, #thing
 ^
t.S:4:14: error: expected compatible register, symbol or integer in range [0, 4095]
 add x0, x0, #thing
             ^
t.S:5:14: error: expected compatible register or logical immediate
 eor x0, x0, #thing
 ^
t.S:6:15: error: index must be an integer in range [-256, 255].
 ldr x0, [x1, #thing]
              ^
t.S:7:19: error: invalid operand for instruction
 ldp x0, x1, [x2, #thing]
 ^
t.S:8:15: error: index must be an integer in range [-256, 255].
 ldr q0, [x0, #thing]
              ^
t.S:9:19: error: invalid operand for instruction
 ldp q0, q1, [x0, #thing]
                  ^
```
The errors for `ldp` are unhelpfully vague, but the caret position hints
that assembler is objecting to the immediate operand.  The `eor` error
is a little unhelpful, but I understand that it's hard to characterize the
acceptable ARM64 logical immediate values.  The other messages are
simply incorrect: it's clear that `thing` has the value 16, which is
easily in range.

It doesn't help to float the data definition above the code which
references it (https://gcc.godbolt.org/z/sejn5frx9); nor does it help to
replace the expressions with their literal values
(https://gcc.godbolt.org/z/v9GKnf8b8).  However, doing _both_ of these
things is successful (https://gcc.godbolt.org/z/Gjrjc6a7M).
```assembler
        .text
 .balign 16
base:
        .skip   16
thing = 16 // . - base
 .skip   16

proc:
        movz    x0, #thing
        add x0, x0, #thing
        eor     x0, x0, #thing
        ldr     x0, [x1, #thing]
        ldp     x0, x1, [x2, #thing]
        ldr     q0, [x0, #thing]
        ldp     q0, q1, [x0, #thing]
 ret
```

I guess, therefore, that there are at least two underlying bugs:

  * the assembler tries to resolve immediate values in the first
    pass; and

  * the assembler doesn't understand that the difference between two
    defined symbols in the same section is a plain integer.

ARM64 is where I tripped over this, but it seems that other targets are
affected also.  For example, the ARM32 fragment
```assembler
        .text
        .arch   armv7-a
 .fpu    neon
proc:
        mov     r0, #thing
        add     r0, r0, #thing
        eor     r0, r0, #thing
        ldr     r0, [r1, #thing]
        ldrd    r0, r1, [r2, #thing]
        vldr    d0, [r0, #thing]
        bx      r14

        .balign 16
base:
 .skip   16
thing = . - base
        .skip   16
```
is acceptable to GNU as (https://gcc.godbolt.org/z/G454KvrE6) but Clang
objects to the `mov`, `ldrd`, and `vldr` instructions
(https://gcc.godbolt.org/z/es33YqrfM).

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWF1v47oR_TX0yyAGRUuy9eCHbLLZLi5uUbS3KPp0QYkjibuUqJCU4-yvL0hK_sqXF9vHawRwLHFmDs_MHI7ErZVNj7gl2SeS3S_46FpttkJap41DcdOJp0WpxfP2y9__DdwCryocnAXXItRaKf0k-wYI27TODZasbgl7IOyhqaplo0WplVtq0xD28IOwB0xqFNmu_Z2wgtB7Qm9JTuMftxa7UqGJ12HpcO_i_4PRlXccb0yfTu9--O89JewOCFu5VvbN-RouBBzXvLcStblypRKnK0n2aZ-cLc7uL9cPp56T2Yp9YBWjPB6i0KuixPWPyXVWBieGZ85LrmTTQ5LHCyW3-IL4pf0ufbB5UXANZHUPS7iBYDJ5u1h4SHX8yXsBg9FirNC-uoBefICs7mIpfD4FRcnqFgTbUMooPakOOKsOuk8ONy8-sWD9ohkpAKTea5FQmtKj1zfqyfs-GG68IYBg64qemL5RYGemVTSti5TSDaMfV1ySn6Q0CUTwIk1omtJry-_cRRoRrEQVNn6K4GUlnptO--YipZsz0_cL89xJYEDkWU1XFX1ZpRcFZOEr4H7Ayi1Py_hO8b4Bg9-wCjol7bXy9J_NP_54LPjjFy9P7A4MDtq4gwRcxHfLf5HV7YqsbpPE40ZjtPH_yK5DIblD6EbroETgPcjeYYMGZA-G9w16FgIJeZatMpLdT3uIwvaqApHs82lkn6yYsUPkyAYKqHQ3cCdLhWCwkdah8Q7tc1dqBdq8DSelRXZMia_4jzUxttE5uuzn0HlMSjey4urI3xTF9847IC4C5z5wdp6QXuD-o2TcsCz33ll2mg1f-tdK_as8rD2c4gLOjispQA9ovArWIR_WmbFyUveHyMO1h8ZFyM3_nYFrj6FXGSh-hYGfO9BewXDRtH-0GGHYEJTkVImB5BS4QRj7FtVQj0o9w443I_pg5ejCsFNxgw4GbaWHCK3snZ1PQO7gML-AtKBLLz7-XHQ6GB8lYdryEsBDITlFbXz8yE3wJy1wUNI5dQJphvIVxl6gsc7zFiJLR9jaQsuN8OGqlhteOTTyB_rYk1iGsY37lrv95-95-rLZYMfViHYCpl2LBjq0ljdoPTvRj5XdoJ5B9pU2BisXshkBVAq5iZBITmOCcgotj8NicO-HAXYHT62sWpATf8itDD5jKZ6J-VcHQqPtCVs78FT4LdZK85gUwR0HgbXsY1Z4qXcY06UFxjjRkcEaDfYVWpDu2gPB4rc-q82-8AfC6hP02gQ43sUEZvY-KF7FyLgfDFordW_hSbrWX5TGJxQNVxPN0x6vg7ErvvzW15tyQ1ixBPibfsJdFHShfZH9WWrX_gm69qHm-SskwPpqtGNVobX1qK7d95dv5luV87Wf05cfDOrzWHic1391jkzyeSb7aKL89ceDvx4NLqzemramdoRmRGu9qRcIrLXB-CM2pMEgpNyBQm4duCcd9Uo9--yWY2MPqZphEnYb-uaooM5ItL7RDVqtdvhCpLxWhAdQaaw7bnfg1vo25b34KMRRVC7lNMiKrCe1gBLdE2Lvd3IMFBQHxTRPHeBY3iFYDGcYBBUfFJeHw_ZM2KIKSwtPgbWvftPDgAL0zjPQSjsrvnRgETsb4UVhdtw06E50mdd1nK24snoJ8KAN4J53g5ryE3R_xaA2vOmwv0zyFV09X-Kman33mG63vuFza9bD6O_2OB_fb7VlnOmveGqPa95bObfmxyvnpjFz05iPWtOIE89z05j3W3M3hRGHKO-3ZrmP3yZJz-t1YvpdGb36OfwNvb3obzm_2gkzgtMwve-59sRIs_S3nfmcE1aEqg1PYdF1nIbsPAuRnHZ65wN7bvwAZsT0yzchyann0Y8OJyPhzx2YaFer_z6a-uT8WojtShSrgi9wm6yTTULXlG4W7bYoUs7SOlnn6zpPMOVVhmK1LtOk3CBu6oXcMspSmidJkmR5ulkmIst4va6qNauRs4ykFDsu1VKpXedRLKS1I26LjBbFQvESlQ3v1xjr8QnCTcIYye4XZuttboIuplRJ6-zRi5NO4TYKBWEbT07ofk_xybh50EZupGs7dLLyulIa_R37mVX0wsm9QDitAblRz4vRqO0Fm9K1Y7msdEfYg8cxfd0MRvscEvYQ0FvCHuLudlv2vwAAAP__yZOq-Q">