• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: not opt -S %s -verify 2>&1 | FileCheck %s
2
3declare token @llvm.call.preallocated.setup(i32)
4declare i8* @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(i32* preallocated(i32))
12declare void @foo2(i32* preallocated(i32), i32*, i32* 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 i8* @llvm.call.preallocated.arg(token %cs, i32 0)
19    %y = bitcast i8* %x to i32*
20    call void @foo1(i32* preallocated(i32) %y) ["preallocated"(token %cs)]
21    ret void
22}
23
24; CHECK: preallocated as a call site attribute can only be on llvm.call.preallocated.arg
25define void @preallocated_call_site_attribute_not_on_arg() {
26    call void @foo0() preallocated(i32)
27    ret void
28}
29
30; CHECK: "preallocated" argument must be a token from llvm.call.preallocated.setup
31define void @preallocated_bundle_token() {
32    %i = call i32 @blackbox()
33    call void @foo0() ["preallocated"(i32 %i)]
34    ret void
35}
36
37; CHECK: "preallocated" argument must be a token from llvm.call.preallocated.setup
38define void @preallocated_bundle_token_from_setup() {
39    %cs = call token @llvm.what()
40    call void @foo0() ["preallocated"(token %cs)]
41    ret void
42}
43
44; CHECK: Expected exactly one preallocated bundle operand
45define void @preallocated_bundle_one_token() {
46    %cs0 = call token @llvm.call.preallocated.setup(i32 0)
47    %cs1 = call token @llvm.call.preallocated.setup(i32 0)
48    call void @foo0() ["preallocated"(token %cs0, token %cs1)]
49    ret void
50}
51
52; CHECK: Multiple preallocated operand bundles
53define void @preallocated_multiple_bundles() {
54    %cs0 = call token @llvm.call.preallocated.setup(i32 0)
55    %cs1 = call token @llvm.call.preallocated.setup(i32 0)
56    call void @foo0() ["preallocated"(token %cs0), "preallocated"(token %cs1)]
57    ret void
58}
59
60; CHECK: Can have at most one call
61define void @preallocated_one_call() {
62    %cs = call token @llvm.call.preallocated.setup(i32 1)
63    %x = call i8* @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
64    %y = bitcast i8* %x to i32*
65    call void @foo1(i32* preallocated(i32) %y) ["preallocated"(token %cs)]
66    call void @foo1(i32* preallocated(i32) %y) ["preallocated"(token %cs)]
67    ret void
68}
69
70; CHECK: must be a constant
71define void @preallocated_setup_constant() {
72    %ac = call i32 @blackbox()
73    %cs = call token @llvm.call.preallocated.setup(i32 %ac)
74    ret void
75}
76
77; CHECK: must be between 0 and corresponding
78define void @preallocated_setup_arg_index_in_bounds() {
79    %cs = call token @llvm.call.preallocated.setup(i32 2)
80    %a0 = call i8* @llvm.call.preallocated.arg(token %cs, i32 2) preallocated(i32)
81    ret void
82}
83
84; CHECK: Attribute 'preallocated' type does not match parameter
85define void @preallocated_attribute_type_mismatch() {
86    %cs = call token @llvm.call.preallocated.setup(i32 1)
87    %x = call i8* @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
88    %y = bitcast i8* %x to i32*
89    call void @foo1(i32* preallocated(i8) %y) ["preallocated"(token %cs)]
90    ret void
91}
92
93; CHECK: preallocated operand either requires a preallocated bundle or the call to be musttail
94define void @preallocated_require_bundle() {
95    %cs = call token @llvm.call.preallocated.setup(i32 1)
96    %x = call i8* @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
97    %y = bitcast i8* %x to i32*
98    call void @foo1(i32* preallocated(i32) %y)
99    ret void
100}
101
102; CHECK: arg size must be equal to number of preallocated arguments
103define void @preallocated_num_args() {
104    %cs = call token @llvm.call.preallocated.setup(i32 3)
105    %x = call i8* @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32)
106    %x1 = bitcast i8* %x to i32*
107    %y = call i8* @llvm.call.preallocated.arg(token %cs, i32 1) preallocated(i32)
108    %y1 = bitcast i8* %y to i32*
109    %a = inttoptr i32 0 to i32*
110    call void @foo2(i32* preallocated(i32) %x1, i32* %a, i32* preallocated(i32) %y1) ["preallocated"(token %cs)]
111    ret void
112}
113
114; CHECK: token argument must be a llvm.call.preallocated.setup
115define void @preallocated_arg_token() {
116    %t = call token @llvm.what()
117    %x = call i8* @llvm.call.preallocated.arg(token %t, i32 1) preallocated(i32)
118    ret void
119}
120
121; CHECK: cannot use preallocated intrinsics on a call without preallocated arguments
122define void @preallocated_no_preallocated_args() {
123    %cs = call token @llvm.call.preallocated.setup(i32 0)
124    call void @foo0() ["preallocated"(token %cs)]
125    ret void
126}
127
128; CHECK: preallocated operand either requires a preallocated bundle or the call to be musttail
129define void @musttail_and_bundle(i32* preallocated(i32) %a) {
130    %cs = call token @llvm.call.preallocated.setup(i32 0)
131    musttail call void @musttail_and_bundle(i32* preallocated(i32) %a) ["preallocated"(token %cs)]
132    ret void
133}
134
135; CHECK: cannot guarantee tail call due to mismatched ABI impacting function attributes
136define void @musttail_attr_no_match(i32* preallocated(i32) %a) {
137    musttail call void @musttail_and_bundle(i32* %a)
138    ret void
139}
140
141; CHECK: token argument must be a llvm.call.preallocated.setup
142define void @teardown_token_not_from_setup() {
143    %cs = call token @llvm.what()
144    call void @llvm.call.preallocated.teardown(token %cs)
145    ret void
146}
147
148; CHECK: Wrong types for attribute:
149; CHECK-NEXT: void (i32)* @not_pointer
150declare void @not_pointer(i32 preallocated(i32))
151