<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/149580>149580</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[x86] isel incorrectly optimizes pblendvb with partial vector usage to unconditional move
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
aneshlya
</td>
</tr>
</table>
<pre>
x86 backend incorrectly optimizes a sequence involving `@llvm.x86.sse41.pblendvb` when only a subset of vector elements are used, resulting in code that ignores the condition and returns one of the inputs unconditionally.
Input LLVM IR
```
define linkonce_odr <16 x i8> @select_partial(<16 x i1> %cond, <16 x i8> %t, <16 x i8> %f, <16 x i8> %__mask) local_unnamed_addr #2 {
%cond_toStorageBool = zext <16 x i1> %cond to <16 x i8>
%res.i = shufflevector <16 x i8> %cond_toStorageBool, <16 x i8> <i8 poison, i8 poison, i8 poison, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>, <16 x i32> <i32 0, i32 1, i32 2, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
%res.i186 = shufflevector <16 x i8> %t, <16 x i8> <i8 poison, i8 poison, i8 poison, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>, <16 x i32> <i32 0, i32 1, i32 2, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
%res.i187 = shufflevector <16 x i8> %f, <16 x i8> <i8 poison, i8 poison, i8 poison, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>, <16 x i32> <i32 0, i32 1, i32 2, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
%blend.i = call <16 x i8> @llvm.x86.sse41.pblendvb(<16 x i8> %res.i187, <16 x i8> %res.i186, <16 x i8> %res.i)
%blend.i189 = shufflevector <16 x i8> %blend.i, <16 x i8> <i8 poison, i8 poison, i8 poison, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>, <16 x i32> <i32 0, i32 1, i32 2, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
ret <16 x i8> %blend.i189
}
```
The backend incorrectly concludes that the blend operation can be eliminated, even though the first 3 elements should still be conditionally selected based on the condition vector.
```
movaps %xmm2, %xmm0
retq
```
The equivalent (IMO) code using `select` produces the expected instructions:
```
define linkonce_odr <16 x i8> @select_partial(<16 x i1> %cond, <16 x i8> %t, <16 x i8> %f, <16 x i8> %__mask) local_unnamed_addr #2 {
%1 = select <16 x i1> %cond, <16 x i8> %t, <16 x i8> %f
%2 = shufflevector <16 x i8> %1, <16 x i8> <i8 poison, i8 poison, i8 poison, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>, <16 x i32> <i32 0, i32 1, i32 2, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
ret <16 x i8> %1
}
```
```
select_partial: # @select_partial
psllw xmm0, 7
pblendvb xmm2, xmm1, xmm0
movdqa xmm0, xmm2
ret
```
Compiler explorer link: https://ispc.godbolt.org/z/b64cT6MrK
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWF1v6ygT_jXkZnQiGzuOc5GLnPZEqt5TvdLu0d5GGCYxWwwuH2naX7_Csd02dVfdq-1KtSJ5DMPwDMMMD2HOyYNGXJPFd7K4nrHga2PXTKOr1SObVUY8rk9lARXjd6gFSM2Ntci9egTTetnIJ3TAwOF9QM0RpD4adZT6AKRISJ4odWzmp7KYO4d5Om8rhVocK1Ik8FCjBqPVYxwfKocezB6OyL2xgAob1N4BswjBoSD0Ciy6oHw0LjVwIxB8zTzIgzYWHfgagRstpJdGA9MCLPpgtQOjMdqOClK3wTsIetRkSj3OSbIhyeYmdsLPn3_cws1vsalI-l-yEbiXGkFJfWc0x50RFkh2lRZwAlmS7AeQPHGokPtdy6yXTBFajhppp0EXcdroy8VQuvCTrfvJ1t2uYe6O0BUow5naBa1Zg2LHRARFMwpk-Z0kGxhm3HnzuzeWHfC7MQpIdg1PePIwCQ-8eT3lYMmim8tusKvDfq-wD9YbfG-nnHAju5IltEY6o2Pv334ELXD_6eTsxyu3Mjr4lVFIOs2MQjoIdGxZjU2jFn1WG_VoNkr5KC1GqRil5SiVozTOkY1zZOllLNOy-Eg4p7bmV_Q-QfSWH4neVAn5it6_Gb3uEOwrKWdKvT1H3js2XxwoQ3iHrTB5UAxZ_n4noasLWGm5-si26rW_Ntcn2lwW_buBSssYaLK8vuA1v2qcpHfcaK6C6HgV8x136iyBadGyjmJxpqFCQCUbqZk_kzQ8ogZfm3Cou0F7aZ2H7JnRudoEJcB5qVQc_oqIwZlBoYCKORRg9AWtO2_Hnq-99KMxR9a66PCpabqlPosJAEk2Fv39xYDed7wP8sgUag-Elje3_4-0qiOXwfU89owpctbWGhF4zzXx1J6hSu28DTzicyTbvMX2n-WO6bkSdMimyeI_wtNbpR-pL-lXZflElWW6tKSTFeWlfLGpsw289xCaTWRBsoHWKfUAADGXI65lh-f8DAfj8D2k_qlp0v4dUUBjjuKePdvo9J7NWPQXuK9M00qFNia5MhZtl7wRf-1922U53RK6la7l84MRlVF-buyB0O0ToduqyPmv4tb-bybWmVhlKzbDdbpc0LJYpXk5q9cpK1YVpjktE87z_ZJXWblfVjQtOCvLfDWTa5rQRbJMS5oki7ycpyJnVcLzYrmnS872JE-wYVLNO7Jg7GEmnQu4TvPVokxmilWoXHezp1TjA3S9hNJ40bfrOOhbFQ4usg3pvHs246VX3V8Cp7Igi2uQDtU7N_9x_R-kr6EP2nCHD44dMF4mX122YyxwFqxav17Jg_R1qObcNIRuI5b-9a215s9YfuNiu4CO0G3v4nFN_woAAP__ZvS7Wg">