[PATCH] D105142: RFC: Implementing new mechanism for hard register operands to inline asm as a constraint.

Anirudh Prasad via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 7 07:40:52 PDT 2021


anirudhp added a comment.

In D105142#2860885 <https://reviews.llvm.org/D105142#2860885>, @MaskRay wrote:

> This is great.
>
>   unsigned long foo(unsigned long addr, unsigned long a0,
>                     unsigned long a1, unsigned long a2,
>                     unsigned long a3, unsigned long a4,
>                     unsigned long a5) {
>     unsigned long result asm("rax");
>     unsigned long b2 asm("rdx") = a2;
>     unsigned long b3 asm("rcx") = a3;
>     unsigned long b4 asm("r8") = a4;
>     unsigned long b5 asm("r9") = a5;
>     asm("call *%1" : "=r" (result) : "{rax}"(addr), "{rdi}"(a0), "{rsi}"(a1), "r"(b2), "r"(b3), "r"(b4), "r"(b5));
>     return result;
>   }
>
> this compiles to`%0 = tail call i64 asm "call *$1", "=r,{r{ax}x},{r{dx}i},{rsi},r,r,r,r,~{dirflag},~{fpsr},~{flags}"(i64 %addr, i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5) #1, !srcloc !3`
> (note `{r{ax}x},{r{dx}i}`) which will cause a backend failure `error: couldn't allocate input reg for constraint '{r{dx}'`.
> Can you investigate it?

Definitely!

I'm assuming this is the X86 target from the usage of the registers in the example. So the issue here seems to be that before a constraint is emitted into the IR, the `SimplifyConstraint` (in CGStmt.cpp) /`TargetInfo::ConvertConstraint` (Target overridden) function(s) is/are called to "convert" the constraint into a simpler form if it exists. So, in this particular case, {rax}, gets "simplified" to {r{ax}} because:

  { -> no simplification rule exists -> simply emit it
  r -> no simplification rule exists -> simply emit it
  a -> simplified to {ax}            -> {ax} is emitted
  x -> no simplification rule exists -> simply emit it
  } -> no simplification rule exists -> simply emit it

Thanks for bringing up this point because I missed it.

Looking into it in more detail, I think we can just forego the "simplification"/"conversion" of the constraint while emitting, if we have the [&]{.*} form, since this already maps to the lower level LLVM inline assembly IR which is responsible for telling the backend to allocate a specific register. All validation is already performed in the Sema stage, and/or in the AddVariableConstraints function. So what can be done imo, is to simply early return in the `SimplifyConstraint` function in CGStmt.cpp, when you have the constraint of the form [&]{.*}. What do you think?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105142/new/

https://reviews.llvm.org/D105142



More information about the cfe-commits mailing list