llvm / llvm/llvm-project

[missed-opt] [x86_64] Suboptimal movzx after inline assembly returning a byte

Open
#172,172 7 comments 0 reactions 0 assignees View on GitHub
backend:X86 missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Found while trying to implement a fast black-box primitive.

[Godbolt](https://godbolt.org/z/K3j7PKPK8)

```cpp
char f(char x) {
asm("nop" : "+r"(x));
return x * 3;
}

short g(short x) {
asm("nop" : "+r"(x));
return x * 3;
}

char h(char x) {
return x * 3;
}
```

```asm
f(char):
nop
movzx eax, dil
lea eax, [rax + 2*rax]
ret

g(short):
nop
lea eax, [rdi + 2*rdi]
ret

h(char):
lea eax, [rdi + 2*rdi]
ret
```

The line `movzx eax, dil` in `f` can be omitted (and, indeed, GCC omits it). I initially thought this was some kind of dependency-breaking optimization, but I'm not sure anymore. For one thing, it's not done for 16-bit numbers (`g`), which would seemingly suffer from the same issue. It is also not done in `h`, where the input to `lea` is the function argument, which by psABI has undefined top bits. If this is an optimization attempt, it seems more like a pessimization after inline assembly, which the author supposedly made as efficient as possible, and there's no way to opt out of the zero-extenion.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.