Skip to content

Missed optimization(?): LLVM ignores carry flag after a 'shr' #123139

@shelerr

Description

@shelerr

https://godbolt.org/z/zdhPve74e

unsigned int bar1();
unsigned int bar2();

int foo(unsigned int num) {
    unsigned int temp = num >> 12;
    if ((num >> 11) % 2 == 0) {
        return bar1() + temp;
    } else {
        return bar2() * temp;
    }
}
foo(unsigned int):
        push    rbx
        mov     ebx, edi
        shr     ebx, 12
        test    edi, 2048
        jne     .LBB0_2
        call    bar1()@PLT
        add     eax, ebx
        pop     rbx
        ret
.LBB0_2:
        call    bar2()@PLT
        imul    eax, ebx
        pop     rbx
        ret

On x86 64, 'shr' sets carry flag to the value of the last bit shifted out of the destination operand. So, I would expect the conditional jump to just be 'jc', instead of 'test'+'jne'. Am I missing something?

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions