Issue 107563
Summary `lea` with following `sub` of same register should be optimized into `mov`
Labels new issue
Assignees
Reporter blaumeise20
    With the following Rust (1.80.0) code on Godbolt:
```rs
#[no_mangle]
pub fn example(start: usize, test: u8) -> usize {
    let mut new = start;
    no_inline();
    new += 1;
    if test >= 0b11000000 {
        no_inline();
        new += 1;
        if test >= 0b11100000 {
            no_inline();
 new += 1;
            if test >= 0b11110000 {
 no_inline();
                new += 1;
            }
        }
 }
    new - start
}

#[inline(never)]
fn no_inline() {}
```
the following assembly is produced:
```asm
example:
 cmp     sil, -65
        jbe     .LBB1_1
        cmp     sil, -32
        jb      .LBB1_4
        cmp     sil, -16
        mov rax, rdi
        sbb     rax, -1
        add     rax, 3
        sub rax, rdi
        ret
.LBB1_1:
        lea     rax, [rdi + 1]
 sub     rax, rdi
        ret
.LBB1_4:
        lea     rax, [rdi + 2]
        sub     rax, rdi
        ret
```

To me it seems very unnecessary to have those separate `lea` and `sub` instructions which take up 7 bytes in the machine code, they could be replaced with `mov al, 1/2`, which only takes up 2 bytes. Also I'm not 100% sure, but probably the `mov rax, rdi` and `sub rax, rdi` in the first block could be removed and the `sbb` turned into a different instruction.

For context, this happened to me while working on optimizing UTF-8 reading using `String::chars().next()` and reading the length using `chars.as_str()` and pointer arithmetic.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to