[PATCH] D114895: [SelectionDagBuilder] improve CallBrInst BlockAddress constraint handling
Nick Desaulniers via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 2 11:55:51 PST 2021
nickdesaulniers added a comment.
Hmm...this still isn't as precise as it could be. Consider the following input:
int x;
void foo (void) {
asm goto (
"# %0\n\t"
"# %1\n\t"
"# %l2\n\t"
: "=r"(x):"rm"(&&bar)::bar);
bar:;
}
and corresponding IR:
%1 = callbr i32 asm "# $0\0A\09# $1\0A\09# ${2:l}\0A\09", "=r,rm,X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@foo, %3), i8* blockaddress(@foo, %3))
to label %2 [label %3]
(so, the indirect destination is //both// in the inputs //and// in the indirect destinations. Given an argument number, we still can't tell whether the first or second `blockaddress` was the intended target.
Changing the above `=r` output constrain to `+r` produces:
%2 = callbr i32 asm "# $0\0A\09# $1\0A\09# ${2:l}\0A\09", "=r,rm,X,0,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@foo, %4), i8* blockaddress(@foo, %4), i32 %1)
to label %3 [label %4]
ie. we have inputs that occur both before and after the indirect dest (in this case, `"X"` is meant for the indirect dest).
(before: "rm" corresponds to the first non-target `blockaddress`. after: `0` is a "backreference" to the 0-th (first) constraint (`"=r"`; the output)
then changing `int x;` at the global scope to `register int x asm("edi");` at function scope produces:
%1 = callbr i32 asm "# $0\0A\09# $1\0A\09# ${2:l}\0A\09", "={edi},rm,X,{edi},~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@foo, %3), i8* blockaddress(@foo, %3), i32 undef)
to label %2 [label %3]
ie. we again have inputs that occur both before and after the indirect dest.
(before: "rm" corresponds to the first non-target `blockaddress`. after: `{edi}` for the input register local).
I don't see how we can try to re-construct or disambiguate which `blockaddress` argument is the intended target at this point.
Perhaps if we refined the Langref from:
> The constraints must always be given in that order: outputs first,
> then inputs, then clobbers. They cannot be intermingled.
to:
> The constraints must always be given in that order: outputs first,
> then inputs, then clobbers, then goto labels. They cannot be intermingled.
example 3 would change to:
%1 = callbr i32 asm "# $0\0A\09# $1\0A\09# ${2:l}\0A\09", "={edi},rm,{edi},~{dirflag},~{fpsr},~{flags},X"(i8* blockaddress(@foo, %3), i32 undef, i8* blockaddress(@foo, %3))
to label %2 [label %3]
This would more closely match the existing order of parameters in inline asm statements. Or perhaps even just requiring that goto labels always were the final inputs. ie. example 3 would change to:
%1 = callbr i32 asm "# $0\0A\09# $1\0A\09# ${2:l}\0A\09", "={edi},rm,{edi},X~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@foo, %3), i32 undef, i8* blockaddress(@foo, %3))
to label %2 [label %3]
Because if we didn't intersperse inputs with "goto labels", and we know we have 3 inputs (in the final case described above) and we know we have 1 goto label, then it's obvious that the argument numbers that are indirect dests are in the range `[arg_size() - CBR->numIndirectDests(), arg_size())`.
I would make such a change as a parent patch, then rebase this on top. Or is there something more perhaps more obvious that I'm missing that won't require a Langref change (and test churn)? Thoughts?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D114895/new/
https://reviews.llvm.org/D114895
More information about the llvm-commits
mailing list