Issue 172281
Summary x86 optimizing load of constants like 0x300000000 (== (3<<32))
Labels
Assignees
Reporter Explorer09
    For x86-64, the load of a 64-bit constant with lower bits being zero can be optimized as a 32-bit load followed by a left shift. This can result in code that's one byte smaller.

GCC performs this optimization in `-Os` and `-Oz` modes. Clang doesn't yet. Thus this feature request. (I specifically request this in `-Oz` mode. Whether it would perform also in `-Os` mode is left for the compiler developers to decide.)

```c
#include <stdint.h>
#include <stdbool.h>
void func1a(void) {
    uint64_t x = 0x300000000; // GCC can optimize this to (3UL << 32)
    __asm__("" :: "r"(x));
}
void func1c(void) {
    uint64_t x = 3UL;
    __asm__("" : "+r"(x));
    x <<= 32;
    __asm__("" :: "r"(x));
}
bool func3(uint64_t x) {
 return x <= 0x300000000; // GCC can optimize this to (x <= (3UL << 32))
}
bool func4(uint64_t x) {
    return x > 0x300000000; // GCC can optimize this to (x > (3UL << 32))
}
bool func3b(uint64_t x) {
 uint64_t y = 3UL;
    __asm__("" : "+r"(y));
    return x <= (y << 32);
}
```

[Compiler Explorer link](https://godbolt.org/z/3PW1G3Mox)

Note: The test code is adapted from [a related issue report I reported to GCC](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122904). (GCC missed a different optimization with a constant like 0x300000000.)

x86-64 clang 21.1.0 with `-Os` option:

```assembly
func1a: # 11 bytes
        movabsq $12884901888, %rax
        retq
func1c: # 10 bytes
        movl    $3, %eax
        shlq    $32, %rax
        retq
func3: # 17 bytes
 movabsq $12884901889, %rax
        cmpq    %rax, %rdi
        setb    %al
 retq
func3b: # 16 bytes
        movl    $3, %eax
        shlq $32, %rax
        cmpq    %rax, %rdi
        setbe   %al
 retq
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to