https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127634
Bug ID: 127634
Summary: misoptimize when zero extend xmm to ymm and fill upper
half with another xmm
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: z00823823 at outlook dot com
Target Milestone: ---
It is a common paradigm to combine 2 xmm by zero-extend one and fill upper half
with another one. e.g. Google Highway's Combine impl:
https://github.com/google/highway/blob/32ae7331df07c4efbdebd687e3b25bab4a07d907/hwy/ops/x86_256-inl.h#L6128
I found gcc misoptimized it here, both in xmm and ymm combine:
https://gcc.godbolt.org/z/nxrv8vGKW
```c++
__m256i combine_xmm_zext(__m128i hi, __m128i lo) {
const __m256i lo256 = _mm256_zextsi128_si256(lo);
return _mm256_inserti128_si256(lo256, hi, 1);
}
```
clang compile it to:
```c++
combine_xmm_zext:
vinsertf128 ymm0, ymm1, xmm0, 1
ret
```
but gcc generate unnecessary upper half clear code:
```c++
"combine_xmm_zext":
vmovdqa xmm1, xmm1
vinserti64x2 ymm0, ymm1, xmm0, 0x1
ret
```
similar issue happens to ymm combination.