Issue 148652
Summary [x86] Could use `cqo` for sign-extending to 128 bits
Labels backend:X86, missed-optimization
Assignees
Reporter Kmeakin
    Instead of sign-extending to 128 bits with a combination of `movsx` and `sar`, do a combination of `movsx` and `cqo`, like GCC does:

https://godbolt.org/z/xKb3jfKq7
```c++
#include <cstdint>

// clang-format off
using u8   = uint8_t;     using i8   = int8_t;
using u16 = uint16_t;    using i16  = int16_t;
using u32  = uint32_t;    using i32  = int32_t;
using u64  = uint64_t;    using i64  = int64_t;
using u128 = __uint128_t; using i128 = __int128_t;
// clang-format on

auto i8_to_i128(i8 x) -> i128 { return x; }
auto i16_to_i128(i16 x) -> i128 { return x; }
auto i32_to_i128(i32 x) -> i128 { return x; }
auto i64_to_i128(i64 x) -> i128 { return x; }
```

LLVM assembly:
```asm
i8_to_i128(signed char):
        movsxd  rax, edi
 sar     dil, 7
        movsx   rdx, dil
 ret

i16_to_i128(short):
        movsxd  rax, edi
        mov     ecx, eax
        shr     ecx, 15
        movsx   rdx, cx
 ret

i32_to_i128(int):
        movsxd  rax, edi
        mov     ecx, eax
        sar     ecx, 31
        movsxd  rdx, ecx
 ret

i64_to_i128(long):
        mov     rax, rdi
        mov     rdx, rdi
        sar     rdx, 63
        ret
```

GCC assembly:
```asm
"i8_to_i128(signed char)":
        movsx   rax, dil
 cqo
        ret
"i16_to_i128(short)":
        movsx   rax, di
 cqo
        ret
"i32_to_i128(int)":
        movsx   rax, edi
 cqo
        ret
"i64_to_i128(long)":
        mov     rax, rdi
 cqo
        ret
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to