preallocated-invalid.ll
5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
; 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
}