Skip to content

x86 optimizing load of constants like 0x300000000 (== (3<<32)) #172281

@Explorer09

Description

@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.)

#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

Note: The test code is adapted from a related issue report I reported to GCC. (GCC missed a different optimization with a constant like 0x300000000.)

x86-64 clang 21.1.0 with -Os option:

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

(The constant that applies to my use case is 0x7ff0000000000000, the bit mask that can be used to check floating point infinities and NaNs.)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions