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

    <tr>
        <th>Summary</th>
        <td>
            Arm neon left shift intrinsics - incorrect immediate value
        </td>
    </tr>

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

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

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

<pre>
    **Summary**
For, seemingly, all Arm left shift neon intrinsics that accept as a first argument a vector and a constant integer as a second argument, the second argument gets turned into a const vector.

This is problematic for languages that wish to use the intrinsics but do not natively support const vectors. For example they needed to be [implemented in Rust](https://github.com/rust-lang/rust/issues/118209).

**How to reproduce:**
```c

#include <stdio.h>
#include <stdint.h>
#ifdef __ARM_NEON
#include <arm_neon.h>
#else
#error "arm only"
#endif

int
main(void)
{
    #define N 1
 int8x8_t a = {15, 14, 13, 12, 11, 10, 9, 8};
    /* Example */
 uint8x8_t retval = vqshlu_n_s8(a, N);
    for (int i = 0; i < 8; ++i) {
        printf("[%d] => %d\n", i, retval[i]);
    }
    return 0;
}
```

According to the [documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s8) it should produce something like the following ir/llvm call:
```llvm
<8 x i8>  @llvm.aarch64.neon.sqshlu.v8i8(<8 x i8>, i32)
```

However something is wrong meaning it actually expects a constant vector as it's second argument like so:
```llvm
<8 x i8> @llvm.aarch64.neon.sqshlu.v8i8(<8 x i8>, <8 x i8>)
```
However the resulting Arm assembly does produce the correct call:
```asm
sqshlu v0.8b, v0.8b, #1
```


If you supply something like the following as a second argument in the IR the `llc` will crash as all values need to be the same
```llvm
call @llvm.aarch64.neon.sqshlu.v8i8(
    <8 x i8> <i8 15, i8 14, i8 13, i8 12, i8 11, i8 10, i8 9, i8 8>
    <8 x i8> <i8 1, i8 2, i8, 3, i8 4, i8 5, i8 6, i8 7, i8 8>
)
```
As it is unable to create the correct Arm assembly code.


This observation is the same for a large portion, if not all, neon intrinsics requiring a left shift by a constant immediate value.

The intrinsics I have observed this with but are potentially not limited to:
- `vqshlu_n_<size>`
- `vqshl_n_<size>`
- `vqshlb_n_<size>`
- `vqshlq_n_<size>`
(where `<size>` denotes `s8`, `u8` etc...)

**Exploration**
This seems to be caused by the incorrect type being used in the tablegen file: `llvm/include/llvm/IR/IntrinsicsAArch64.td`. For example the `sqshlu` intrinsic is using the type `AdvSIMD_2IntArg_Intrinsic` which, through me fumbling around, seems to be remedied with the use of a type like the bellow along with removing the intrinsic out of the NEONMAP in `clang/lib/CodeGen/CGBuiltin.cpp` however I was mostly looking at the IR as opposed to clang and this is a fairly surface level dive into the problem
```
/* Example type that seemed to work */
class AdvSIMD_2VectorArg_Scalar
  : DefaultAttrsIntrinsic<[llvm_anyint_ty],
 [LLVMMatchType<0>, llvm_i32_ty],
 [IntrNoMem]>;
```

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJycV9tu4zjSfhrmphDDpnyQL3zhQzyTH5P8i-7B3BoUVbK4TZFqkrLjffpFUZJt5dAz2CCgKZEs1uGrqk_Ce3U0iCs227DZ7kE0obRu9X-iQp8JV1iXP2Q2v6wYXzO-_t5UlXCX9oGNd2y83lvH-BY8YqXMUV_oQWgNa1eBxiKAL1URwKA1oExwynglPYRSBBBSYh1AeBBQKOcDCHdsKjQBBJxQButAmBwESGt8ECaQCDyia894lJaWu0N0dSjx_Ws4YvAQGmcwp_O2l9ddMWoNacc_S-VBeaidzTRWIigJhXWghTk24oid5mflSwgWGo_xyjvLsiZAbsHYAEYEdUJ9Ad_UtXVhcK0fwd46wDdR1TpKuYBBzDEnwRkCm20ULZENUXP41vjAZjvG0zKE2rNkzfie8f1RhbLJRtJWjO9d48MjqdvNGd8r7xv0jO8nk5SPl4wvBza34fzdnulih7WzeSMxSr_Fmc3H7b8cHk2UkbrJEViy9SFXdlSy5OmrVRPeLRc5FnA4rL-9HF6f_v_1s3PCVQeCz_Akao-3B-esA8a5cBVYQyjkt0WTq-JeaWVCO6mEMoynJ6tyxpfdlsWmnQAAMJ7kWCiD8AqT7rUyIX1LDwRRluyALTaTGSFvMo1jEkcex0kcxzQuaUjZYseSgfw942t46jAQ_b3vlpvrRQ7DSeh42-mnL3VzMAefMp4KEvpKqt8LLaIrUkXZEg-NWbKJU9Ig2QDjG8Y3ivElDKylv9opEwrGU_LgbMP4LGezHYlhyRO0j1tDi3wLioZWOwJrhOZQFzL4-uCQkjCq0_t69w5c92FaS2ldrsyRYElJxmab3MqY0yIoaz5LhRxPqG2NbiRc1WWEcLJUAWVoXMwCZXxwjSQRjx5D-6rPX8b3AycvQVENs43OocsM8LbCUJJmWv1oC0BhtbZneqUc43utTxVIoTUpNjSRlrpXyTaFN1ApuRbYNC6NBKk7n44i5H1UZXRKFcX7_kD0f8JvuP3Mhb_bM57Q3SmsPJydNUeoUJj4gspwaITWF8C3GmXw9_W2r8IeVGB84T8U1-gBb_-xnf-DmcPnz-3tLaVYOPSNDmQcNSHhPVaZvkBu0V9DSPukdQ5l-CJOwnfqt8rBaTxKM1LnOmE8mfzC-e34XMDFNrEDUCP4FXI-62lU9mnX87c2Bcivks3HcFZag3TCl_Gc1nASukEfe0jXQWIzFBV-GRmy_B9F5JbQg1gmW5VCW_5oMu0nST_h_WTST8bdZNn9ptei_pX4bmMnisZefH9fr8C8-118kP0VbNaEa0qKxoiMurAF6VCEIUAGMJI2x9HHOEfiYDOP7hSLEwnt_R9LsgAt3BGBiAAVL1KxiDSB4Me3HyiSw5-NchEY90wquwz4UFVhrkjhGP53XGZATJ6hFCfsdCSMkMZnFcpIWYQj1QKaoGItIMW0qlSIaLqmxyNB8Fogqaur_yC5uffobcPfrWd_t-Hn5xsYT88lupgMg2XI0diAnhZ8SquUpPNxQ3PAIEej0Q0Id9Tn6a3W1rU95Y7yxJASsfVdPknReMwpAi3n6_ERLjVChhSquKHL2UCQOqKBQmmiU9DnHvWbSG-6TsH4_vkbDddgrddtLoaczccfiGI0MMaADLuGOOLYx4ZJt5NSbD5e56fvzy-7A382Ye2Oh-slsYqUSpYtb3a2OZZAYG2qTEfYOduYvGf3vRMcEuIwb6FDNxEJtgWI9sprYcuQChsITe0mbnZY2VOv301t2wQ6Ty-JA76s_0UeJKrZ0VitMsb3W5vjb2ho9tumUVThR7KuyYyyq_7PcBYeKuuDvoC29kc0I_QVVHiwdW19WyCj9Ph9ETrSL6AQykW-7gohETSxCcjVCdsPB5LTfRl8XviHfC76I34vkAPbW8_W_RgQPamF93CN0l-x4VKgvkuhhetrI-Fnh4VodFiH4PwtjMmWzTYEo4MwF2XCIVwiM9p2R9ls88cff728iCDLPy81smQ77jprPKUS_skRkv9qX7CiheTpxtmGFj_kqyRfJkvxgKvJgk_TJFku5w_lKpliVnCZClwsl2IyXS6mWCxngs_SNF-ifFArPubTccrTcZokk_mIT5Y4KabJBKdJtlgu2HSMlVB6FLuTdceH-B2zmoznyTR90CJD7fsPV7eiXY9Zc_TUz5QP_nYuqKBxRVU81ti7YnpXHh_vEvpdVX1onF794pOry-GoQe3sv1EOv7pahU8r_t8AAAD__2vru7k">