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

    <tr>
        <th>Summary</th>
        <td>
            [AArch64] INSvi64lane peephole optimization in backend incorrectly drops register constraint on MULv8i16_indexed
        </td>
    </tr>

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

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

    <tr>
      <th>Reporter</th>
      <td>
          Benjins
      </td>
    </tr>
</table>

<pre>
    Here is a repro that is as minimal as I could make it:

```llvm
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-gnu"

define <8 x i16> @do_stuff(<8 x i16> %0, <8 x i16> %1, <8 x i16> %2, <8 x i16> %3, <8 x i16> %4, <8 x i16> %5, <8 x i16> %6, <8 x i16> %7, ptr %iPtr) {
  %9 = mul <8 x i16> %6, %0
  %10 = mul <8 x i16> %7, %3
  %11 = mul <8 x i16> %9, %0

  ; Load and zero-out the upper half of the register so that it trips the peephole optimization
  %tmp.2 = load <4 x i32>, ptr %iPtr, align 4
  %tmp.5 = shufflevector <4 x i32> %tmp.2, <4 x i32> zeroinitializer, <2 x i32> <i32 3, i32 3>
  %tmp.6 = shufflevector <2 x i32> %tmp.5, <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  %tmp.7 = bitcast <4 x i32> %tmp.6 to <8 x i16>

  ; make a broadcast of a specific element, so that it will be selected as a mul_indexed
  %vtmp12 = shufflevector <8 x i16> %tmp.7, <8 x i16> zeroinitializer, <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3>

  ; The problematic multiply
  %m14 = mul <8 x i16> %11, %vtmp12

  %mul.7 = mul <8 x i16> %10, %tmp.7
  %sum.14 = add <8 x i16> %mul.7, %m14
  %12 = or <8 x i16> %sum.14, %1
  %13 = or <8 x i16> %12, %2
  %14 = or <8 x i16> %13, %4
  %15 = or <8 x i16> %14, %5
  ret <8 x i16> %15
}
```

