<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/71142>71142</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[Mips] Incorrect code generated to perform i128 shifting by a truncated amount
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
chenx97
</td>
</tr>
</table>
<pre>
### Description:
When compiling the following PoC with LLVM, an unexpected behavior happens, where the i128 representation of -1 will be shifted as if it were a <2xi64> vector with each element shifted by the given amount. In better-supported architectures and in older versions of LLVM, the shifting of i128 behaves correctly on Mips targets.
### Environment:
* **Compiler**: LLVM 18, commit b120fe8d3288c4dca1b5427ca34839ce8833f71c
* **Target Architecture**: mips64el-unknown-linux-gnuabi64
* **Optimization level**: works from O0 to O3
### PoC
```C
#include <stdio.h>
#include <stdint.h>
extern __int128 owo(__int128, int64_t);
int main() {
__int128 a = 0xabcdef00abcdef11;
a <<= 64;
a |= 0xabcdef22abcdef33;
__int128 b = owo(a, 48);
unsigned long *p = (void *)&b;
printf("%lx%lx\n", p[1], p[0]);
return 0;
}
```
```llvm
target triple = "mips64el-unknown-linux-gnuabi64"
define i128 @owo(i128 %a, i64 %b) {
start:
%tmp = sext i64 %b to i128
%_1 = and i128 %tmp, 127
%_0 = shl i128 %a, %_1
ret i128 %_0
}
!1 = !{}
```
### Expected Behavior:
The resulted i128 should be `ef11abcdef22abcdef33000000000000`
### Observed Behavior:
The resulted i128 is `ef11000000000000ef33000000000000`
### Analysis:
The result looks like that when shifting by a number less than 64, although both i64 numbers get correctly shifted, the overflown bits of the lower 64 bits are not copied to the lower part of the higher 64 bits. Note that the and operation in the IR only applies to the number of bits to shift by, which is smaller than the limit of i8 in this case.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVtuO4ygTfhpyU0pkg504F7noTqalkWb-Hv0a7V62MC7HbGOwAOewT78CnM5B03uIIh-g6vvqRJW5c3KvETekfCblbsZH3xm7ER3q03o1q01z3hDK0h926ISVg5dGE_ZEsh3JpuvvHWoQph-kknoPvkNojVLmGN5-mC0cpe_g27ffvhO6Ba5h1HgaUHhsoMaOH6Sx0PFhQO2CxLFDixFG5rQCi4NFh9rzwA2mhXkOR6kU1Aiuk23A4Q5kC9LDMehyIGxLT3JZEPYFDii8sckK5KIDVNij9h_K9Tmy7eUBNfDejNov4KuGGr1HO3fjMBgbWazopEfhR4sOuG5AajCqQQsHtE4a7YJ9F1cDaOQIgTBtcid6jA6EsRaFV2cwGr7LwYHndo_eLW5je43_F32Q1uhg-EP8CX0CQsNtG5OANr0R9hRNgbwK1gjT99JDndOsxaphtKpE0Qie12VBV4KzomJrgVXFWLvKxSP2z2gdPN2E4ErTy8EtC1TzUb9rc9RzJfV4mu_1yOuQhQes18HLXv6ZEqrwgOoKdTT23UFrTQ-vGXgDr-zXAflhtncbyyz9tx-CUgs1NhiKwflGmkVH2JfPdrW_3Y5XPHm0Gt7epPYhdeZoCK0uryGmUvtl8eYJXRP2fKsqtYeeS02C3BrIatoFgCteKNMdZCdeiwbbLEv3PP_ACtKxluN_B6Ge77dW21sIStOdsTu5D8I6EiY3eLC_qG5ND7Kjjk2hAWX0PqRriDqEVgcjm5S_NaHL-k5rsFL7NjpLCS3VKV3KrY4LWxhI-ZyTcnd5zuLzPbVFP1oN2TWUq91Dbn-ZcKUOfVpKJwi8lYPCyW76T7VJ6S1qg63UU-chRZZild5oGWMml0V4ru_y6jy313MJQcD3KXQOT_5DKRR0QLuRe8ujWOwmE4_vh8CU09UkF8SyhNYpuDMnIlzgLPqP3bfsMYpT5ef5FJo8mP_3Mb62n0vHfp469kMT-tkhWHSjCjLRBNeZUYUOD2SZhbJ-rNHs5vcp72vt0B7-C690F8Jbgn9N-KS5OjvpPuUBZcy7AyXfw5DiPswrfe3z9Rk46LGv0YJC54KMDic3zD7lOzPuO6iN72JNJEEHoWyvE2EaTJcZYg5oW2WOGmrp44QJq8oc0cKySIvcImgTQAaJTSizq8zArb9odXLfXdUW8D_jJzfCbihCM6BNnVnquPj1_2C0OgMfBiXRXbAnH02bDPAmmQ31OQ1xKbqQC9dzpdCmMESbZBhDYRxWiUE6ENzhYtZsWLNmaz7DTb5cV-tqRRmbdRvRriiWrEJEbJusWJYoVtgUnK9LtizrmdzQjLI8z1hWlKxki7asCmxYW9O2bjhrSJFhz6VahF6xMHY_k86NuFnleUFniteoXPwMolTjEeJmaAzlbmY3QWdej3tHikxJ590VxUuv4vdTGOCk3MFXPWURhGkQ9qhDMFNCBrStsf3ldNzWi7ejFlEufX7MRqs2nfdDLEP6QujLXvpurBfC9IS-xJaXbvPBmj9QeEJfotmO0Jfo1l8BAAD__2sw7Bk">