https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107627
Bug ID: 107627 Summary: [13] Regression int128_t shift generates extra xor/or. Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: crazylht at gmail dot com Target Milestone: --- Target: x86_64-*-* i?86-*-* The case is from PR106220. #include<stdint.h> static __inline unsigned __int128 mk_u128(uint64_t hi, uint64_t lo) { return ((unsigned __int128)hi << 64) | lo; } static __inline uint64_t shrdq(uint64_t hi, uint64_t lo, unsigned rshift) { return (uint64_t)(mk_u128(hi, lo) >> (rshift % 64)); } void foo1to1(uint64_t *dst, const uint64_t* src, unsigned rshift) { uint64_t r0 = shrdq(src[0], src[1], rshift); dst[0] = r0; } GCC trunk generates foo1to1: mov rax, QWORD PTR [rsi] mov r8, QWORD PTR [rsi+8] mov ecx, edx xor r9d, r9d mov rdx, rax xor eax, eax or rax, r8 or rdx, r9 shrd rax, rdx, cl mov QWORD PTR [rdi], rax GCC12.2 generates foo1to1: mov rax, QWORD PTR [rsi+8] mov r8, rdi mov rdi, QWORD PTR [rsi] mov ecx, edx shrd rax, rdi, cl mov QWORD PTR [r8], rax ret