| 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