[Godbolt link](https://godbolt.org/z/hEPn83E8x)

In this case, we can observe that the assembly from `llc` gives the following line:
```asm
mul v0.8h, v0.8h, v16.h[3]
```

If we feed that to `aarch64-linux-gnu-as`, it errors:
```
test.s: Assembler messages:
test.s:17: Error: register number out of range 0 to 15 at operand 3 -- `mul v0.8h,v0.8h,v16.h[3]'
```

If we instead use `llc` to compile to an object file and run objdump, we see it becomes this line:
```asm
20:   4f708000        mul     v0.8h, v0.8h, v0.h[3]
```

As I understand, for indexed multiplies, they are constrained to the lower 16 vector registers and the instruction opcode only has 4 bits for it. This looks like it's being correctly modeled in LLVM, but it's possible for `AArch64MIPeepholeOpt::visitINSvi64lane` to drop this constraint. The relevant part of the Machine IR for the repro is:
```
 %20:fpr128 = INSERT_SUBREG %21:fpr128(tied-def 0), killed %15:fpr64, %subreg.dsub
  %22:fpr128_lo = INSvi64lane %20:fpr128(tied-def 0), 1, killed %18:fpr128, 0
  %23:fpr128 = MULv8i16_indexed killed %11:fpr128, %22:fpr128_lo, 3
```
which after `visitINSvi64lane` becomes:
```
 %20:fpr128 = INSERT_SUBREG %21:fpr128(tied-def 0), killed %15:fpr64, %subreg.dsub
  %23:fpr128 = MULv8i16_indexed killed %11:fpr128, %20:fpr128, 3
```
which drops the register constraint for the indexed operand of the `MULv8i16_indexed`. This means that during register allocation it might be assigned to an out of range register like `v16`, and generate incorrect assembly

A bisect shows that this started happening since 6e7840dd42d1c0a23f69bcfcda457f086ed35743

I have verified that this still repros on the latest trunk, 278a8efb7fdb145e0504aee7d44bef07d78d16a9

For priority/triage purposes: this was not in manually-written code, but was instead found by a fuzzer to test SIMD codegen
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMGMtu4zjya5RLwYZEPX3IIc_ZAN2zg-mZvTYosWRxQpECSTntfP2iKMmxE6VnsXtZI7HpYr3fFndO7jXidZTfRvn9FR99Z-z1Leq_pHZXtRHH63-gRZAOOFgcrAHfcR--O-illj1XdHyCxoxKQM-fEaSP0psovo_i5b2Ipz-lDv0E8tzu0YPgnit-NKOHKL2HiDHc9FF6gxtZRekN_adsI5MiSm_CG30rsii9KbKNTBghJKza6JRNsG8EY-xCiLdyULgI4Nw2XZFtRv2szYveKKnHH5u9Hk9k07vAVmqiuqvgBwQVHiDKYmG-Oz-2bUTCL-5YHkfs7j0Fy5NVKFuFpqvQbBWar0KLVWhJ0MFbOsvfvI3YDqLydjIVCLoLDupH9RlLMu8NPYk_xy9n_PQcP_kcf3fJ_0SV3sIXwwVwLeAVrdlQnvgOYRwGtNBx1YJpA8TiXjqPFtySolPcXbgdEIfOKAQzeNnLV-6l0WfK-X7YsqCfInlRepeRgpRUDx8cdwdcyb2G7B2DPDBw3di2Cg_YeGMvOZ0kzRE6uyHrpJZeciVf0c4I7Iw0vZMpg5Ae0yF9eCe_WJfPPsjPP7Jfl599kB8v8pPlwH6iURk0qqVvuPPrvijAm8uE-JgDoalwqK3hInAyLXBwAzaylQ2gwh61Jz3Ogv8ilYIawaHCxqOgLsUp_b5LLfAHijNdD74fErbuvstMDVZ9LLB191U_C99_d1hzzx-U4NbUCnvuZUM2ejmo45mBfZJ9Xn1JMpff5IZ3Aljej2qO5Dp5PJNPvnmjc2O_neVyIT4SBr4zbZ-cV9Mci7UATExnquScJv2UJmEzPjvHzz7HT2f8C53yz_EXffIF36JfQZuvo_L-3Vi8mJX57S9G1EZ5UFI_R_l9xKrO-8HRUGWPEXvcT_dbY_cRe3yN2GP38Juu0ofqR8R258yeNPhOOmi4Q9LxBaHhGkzt0B5wqhXqj9w57Gt1hNaaHsKgbqIihr084NRBW6OUeZF6T1rh23xfTOBuHuyUI4d4W3Uk7-2QFNsuym9Tsudz459aUrFFFLNuhpRZJvZpUm-4I0KqCg9orbHuo0bzCoDOb-kWbiYb0UKPzvE9vtGckJKSMB-IIx1OQ0WPfY0WaPyYFizXe4SYtEty4B7MgJZmVAqbDSl87oPT57kHWPm3TpDaeeQCRodnAfEGGtMPUiEdQyj_wsZDSxBSwY4BJsZ-mAPukDYyqLExfQimdH8XQxaT9QBZW8ZVHMcwv8gueq3EN_5PwntDi-KoBVrnuRZE2BoLc0NeGpdERze-wyNwi9AY7bzlUlNWmJCNyryghaSAuU8vgXLBB4RB7rNjQ3MezNAYgWC0OkLHHWQ0ktwk2m_hj-ARY57JL9P6ykoHNVK2N8ZabLw6Qm8EKhQgNXz58q-vpGI9-gV7MM7JWmHgGhXxzU3I2a9Pv82rxz-HsBWnNwfppH_69dtBFpniGuewCmuGuVgXe4NutNooPHDtYeDWL_vOV950tJ4-_R4kTisQ7efy01IIHZAi2w42YVVoZ0-_fnv4_Y_v3_68_f3hl4CQnBAiVnmJYiOwpbkflrRnqcgHUzcLiMXS_NxYW9xvhRvrs7bJ2Infd2UWmYvt71Rak5i8E1udYd_B-UbK0kvbvv755VDJpFgG_jmX5ILLBz0JmK468aWTTQe8pa4QFfFaMOdK-_8Kw__km_gC8jPHUBa7y4X8LZ1PmboIXfrmnNNREb_XKyriuUB75NpNU0GMlkrzJIErZZqw0lOj6-W-o3YH869bsXTK8-Z9og0VT4FMinmkkEJ71Gi5J03nBnAakRf9DGrp6NJ15sUt41Q6cJ5b2jk7PgyoSVkndYNQYFllsRAZE0kTc5a2xa5u2kbwLC_buCpQpHmZpRfjADp-QDigla08DcZJCu24oewdGD11Rk7DDLwd9TNZw8qKV9jWZSvqJMsxzuOMI5Yiy2ps41KUlUgKfrE1PBoLg5XGSn-M2KO3ku8RhtEOxoW8nsS_cAfaeGqIPdcjV-q4ebHSe9RADXfpkIS3TLPWjFpAfQQO7fj6ijZ0dNL429PX-0C2R30lrlOxS3f8Cq-Toqp2VRmnu6vuusK6adMkbmpWFXmap1Ub53mTcp5lRVwVV_KaxSyNyyROkjjNd9syrZsmSRnWgrFdW0ZZjD2XaqvUoacN6ko6N-J1kZZleaV4jcotj0PsNSFt6nHvoixW0nn3RualV-HBydzpo_yys63-5CRf1bx5Ri3eUksd57JZKxmjP9Tq1WjV9buNUPpurLeN6SP2GB6yTB-bwRraDyL2GMx0EXsMlv47AAD__95yKhg">