| Issue |
71080
|
| Summary |
Register-or-memory inline assembly constraints generate suboptimal code
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
davidben
|
If I'm understanding GCC inline assembly syntax correctly (I may not be), a constraint like `"r"(x)` means that `x` must be passed into a register, `"m"(x)` means it must be passed in as memory, and `"rm"(x)` allows the compiler to pick whichever is more convenient.
Since the programmer does not necessarily know whether `x` is in a register or was spilled to memory, an `"rm"` constraint seems preferable when possible, since it allows the compiler freedom to generate code as it like. GCC seems to generate good code given `"rm"`, but clang seems to just interpret it as `"m"` in my testing:
```
void RegisterInputConstraint(int x, int *y) {
// This is free
__asm__ volatile("nop" : /* no outputs */ : "r"(x));
// This forces the compiler to load from y.
__asm__ volatile("nop" : /* no outputs */ : "r"(*y));
}
void MemoryInputConstraint(int x, int *y) {
// This forces the compiler to stash x to memory.
__asm__ volatile("nop" : /* no outputs */ : "m"(x));
// This is free.
__asm__ volatile("nop" : /* no outputs */ : "m"(*y));
}
void RegisterOrMemoryInputConstraint(int x, int *y) {
// This should be free, but Clang treats it as "m"
__asm__ volatile("nop" : /* no outputs */ : "rm"(x));
// This is free.
__asm__ volatile("nop" : /* no outputs */ : "rm"(*y));
}
```
https://godbolt.org/z/saWv77Yhh
This seems like a missed optimization.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs