blob: d801743765a52ed9d1875f3cb452b9227b07341e [file] [edit]
// RUN: mlir-opt %s -split-input-file -verify-diagnostics
// Violations of the 1:1 relationship between the forwarded operands/results of
// a call operation and the arguments/results of its callee, as reported by
// `call_interface_impl::verifyCallOpInterface`.
// `test.call_and_produce` produces its first result itself; only the trailing
// results are forwarded from the callee. Neither the produced result nor a
// non-forwarded operand takes part in the verification.
func.func private @callee(i32) -> i32
func.func @too_many_forwarded_operands(%arg0: i32) {
// expected-error @below {{incorrect number of operands for callee: expected 1, but got 2}}
%status, %res = test.call_and_produce @callee(%arg0, %arg0) : (i32, i32) -> (i1, i32)
return
}
// -----
func.func private @callee(i32, i32) -> i32
func.func @too_few_forwarded_operands(%arg0: i32) {
// expected-error @below {{incorrect number of operands for callee: expected 2, but got 1}}
%status, %res = test.call_and_produce @callee(%arg0) : (i32) -> (i1, i32)
return
}
// -----
func.func private @callee(i32) -> i32
func.func @too_many_forwarded_results(%arg0: i32) {
// expected-error @below {{incorrect number of results for callee: expected 1, but got 2}}
%status, %res0, %res1 = test.call_and_produce @callee(%arg0) : (i32) -> (i1, i32, i32)
return
}
// -----
func.func private @callee(i32) -> (i32, i32)
func.func @too_few_forwarded_results(%arg0: i32) {
// expected-error @below {{incorrect number of results for callee: expected 2, but got 1}}
%status, %res = test.call_and_produce @callee(%arg0) : (i32) -> (i1, i32)
return
}
// -----
// The verifier requires corresponding types to be equal.
func.func private @callee(i32) -> i32
func.func @operand_types_must_match(%arg0: f32) {
// expected-error @below {{operand type mismatch: expected operand type 'i32', but provided 'f32' for operand number 0}}
%status, %res = test.call_and_produce @callee(%arg0) : (f32) -> (i1, i32)
return
}
// -----
func.func private @callee(i32) -> i32
func.func @result_types_must_match(%arg0: i32) {
// expected-error @+3 {{result type mismatch at index 0}}
// expected-note @+2 {{op result types: 'f64'}}
// expected-note @+1 {{callee result types: 'i32'}}
%status, %res = test.call_and_produce @callee(%arg0) : (i32) -> (i1, f64)
return
}
// -----
// The declared parameters of a variadic callee are still checked. Here
// `var_callee_type` declares one parameter while the callee declares two, so
// only one operand is an argument operand and the call does not match.
llvm.func @printf(!llvm.ptr, i32, ...) -> i32
llvm.func @inconsistent_var_callee_type(%arg0: !llvm.ptr, %arg1: i32) {
// expected-error @below {{incorrect number of operands for callee: expected 2, but got 1}}
%res = llvm.call @printf(%arg0, %arg1) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i32) -> i32
llvm.return
}
// -----
// A call operation that does not model variadic callees claims all its operands
// as argument operands, so it does not satisfy the 1:1 relationship here.
llvm.func @printf(!llvm.ptr, ...) -> i32
func.func @variadic_callee_not_modelled(%arg0: !llvm.ptr, %arg1: i32) {
// expected-error @below {{incorrect number of operands for callee: expected 1, but got 2}}
%status, %res = test.call_and_produce @printf(%arg0, %arg1) : (!llvm.ptr, i32) -> (i1, i32)
return
}
// -----
// `func.call` can never be variadic: the builtin `FunctionType` has no variadic
// bit, so the number of forwarded operands always matches the callee exactly.
func.func private @callee(i32) -> i32
func.func @func_call_is_never_variadic(%arg0: i32) {
// expected-error @below {{incorrect number of operands for callee}}
%res = func.call @callee(%arg0, %arg0) : (i32, i32) -> i32
return
}