llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.14k stars 12.02k forks source link

Missed optimization: inefficient bitfield increment with saturation #74844

Open dvyukov opened 11 months ago

dvyukov commented 11 months ago

The code is:

struct X {
  unsigned a : 10;
  unsigned b : 4;
  unsigned c : 10;
};

void foo(X* x) {
    if (x->b < 10)  {
        x->b++;
    }
}

Clang generates:

foo(X*):                              # @foo(X*)
        movl    (%rdi), %eax
        movl    %eax, %ecx
        andl    $14336, %ecx                    # imm = 0x3800
        cmpl    $10239, %ecx                    # imm = 0x27FF
        ja      .LBB0_2
        leal    1024(%rax), %ecx
        andl    $15360, %ecx                    # imm = 0x3C00
        andl    $-15361, %eax                   # imm = 0xC3FF
        orl     %ecx, %eax
        movl    %eax, (%rdi)
.LBB0_2:
        retq

https://godbolt.org/z/8KEqvx8Mh

Since we already checked that x->b++ won't overflow, the code can be faster/smaller:

foo(X*):                              # @foo(X*)
        movl    (%rdi), %eax
        movl    %eax, %ecx
        andl    $14336, %ecx                    # imm = 0x3800
        cmpl    $10239, %ecx                    # imm = 0x27FF
        ja      .LBB0_2
        addl    $1024, %eax
        movl    %eax, (%rdi)
.LBB0_2:
        retq
dtcxzyw commented 11 months ago

Alive2: https://alive2.llvm.org/ce/z/tKzo6Q