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.

Reply via email to