[PATCH] D103275: Update musttail verification to check all swiftasync->swiftasync tail calls.
Duncan P. N. Exon Smith via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri May 28 12:03:53 PDT 2021
dexonsmith requested changes to this revision.
dexonsmith added a comment.
This revision now requires changes to proceed.
In D103275#2787268 <https://reviews.llvm.org/D103275#2787268>, @aschwaighofer wrote:
> I guess that the 'in tail position' restriction cannot really be used by frontends because it has to predict that `otherStuff()` cannot be optimized away. So it would not buy us much other than a loss of clarity ...
Yeah, I think that's right. The check for `ReturnInst` seems quite fragile. Replacing it with a restriction that frontends need to explicitly say `notail` or `musttail` seems much easier to reason about.
To that end, a bunch of more specific feedback inline.
================
Comment at: llvm/docs/LangRef.rst:447-450
"``swifttailcc``"
This calling convention is like ``swiftcc`` in most respects, but also the
callee pops the argument area of the stack so that mandatory tail calls are
possible as in ``tailcc``.
----------------
I think this is a good place to document that all calls to swifttailcc from swifttailcc must be marked with either `notail` or `musttail`.
================
Comment at: llvm/docs/LangRef.rst:11323-11329
+#. The optional ``tail`` and ``musttail`` markers (with one exception for
+ mandatory ``musttail`` when using ``swifttailcc``, see below) indicate that
+ the optimizers should perform tail call optimization. The ``tail`` marker is
+ a hint that `can be ignored <CodeGenerator.html#sibcallopt>`_. The
+ ``musttail`` marker means that the call must be tail call optimized in
+ order for the program to be correct. The ``musttail`` marker provides
+ these guarantees:
----------------
I'm not sure you need this change. The text is already clear that `musttail` means the tail call is mandatory for this particular call.
================
Comment at: llvm/docs/LangRef.rst:11360
+ - ``musttail`` is mandatory for tail calls where both the caller and
+ the callee use the ``swifttailcc`` convention.
----------------
aschwaighofer wrote:
> I think we should clarify that this only applies to calls immediately followed by return.
Given John's feedback about using `notail` and `musttail`, I think the return restriction should be dropped, and this content moved to the section on `swifttailcc`.
================
Comment at: llvm/lib/IR/Verifier.cpp:3424-3425
+// default.
+static cl::opt<bool> DisableSwiftTailCCMustTailCheck(
+ "disable-swifttailcc-musttail-check", cl::init(false),
+ cl::desc("Check that tail calls from swifttailcc functions to"
----------------
Maybe a better name would be `-disable-swifttailcc-check` or `-disable-verify-swifttailcc`? Since it's not just about `musttail` anymore.
================
Comment at: llvm/lib/IR/Verifier.cpp:3507
visitCallBase(CI);
-
- if (CI.isMustTailCall())
- verifyMustTailCall(CI);
+ verifyMustTailCall(CI);
}
----------------
I suggest reverting this change (and the one to `verifyMustTailCall()`), since the new invariant isn't just about `musttail`. Instead, you can just add the new check directly in `visitCallInst()`, or add/call a new function called something like `verifyCallingConv()`.
Incorporating John's feedback about using `notail` instead of `ret`, I think the check would be something like:
```
lang=c++
if (!Disable... &&
CI.getCallingConv() == CallingConv::SwiftTail &&
CI.getCaller()->getCallingConv() == CallingConv::SwiftTail)
Assert(CI.isMustTailCall() || CI.isNoTailCall(), ...);
```
================
Comment at: llvm/test/Verifier/musttail-missing.ll:5-9
+define swifttailcc void @swift_caller() {
+; CHECK: tail call from swifttail->swifttail should be marked musttail
+ call swifttailcc void @swift_callee()
+ ret void
+}
----------------
This is a great start. It should also check that the verifier doesn't fire when the IR is valid.
Taking into account John's feedback, I think the matrix should be:
- `musttail` vs. `notail` vs. `tail` vs. none of the above (former two are valid, latter two are invalid)
- one of callee and caller is `swifttailcc`, and the other is not (one example for each direction where the IR would be invalid if both were `swiftailcc`)
Assuming we're dropping the rule about other instructions before `ret` we probably don't need that in the matrix.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D103275/new/
https://reviews.llvm.org/D103275
More information about the llvm-commits
mailing list