xref: /llvm-project/llvm/test/Verifier/preallocated-invalid.ll (revision b05c71814c3b9f91a2e00af891d67a83790a109c)
1; RUN: not opt -S %s -passes=verify 2>&1 | FileCheck %s
2
3declare token @llvm.call.preallocated.setup(i32)
4declare ptr @llvm.call.preallocated.arg(token, i32)
5declare void @llvm.call.preallocated.teardown(token)
6
7; Fake LLVM intrinsic to return a token
8declare token @llvm.what()
9
10declare void @foo0()
11declare void @foo1(ptr preallocated(i32))
12declare void @foo2(ptr preallocated(i32), ptr, ptr preallocated(i32))
13declare i32 @blackbox()
14
15; CHECK: llvm.call.preallocated.arg must be called with a "preallocated" call site attribute
16define void @preallocated_arg_missing_preallocated_attribute() {
17    %cs = call token @llvm.call.preallocated.setup(i32 1)
18    %x = call ptr @llvm.call.preallocated.arg(token %cs, i32 0)
19    call void @foo1(ptr preallocated(i32) %x) ["preallocated"(token %cs)]
20    ret void
21}
22
23; CHECK: preallocated as a call site attribute can only be on llvm.call.preallocated.arg
24define void @preallocated_call_site_attribute_not_on_arg() {
25    call void @foo0() preallocated(i32)
26    ret void
27}
28
29; CHECK: "preallocated" argument must be a token from llvm.call.preallocated.setup
30define void @preallocated_bundle_token() {
31    %i = call i32 @blackbox()
32    call void @foo0() ["preallocated"(i32 %i)]
33    ret void
34}
35
36; CHECK: "preallocated" argument must be a token from llvm.call.preallocated.setup
37define void @preallocated_bundle_token_from_setup() {
38    %cs = call token @llvm.what()
39    call void @foo0() ["preallocated"(token %cs)]
40    ret void
41}
42
43; CHECK: Expected exactly one preallocated bundle operand
44define void @preallocated_bundle_one_token() {
45    %cs0 = call token @llvm.call.preallocated.setup(i32 0)
46    %cs1 = call token @llvm.call.preallocated.setup(i32 0)
47    call void @foo0() ["preallocated"(token %cs0, token %cs1)]
48    ret void
49}
50
51; CHECK: Multiple preallocated operand bundles
52define void @preallocated_multiple_bundles() {
53    %cs0 = call token @llvm.call.preallocated.setup(i32 0)
54    %cs1 = call token @llvm.call.preallocated.setup(i32 0)
55    call void @foo0() ["preallocated"(token %cs0), "preallocated"(token %cs1)]
56    ret void
57}
58
59; CHECK: Can have at most one call
60define void @preallocated_one_call() {
61    %cs = call token @llvm.call.preallocated.setup(i32 1)
62    %x = call ptr @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
63    call void @foo1(ptr preallocated(i32) %x) ["preallocated"(token %cs)]
64    call void @foo1(ptr preallocated(i32) %x) ["preallocated"(token %cs)]
65    ret void
66}
67
68; CHECK: must be a constant
69define void @preallocated_setup_constant() {
70    %ac = call i32 @blackbox()
71    %cs = call token @llvm.call.preallocated.setup(i32 %ac)
72    ret void
73}
74
75; CHECK: must be between 0 and corresponding
76define void @preallocated_setup_arg_index_in_bounds() {
77    %cs = call token @llvm.call.preallocated.setup(i32 2)
78    %a0 = call ptr @llvm.call.preallocated.arg(token %cs, i32 2) preallocated(i32)
79    ret void
80}
81
82; CHECK: preallocated operand either requires a preallocated bundle or the call to be musttail
83define void @preallocated_require_bundle() {
84    %cs = call token @llvm.call.preallocated.setup(i32 1)
85    %x = call ptr @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
86    call void @foo1(ptr preallocated(i32) %x)
87    ret void
88}
89
90; CHECK: arg size must be equal to number of preallocated arguments
91define void @preallocated_num_args() {
92    %cs = call token @llvm.call.preallocated.setup(i32 3)
93    %x = call ptr @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
94    %y = call ptr @llvm.call.preallocated.arg(token %cs, i32 1) preallocated(i32)
95    %a = inttoptr i32 0 to ptr
96    call void @foo2(ptr preallocated(i32) %x, ptr %a, ptr preallocated(i32) %y) ["preallocated"(token %cs)]
97    ret void
98}
99
100; CHECK: token argument must be a llvm.call.preallocated.setup
101define void @preallocated_arg_token() {
102    %t = call token @llvm.what()
103    %x = call ptr @llvm.call.preallocated.arg(token %t, i32 1) preallocated(i32)
104    ret void
105}
106
107; CHECK: cannot use preallocated intrinsics on a call without preallocated arguments
108define void @preallocated_no_preallocated_args() {
109    %cs = call token @llvm.call.preallocated.setup(i32 0)
110    call void @foo0() ["preallocated"(token %cs)]
111    ret void
112}
113
114; CHECK: preallocated operand either requires a preallocated bundle or the call to be musttail
115define void @musttail_and_bundle(ptr preallocated(i32) %a) {
116    %cs = call token @llvm.call.preallocated.setup(i32 0)
117    musttail call void @musttail_and_bundle(ptr preallocated(i32) %a) ["preallocated"(token %cs)]
118    ret void
119}
120
121; CHECK: cannot guarantee tail call due to mismatched ABI impacting function attributes
122define void @musttail_attr_no_match(ptr preallocated(i32) %a) {
123    musttail call void @musttail_and_bundle(ptr %a)
124    ret void
125}
126
127; CHECK: token argument must be a llvm.call.preallocated.setup
128define void @teardown_token_not_from_setup() {
129    %cs = call token @llvm.what()
130    call void @llvm.call.preallocated.teardown(token %cs)
131    ret void
132}
133
134; CHECK: Attribute 'preallocated(i32)' applied to incompatible type!
135; CHECK-NEXT: ptr @not_pointer
136declare void @not_pointer(i32 preallocated(i32))
137