mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
Modify verifier checks to support musttail + preallocated
Summary: preallocated and musttail can work together, but we don't want to call @llvm.call.preallocated.setup() to modify the stack in musttail calls. So we shouldn't have the "preallocated" operand bundle when a preallocated call is musttail. Also disallow use of preallocated on calls without preallocated. Codegen not yet implemented. Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D80581
This commit is contained in:
parent
7c8e51c47a
commit
79048330b0
@ -1065,17 +1065,22 @@ Currently, only the following parameter attributes are defined:
|
||||
form and the known alignment of the pointer specified to the call
|
||||
site. If the alignment is not specified, then the code generator
|
||||
makes a target-specific assumption.
|
||||
|
||||
.. _attr_preallocated:
|
||||
|
||||
``preallocated(<ty>)``
|
||||
This indicates that the pointer parameter should really be passed by
|
||||
value to the function, and that the pointer parameter's pointee has
|
||||
already been initialized before the call instruction. This attribute
|
||||
is only valid on LLVM pointer arguments. The argument must be the value
|
||||
returned by the appropriate
|
||||
:ref:`llvm.call.preallocated.arg<int_call_preallocated_arg>`, although is
|
||||
ignored during codegen.
|
||||
:ref:`llvm.call.preallocated.arg<int_call_preallocated_arg>` on non
|
||||
``musttail`` calls, or the corresponding caller parameter in ``musttail``
|
||||
calls, although it is ignored during codegen.
|
||||
|
||||
Any function call with a ``preallocated`` attribute in any parameter
|
||||
must have a ``"preallocated"`` operand bundle.
|
||||
A non ``musttail`` function call with a ``preallocated`` attribute in
|
||||
any parameter must have a ``"preallocated"`` operand bundle. A ``musttail``
|
||||
function call cannot have a ``"preallocated"`` operand bundle.
|
||||
|
||||
The preallocated attribute requires a type argument, which must be
|
||||
the same as the pointee type of the argument.
|
||||
@ -10634,8 +10639,8 @@ This instruction requires several arguments:
|
||||
|
||||
#. The call will not cause unbounded stack growth if it is part of a
|
||||
recursive cycle in the call graph.
|
||||
#. Arguments with the :ref:`inalloca <attr_inalloca>` attribute are
|
||||
forwarded in place.
|
||||
#. Arguments with the :ref:`inalloca <attr_inalloca>` or
|
||||
:ref:`preallocated <attr_preallocated>` attribute are forwarded in place.
|
||||
#. If the musttail call appears in a function with the ``"thunk"`` attribute
|
||||
and the caller and callee both have varargs, than any unprototyped
|
||||
arguments in register or memory are forwarded to the callee. Similarly,
|
||||
|
@ -2988,9 +2988,13 @@ void Verifier::visitCallBase(CallBase &Call) {
|
||||
|
||||
if (Call.paramHasAttr(i, Attribute::Preallocated)) {
|
||||
Value *ArgVal = Call.getArgOperand(i);
|
||||
Assert(Call.countOperandBundlesOfType(LLVMContext::OB_preallocated) != 0,
|
||||
"preallocated operand requires a preallocated bundle", ArgVal,
|
||||
Call);
|
||||
bool hasOB =
|
||||
Call.countOperandBundlesOfType(LLVMContext::OB_preallocated) != 0;
|
||||
bool isMustTail = Call.isMustTailCall();
|
||||
Assert(hasOB != isMustTail,
|
||||
"preallocated operand either requires a preallocated bundle or "
|
||||
"the call to be musttail (but not both)",
|
||||
ArgVal, Call);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3150,9 +3154,6 @@ static AttrBuilder getParameterABIAttributes(int I, AttributeList Attrs) {
|
||||
|
||||
void Verifier::verifyMustTailCall(CallInst &CI) {
|
||||
Assert(!CI.isInlineAsm(), "cannot use musttail call with inline asm", &CI);
|
||||
// FIXME: support musttail + preallocated
|
||||
Assert(!CI.countOperandBundlesOfType(LLVMContext::OB_preallocated),
|
||||
"musttail and preallocated not yet supported", &CI);
|
||||
|
||||
// - The caller and callee prototypes must match. Pointer types of
|
||||
// parameters or return types may differ in pointee type, but not
|
||||
@ -4533,6 +4534,9 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
|
||||
++NumPreallocatedArgs;
|
||||
}
|
||||
}
|
||||
Assert(NumPreallocatedArgs != 0,
|
||||
"cannot use preallocated intrinsics on a call without "
|
||||
"preallocated arguments");
|
||||
Assert(NumArgs->equalsInt(NumPreallocatedArgs),
|
||||
"llvm.call.preallocated.setup arg size must be equal to number "
|
||||
"of preallocated arguments "
|
||||
|
@ -89,7 +89,7 @@ define void @preallocated_attribute_type_mismatch() {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: preallocated operand requires a preallocated bundle
|
||||
; CHECK: preallocated operand either requires a preallocated bundle or the call to be musttail
|
||||
define void @preallocated_require_bundle() {
|
||||
%cs = call token @llvm.call.preallocated.setup(i32 1)
|
||||
%x = call i8* @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
|
||||
@ -117,9 +117,22 @@ define void @preallocated_arg_token() {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: musttail and preallocated not yet supported
|
||||
define void @musttail() {
|
||||
; CHECK: cannot use preallocated intrinsics on a call without preallocated arguments
|
||||
define void @preallocated_no_preallocated_args() {
|
||||
%cs = call token @llvm.call.preallocated.setup(i32 0)
|
||||
musttail call void @foo0() ["preallocated"(token %cs)]
|
||||
call void @foo0() ["preallocated"(token %cs)]
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: preallocated operand either requires a preallocated bundle or the call to be musttail
|
||||
define void @musttail_and_bundle(i32* preallocated(i32) %a) {
|
||||
%cs = call token @llvm.call.preallocated.setup(i32 0)
|
||||
musttail call void @musttail_and_bundle(i32* preallocated(i32) %a) ["preallocated"(token %cs)]
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: cannot guarantee tail call due to mismatched ABI impacting function attributes
|
||||
define void @musttail_attr_no_match(i32* preallocated(i32) %a) {
|
||||
musttail call void @musttail_and_bundle(i32* %a)
|
||||
ret void
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ declare token @llvm.call.preallocated.setup(i32)
|
||||
declare i8* @llvm.call.preallocated.arg(token, i32)
|
||||
|
||||
declare void @foo1(i32* preallocated(i32))
|
||||
declare i64 @foo1_i64(i32* preallocated(i32))
|
||||
declare void @foo2(i32* preallocated(i32), i32*, i32* preallocated(i32))
|
||||
|
||||
define void @preallocated() {
|
||||
@ -38,3 +39,13 @@ define void @preallocated_num_args() {
|
||||
call void @foo2(i32* preallocated(i32) %x1, i32* %a, i32* preallocated(i32) %y1) ["preallocated"(token %cs)]
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @preallocate_musttail(i32* preallocated(i32) %a) {
|
||||
musttail call void @foo1(i32* preallocated(i32) %a)
|
||||
ret void
|
||||
}
|
||||
|
||||
define i64 @preallocate_musttail_i64(i32* preallocated(i32) %a) {
|
||||
%r = musttail call i64 @foo1_i64(i32* preallocated(i32) %a)
|
||||
ret i64 %r
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user