This is an archive of the discontinued LLVM Phabricator instance.

[Verifier] Check that calls' arguments match the callee's byval/inalloca/preallocated
AbandonedPublic

Authored by aeubanks on May 2 2021, 1:04 PM.

Details

Summary

Previously we only checked this if the arguments had the attributes, but
not if the callee had the attributes.

As examples, there are a number of tests missing attributes on calls.

Diff Detail

Event Timeline

aeubanks created this revision.May 2 2021, 1:04 PM
aeubanks requested review of this revision.May 2 2021, 1:04 PM
Herald added a reviewer: sstefan1. · View Herald Transcript
Herald added a reviewer: baziotis. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript

Though does this break bitcode backwards compatibility, or does the bitcode not have this ambiguity/duplication?

While the textual IR doesn't have backcompat issues - maybe it'd be easy enough for the textual IR parser to correct this issue by checking the declaration and attaching the right attribute value? Though not necessary by any means.

llvm/lib/IR/Verifier.cpp
3274–3277

Should this be in a separate patch? (looks not strictly related/required in this patch)

aeubanks updated this revision to Diff 342294.May 2 2021, 5:24 PM

remove unrelated change
update some more tests

I think the bitcode and textual representation both allow this issue.
But based on the fact that so much of the checking for byval and related attributes is on the arguments rather than the parameters, IMO it's always been intended to have the attributes at least on the parameters. Users like Clang have always been properly emitting byval on the parameters (no check-clang tests regressed). This patch is just filling in a hole that should always have been filled in. But maybe someone else should chime in.

I think the bitcode and textual representation both allow this issue.
But based on the fact that so much of the checking for byval and related attributes is on the arguments rather than the parameters, IMO it's always been intended to have the attributes at least on the parameters. Users like Clang have always been properly emitting byval on the parameters (no check-clang tests regressed). This patch is just filling in a hole that should always have been filled in. But maybe someone else should chime in.

The argument is that this was always invalid, but a bug that it wasn't detected, so it doesn't need to be upgraded when reading IR, it's OK for that to fail the verifier)

Compared to an argument that it was valid, is now invalid, so needs to be upgraded to ensure bitcode compatibility?

Do you think it'd be especially complicated to auto-upgrade?

nikic added a subscriber: nikic.May 3 2021, 12:35 AM

FWIW I think the that we don't auto-upgrade textual IR as a matter of general policy. The only exception that comes to mind are align annotations on load/store, and those are really more a matter of the annotation being optional in textual IR than a real auto-upgrade.

I think the bitcode and textual representation both allow this issue.
But based on the fact that so much of the checking for byval and related attributes is on the arguments rather than the parameters, IMO it's always been intended to have the attributes at least on the parameters. Users like Clang have always been properly emitting byval on the parameters (no check-clang tests regressed). This patch is just filling in a hole that should always have been filled in. But maybe someone else should chime in.

The argument is that this was always invalid, but a bug that it wasn't detected, so it doesn't need to be upgraded when reading IR, it's OK for that to fail the verifier)

Compared to an argument that it was valid, is now invalid, so needs to be upgraded to ensure bitcode compatibility?

Do you think it'd be especially complicated to auto-upgrade?

Yeah my argument is that it was always invalid.

I'm sure it's possible to auto-upgrade bitcode, but that would have non-zero cost for every call we read from bitcode. IMO it's not worth it if this was always supposed to be invalid.

Maybe we should ask llvm-dev for more opinions?

rnk added a comment.May 3 2021, 1:15 PM

I need more time to read into this, but my first thought is, we can't do this. People can write code that does stuff like:

struct Byval { int x; } bv;
void takeByval(Byval);
void foo(bool isByRef, void (*fp)()) {
  if (isByRef) {  ((void(*)(ByVal*))fp)(&bv); }
  else { ((void(*)(ByVal))fp)(bv); }
}
void bar() {
  foo(false, &takeByval);
}

Inlining foo into bar and simplifying would lead to a verifier failure, no?

This is for example why the verifier doesn't check that calling conventions match:
https://llvm.org/docs/FAQ.html#why-does-instcombine-simplifycfg-turn-a-call-to-a-function-with-a-mismatched-calling-convention-into-unreachable-why-not-make-the-verifier-reject-it

I think the bitcode and textual representation both allow this issue.
But based on the fact that so much of the checking for byval and related attributes is on the arguments rather than the parameters, IMO it's always been intended to have the attributes at least on the parameters. Users like Clang have always been properly emitting byval on the parameters (no check-clang tests regressed). This patch is just filling in a hole that should always have been filled in. But maybe someone else should chime in.

The argument is that this was always invalid, but a bug that it wasn't detected, so it doesn't need to be upgraded when reading IR, it's OK for that to fail the verifier)

Compared to an argument that it was valid, is now invalid, so needs to be upgraded to ensure bitcode compatibility?

Do you think it'd be especially complicated to auto-upgrade?

Yeah my argument is that it was always invalid.

I'm sure it's possible to auto-upgrade bitcode, but that would have non-zero cost for every call we read from bitcode. IMO it's not worth it if this was always supposed to be invalid.

Maybe we should ask llvm-dev for more opinions?

Yeah - if it's not possible to make that sort of IR from the APIs - if it'd require hand-crafted textual IR, or really weird/novel bitcode creation (please confirm whether/how hard it would be to have this in bitcode - if simple use of the IRBuilder/IR creation APIs could result in this problematic representation) I'd probably be OK calling it an "accepts invalid" bug and declaring it invalid.

Pending @rnk's concerns too.

aeubanks abandoned this revision.May 3 2021, 6:14 PM

rnk's comment makes sense, abandoning in favor of D101806