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

Reply via email to