mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
b227a46d3d
A couple of attributes had explicit checks for incompatibility with pointer types. However, this is already handled generically by the typeIncompatible() check. We can drop these after adding SwiftError to typeIncompatible(). However, the previous implementation of the check prints out all attributes that are incompatible with a given type, even though those attributes aren't actually used. This has the annoying result that the error message changes every time a new attribute is added to the list. Improve this by explicitly finding which attribute isn't compatible and printing just that.
151 lines
5.6 KiB
LLVM
151 lines
5.6 KiB
LLVM
; RUN: not opt -S %s -verify 2>&1 | FileCheck %s
|
|
|
|
declare token @llvm.call.preallocated.setup(i32)
|
|
declare i8* @llvm.call.preallocated.arg(token, i32)
|
|
declare void @llvm.call.preallocated.teardown(token)
|
|
|
|
; Fake LLVM intrinsic to return a token
|
|
declare token @llvm.what()
|
|
|
|
declare void @foo0()
|
|
declare void @foo1(i32* preallocated(i32))
|
|
declare void @foo2(i32* preallocated(i32), i32*, i32* preallocated(i32))
|
|
declare i32 @blackbox()
|
|
|
|
; CHECK: llvm.call.preallocated.arg must be called with a "preallocated" call site attribute
|
|
define void @preallocated_arg_missing_preallocated_attribute() {
|
|
%cs = call token @llvm.call.preallocated.setup(i32 1)
|
|
%x = call i8* @llvm.call.preallocated.arg(token %cs, i32 0)
|
|
%y = bitcast i8* %x to i32*
|
|
call void @foo1(i32* preallocated(i32) %y) ["preallocated"(token %cs)]
|
|
ret void
|
|
}
|
|
|
|
; CHECK: preallocated as a call site attribute can only be on llvm.call.preallocated.arg
|
|
define void @preallocated_call_site_attribute_not_on_arg() {
|
|
call void @foo0() preallocated(i32)
|
|
ret void
|
|
}
|
|
|
|
; CHECK: "preallocated" argument must be a token from llvm.call.preallocated.setup
|
|
define void @preallocated_bundle_token() {
|
|
%i = call i32 @blackbox()
|
|
call void @foo0() ["preallocated"(i32 %i)]
|
|
ret void
|
|
}
|
|
|
|
; CHECK: "preallocated" argument must be a token from llvm.call.preallocated.setup
|
|
define void @preallocated_bundle_token_from_setup() {
|
|
%cs = call token @llvm.what()
|
|
call void @foo0() ["preallocated"(token %cs)]
|
|
ret void
|
|
}
|
|
|
|
; CHECK: Expected exactly one preallocated bundle operand
|
|
define void @preallocated_bundle_one_token() {
|
|
%cs0 = call token @llvm.call.preallocated.setup(i32 0)
|
|
%cs1 = call token @llvm.call.preallocated.setup(i32 0)
|
|
call void @foo0() ["preallocated"(token %cs0, token %cs1)]
|
|
ret void
|
|
}
|
|
|
|
; CHECK: Multiple preallocated operand bundles
|
|
define void @preallocated_multiple_bundles() {
|
|
%cs0 = call token @llvm.call.preallocated.setup(i32 0)
|
|
%cs1 = call token @llvm.call.preallocated.setup(i32 0)
|
|
call void @foo0() ["preallocated"(token %cs0), "preallocated"(token %cs1)]
|
|
ret void
|
|
}
|
|
|
|
; CHECK: Can have at most one call
|
|
define void @preallocated_one_call() {
|
|
%cs = call token @llvm.call.preallocated.setup(i32 1)
|
|
%x = call i8* @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
|
|
%y = bitcast i8* %x to i32*
|
|
call void @foo1(i32* preallocated(i32) %y) ["preallocated"(token %cs)]
|
|
call void @foo1(i32* preallocated(i32) %y) ["preallocated"(token %cs)]
|
|
ret void
|
|
}
|
|
|
|
; CHECK: must be a constant
|
|
define void @preallocated_setup_constant() {
|
|
%ac = call i32 @blackbox()
|
|
%cs = call token @llvm.call.preallocated.setup(i32 %ac)
|
|
ret void
|
|
}
|
|
|
|
; CHECK: must be between 0 and corresponding
|
|
define void @preallocated_setup_arg_index_in_bounds() {
|
|
%cs = call token @llvm.call.preallocated.setup(i32 2)
|
|
%a0 = call i8* @llvm.call.preallocated.arg(token %cs, i32 2) preallocated(i32)
|
|
ret void
|
|
}
|
|
|
|
; CHECK: Attribute 'preallocated' type does not match parameter
|
|
define void @preallocated_attribute_type_mismatch() {
|
|
%cs = call token @llvm.call.preallocated.setup(i32 1)
|
|
%x = call i8* @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
|
|
%y = bitcast i8* %x to i32*
|
|
call void @foo1(i32* preallocated(i8) %y) ["preallocated"(token %cs)]
|
|
ret void
|
|
}
|
|
|
|
; 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)
|
|
%y = bitcast i8* %x to i32*
|
|
call void @foo1(i32* preallocated(i32) %y)
|
|
ret void
|
|
}
|
|
|
|
; CHECK: arg size must be equal to number of preallocated arguments
|
|
define void @preallocated_num_args() {
|
|
%cs = call token @llvm.call.preallocated.setup(i32 3)
|
|
%x = call i8* @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
|
|
%x1 = bitcast i8* %x to i32*
|
|
%y = call i8* @llvm.call.preallocated.arg(token %cs, i32 1) preallocated(i32)
|
|
%y1 = bitcast i8* %y to i32*
|
|
%a = inttoptr i32 0 to i32*
|
|
call void @foo2(i32* preallocated(i32) %x1, i32* %a, i32* preallocated(i32) %y1) ["preallocated"(token %cs)]
|
|
ret void
|
|
}
|
|
|
|
; CHECK: token argument must be a llvm.call.preallocated.setup
|
|
define void @preallocated_arg_token() {
|
|
%t = call token @llvm.what()
|
|
%x = call i8* @llvm.call.preallocated.arg(token %t, i32 1) preallocated(i32)
|
|
ret void
|
|
}
|
|
|
|
; 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)
|
|
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
|
|
}
|
|
|
|
; CHECK: token argument must be a llvm.call.preallocated.setup
|
|
define void @teardown_token_not_from_setup() {
|
|
%cs = call token @llvm.what()
|
|
call void @llvm.call.preallocated.teardown(token %cs)
|
|
ret void
|
|
}
|
|
|
|
; CHECK: Attribute 'preallocated(i32)' applied to incompatible type!
|
|
; CHECK-NEXT: void (i32)* @not_pointer
|
|
declare void @not_pointer(i32 preallocated(i32))
|