Skip to content

Commit 96f3f03

Browse files
arichardsonresistor
authored andcommitted
[InstSimplify] Add a test for current get/set intrinsic folding
1 parent 53e5821 commit 96f3f03

File tree

1 file changed

+296
-0
lines changed

1 file changed

+296
-0
lines changed
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --force-update
2+
;; Check folds for CHERI intrinsics that have both get and set variants
3+
; RUN: sed 's/FIELD/address/' %s | opt -S -passes=instsimplify | FileCheck %s --check-prefixes=ADDRESS
4+
; RUN: sed 's/FIELD/flags/' %s | opt -S -passes=instsimplify | FileCheck %s --check-prefixes=FLAGS
5+
; RUN: sed 's/FIELD/high/' %s | opt -S -passes=instsimplify | FileCheck %s --check-prefixes=HIGH
6+
; RUN: sed 's/FIELD/offset/' %s | opt -S -passes=instsimplify | FileCheck %s --check-prefixes=OFFSET
7+
target datalayout = "pf200:128:128:128:64-A200-P200-G200"
8+
9+
declare i64 @check_fold(i64) nounwind
10+
declare i64 @llvm.cheri.cap.FIELD.get.i64(ptr addrspace(200)) nounwind
11+
declare ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200), i64) nounwind
12+
13+
14+
;; This is a no-op and should be folded to ret %arg
15+
define ptr addrspace(200) @fold_set_of_get(ptr addrspace(200) %arg) nounwind {
16+
; ADDRESS-LABEL: define {{[^@]+}}@fold_set_of_get
17+
; ADDRESS-SAME: (ptr addrspace(200) [[ARG:%.*]]) addrspace(200) #[[ATTR0:[0-9]+]] {
18+
; ADDRESS-NEXT: ret ptr addrspace(200) [[ARG]]
19+
;
20+
; FLAGS-LABEL: define {{[^@]+}}@fold_set_of_get
21+
; FLAGS-SAME: (ptr addrspace(200) [[ARG:%.*]]) addrspace(200) #[[ATTR0:[0-9]+]] {
22+
; FLAGS-NEXT: [[VALUE:%.*]] = tail call i64 @llvm.cheri.cap.flags.get.i64(ptr addrspace(200) [[ARG]])
23+
; FLAGS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.flags.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
24+
; FLAGS-NEXT: ret ptr addrspace(200) [[RET]]
25+
;
26+
; HIGH-LABEL: define {{[^@]+}}@fold_set_of_get
27+
; HIGH-SAME: (ptr addrspace(200) [[ARG:%.*]]) addrspace(200) #[[ATTR0:[0-9]+]] {
28+
; HIGH-NEXT: [[VALUE:%.*]] = tail call i64 @llvm.cheri.cap.high.get.i64(ptr addrspace(200) [[ARG]])
29+
; HIGH-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.high.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
30+
; HIGH-NEXT: ret ptr addrspace(200) [[RET]]
31+
;
32+
; OFFSET-LABEL: define {{[^@]+}}@fold_set_of_get
33+
; OFFSET-SAME: (ptr addrspace(200) [[ARG:%.*]]) addrspace(200) #[[ATTR0:[0-9]+]] {
34+
; OFFSET-NEXT: ret ptr addrspace(200) [[ARG]]
35+
;
36+
%value = tail call i64 @llvm.cheri.cap.FIELD.get.i64(ptr addrspace(200) %arg)
37+
%ret = tail call ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200) %arg, i64 %value)
38+
ret ptr addrspace(200) %ret
39+
}
40+
41+
;; negative test - get of a different value should not be folded to ret %arg
42+
define ptr addrspace(200) @fold_set_of_get_bad(ptr addrspace(200) %arg, ptr addrspace(200) %other) nounwind {
43+
; ADDRESS-LABEL: define {{[^@]+}}@fold_set_of_get_bad
44+
; ADDRESS-SAME: (ptr addrspace(200) [[ARG:%.*]], ptr addrspace(200) [[OTHER:%.*]]) addrspace(200) #[[ATTR0]] {
45+
; ADDRESS-NEXT: [[VALUE:%.*]] = tail call i64 @llvm.cheri.cap.address.get.i64(ptr addrspace(200) [[OTHER]])
46+
; ADDRESS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.address.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
47+
; ADDRESS-NEXT: ret ptr addrspace(200) [[RET]]
48+
;
49+
; FLAGS-LABEL: define {{[^@]+}}@fold_set_of_get_bad
50+
; FLAGS-SAME: (ptr addrspace(200) [[ARG:%.*]], ptr addrspace(200) [[OTHER:%.*]]) addrspace(200) #[[ATTR0]] {
51+
; FLAGS-NEXT: [[VALUE:%.*]] = tail call i64 @llvm.cheri.cap.flags.get.i64(ptr addrspace(200) [[OTHER]])
52+
; FLAGS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.flags.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
53+
; FLAGS-NEXT: ret ptr addrspace(200) [[RET]]
54+
;
55+
; HIGH-LABEL: define {{[^@]+}}@fold_set_of_get_bad
56+
; HIGH-SAME: (ptr addrspace(200) [[ARG:%.*]], ptr addrspace(200) [[OTHER:%.*]]) addrspace(200) #[[ATTR0]] {
57+
; HIGH-NEXT: [[VALUE:%.*]] = tail call i64 @llvm.cheri.cap.high.get.i64(ptr addrspace(200) [[OTHER]])
58+
; HIGH-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.high.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
59+
; HIGH-NEXT: ret ptr addrspace(200) [[RET]]
60+
;
61+
; OFFSET-LABEL: define {{[^@]+}}@fold_set_of_get_bad
62+
; OFFSET-SAME: (ptr addrspace(200) [[ARG:%.*]], ptr addrspace(200) [[OTHER:%.*]]) addrspace(200) #[[ATTR0]] {
63+
; OFFSET-NEXT: [[VALUE:%.*]] = tail call i64 @llvm.cheri.cap.offset.get.i64(ptr addrspace(200) [[OTHER]])
64+
; OFFSET-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.offset.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
65+
; OFFSET-NEXT: ret ptr addrspace(200) [[RET]]
66+
;
67+
%value = tail call i64 @llvm.cheri.cap.FIELD.get.i64(ptr addrspace(200) %other)
68+
%ret = tail call ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200) %arg, i64 %value)
69+
ret ptr addrspace(200) %ret
70+
}
71+
72+
;; For almost all intrinsics this get-of-set pair can be elided
73+
;; NB: This is not true for flags where the value written by set could be truncated to another value
74+
;; FIXME: high.get should be folded.
75+
define i64 @fold_get_of_set(ptr addrspace(200) %arg, i64 %value) nounwind {
76+
; ADDRESS-LABEL: define {{[^@]+}}@fold_get_of_set
77+
; ADDRESS-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
78+
; ADDRESS-NEXT: ret i64 [[VALUE]]
79+
;
80+
; FLAGS-LABEL: define {{[^@]+}}@fold_get_of_set
81+
; FLAGS-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
82+
; FLAGS-NEXT: [[MODIFIED:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.flags.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
83+
; FLAGS-NEXT: [[RET:%.*]] = tail call i64 @llvm.cheri.cap.flags.get.i64(ptr addrspace(200) [[MODIFIED]])
84+
; FLAGS-NEXT: ret i64 [[RET]]
85+
;
86+
; HIGH-LABEL: define {{[^@]+}}@fold_get_of_set
87+
; HIGH-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
88+
; HIGH-NEXT: [[MODIFIED:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.high.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
89+
; HIGH-NEXT: [[RET:%.*]] = tail call i64 @llvm.cheri.cap.high.get.i64(ptr addrspace(200) [[MODIFIED]])
90+
; HIGH-NEXT: ret i64 [[RET]]
91+
;
92+
; OFFSET-LABEL: define {{[^@]+}}@fold_get_of_set
93+
; OFFSET-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
94+
; OFFSET-NEXT: ret i64 [[VALUE]]
95+
;
96+
%modified = tail call ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200) %arg, i64 %value)
97+
%ret = tail call i64 @llvm.cheri.cap.FIELD.get.i64(ptr addrspace(200) %modified)
98+
ret i64 %ret
99+
}
100+
101+
;; Negative test -- get is used on other intrinsic
102+
define i64 @fold_get_of_set_bad(ptr addrspace(200) %arg, ptr addrspace(200) %other, i64 %value) nounwind {
103+
; ADDRESS-LABEL: define {{[^@]+}}@fold_get_of_set_bad
104+
; ADDRESS-SAME: (ptr addrspace(200) [[ARG:%.*]], ptr addrspace(200) [[OTHER:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
105+
; ADDRESS-NEXT: [[RET:%.*]] = tail call i64 @llvm.cheri.cap.address.get.i64(ptr addrspace(200) [[ARG]])
106+
; ADDRESS-NEXT: ret i64 [[RET]]
107+
;
108+
; FLAGS-LABEL: define {{[^@]+}}@fold_get_of_set_bad
109+
; FLAGS-SAME: (ptr addrspace(200) [[ARG:%.*]], ptr addrspace(200) [[OTHER:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
110+
; FLAGS-NEXT: [[RET:%.*]] = tail call i64 @llvm.cheri.cap.flags.get.i64(ptr addrspace(200) [[ARG]])
111+
; FLAGS-NEXT: ret i64 [[RET]]
112+
;
113+
; HIGH-LABEL: define {{[^@]+}}@fold_get_of_set_bad
114+
; HIGH-SAME: (ptr addrspace(200) [[ARG:%.*]], ptr addrspace(200) [[OTHER:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
115+
; HIGH-NEXT: [[RET:%.*]] = tail call i64 @llvm.cheri.cap.high.get.i64(ptr addrspace(200) [[ARG]])
116+
; HIGH-NEXT: ret i64 [[RET]]
117+
;
118+
; OFFSET-LABEL: define {{[^@]+}}@fold_get_of_set_bad
119+
; OFFSET-SAME: (ptr addrspace(200) [[ARG:%.*]], ptr addrspace(200) [[OTHER:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
120+
; OFFSET-NEXT: [[RET:%.*]] = tail call i64 @llvm.cheri.cap.offset.get.i64(ptr addrspace(200) [[ARG]])
121+
; OFFSET-NEXT: ret i64 [[RET]]
122+
;
123+
%modified = tail call ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200) %other, i64 %value)
124+
%ret = tail call i64 @llvm.cheri.cap.FIELD.get.i64(ptr addrspace(200) %arg)
125+
ret i64 %ret
126+
}
127+
128+
define i64 @fold_get_on_null() nounwind {
129+
; ADDRESS-LABEL: define {{[^@]+}}@fold_get_on_null
130+
; ADDRESS-SAME: () addrspace(200) #[[ATTR0]] {
131+
; ADDRESS-NEXT: ret i64 0
132+
;
133+
; FLAGS-LABEL: define {{[^@]+}}@fold_get_on_null
134+
; FLAGS-SAME: () addrspace(200) #[[ATTR0]] {
135+
; FLAGS-NEXT: ret i64 0
136+
;
137+
; HIGH-LABEL: define {{[^@]+}}@fold_get_on_null
138+
; HIGH-SAME: () addrspace(200) #[[ATTR0]] {
139+
; HIGH-NEXT: [[RET:%.*]] = tail call i64 @llvm.cheri.cap.high.get.i64(ptr addrspace(200) null)
140+
; HIGH-NEXT: ret i64 [[RET]]
141+
;
142+
; OFFSET-LABEL: define {{[^@]+}}@fold_get_on_null
143+
; OFFSET-SAME: () addrspace(200) #[[ATTR0]] {
144+
; OFFSET-NEXT: ret i64 0
145+
;
146+
%ret = tail call i64 @llvm.cheri.cap.FIELD.get.i64(ptr addrspace(200) null)
147+
ret i64 %ret
148+
}
149+
150+
define i64 @fold_get_on_null_with_gep(i64 %value, i64 %gepoff) nounwind {
151+
; ADDRESS-LABEL: define {{[^@]+}}@fold_get_on_null_with_gep
152+
; ADDRESS-SAME: (i64 [[VALUE:%.*]], i64 [[GEPOFF:%.*]]) addrspace(200) #[[ATTR0]] {
153+
; ADDRESS-NEXT: ret i64 [[GEPOFF]]
154+
;
155+
; FLAGS-LABEL: define {{[^@]+}}@fold_get_on_null_with_gep
156+
; FLAGS-SAME: (i64 [[VALUE:%.*]], i64 [[GEPOFF:%.*]]) addrspace(200) #[[ATTR0]] {
157+
; FLAGS-NEXT: ret i64 0
158+
;
159+
; HIGH-LABEL: define {{[^@]+}}@fold_get_on_null_with_gep
160+
; HIGH-SAME: (i64 [[VALUE:%.*]], i64 [[GEPOFF:%.*]]) addrspace(200) #[[ATTR0]] {
161+
; HIGH-NEXT: [[TMP:%.*]] = getelementptr i8, ptr addrspace(200) null, i64 [[GEPOFF]]
162+
; HIGH-NEXT: [[RET:%.*]] = tail call i64 @llvm.cheri.cap.high.get.i64(ptr addrspace(200) [[TMP]])
163+
; HIGH-NEXT: ret i64 [[RET]]
164+
;
165+
; OFFSET-LABEL: define {{[^@]+}}@fold_get_on_null_with_gep
166+
; OFFSET-SAME: (i64 [[VALUE:%.*]], i64 [[GEPOFF:%.*]]) addrspace(200) #[[ATTR0]] {
167+
; OFFSET-NEXT: ret i64 [[GEPOFF]]
168+
;
169+
%tmp = getelementptr i8, ptr addrspace(200) null, i64 %gepoff
170+
%ret = tail call i64 @llvm.cheri.cap.FIELD.get.i64(ptr addrspace(200) %tmp)
171+
ret i64 %ret
172+
}
173+
174+
;; TODO: Setting is idempotent, so the first call should be elided
175+
define ptr addrspace(200) @set_idempotent(ptr addrspace(200) %arg, i64 %value) nounwind {
176+
; ADDRESS-LABEL: define {{[^@]+}}@set_idempotent
177+
; ADDRESS-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
178+
; ADDRESS-NEXT: [[MODIFIED:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.address.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
179+
; ADDRESS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.address.set.i64(ptr addrspace(200) [[MODIFIED]], i64 [[VALUE]])
180+
; ADDRESS-NEXT: ret ptr addrspace(200) [[RET]]
181+
;
182+
; FLAGS-LABEL: define {{[^@]+}}@set_idempotent
183+
; FLAGS-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
184+
; FLAGS-NEXT: [[MODIFIED:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.flags.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
185+
; FLAGS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.flags.set.i64(ptr addrspace(200) [[MODIFIED]], i64 [[VALUE]])
186+
; FLAGS-NEXT: ret ptr addrspace(200) [[RET]]
187+
;
188+
; HIGH-LABEL: define {{[^@]+}}@set_idempotent
189+
; HIGH-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
190+
; HIGH-NEXT: [[MODIFIED:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.high.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
191+
; HIGH-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.high.set.i64(ptr addrspace(200) [[MODIFIED]], i64 [[VALUE]])
192+
; HIGH-NEXT: ret ptr addrspace(200) [[RET]]
193+
;
194+
; OFFSET-LABEL: define {{[^@]+}}@set_idempotent
195+
; OFFSET-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
196+
; OFFSET-NEXT: [[MODIFIED:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.offset.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
197+
; OFFSET-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.offset.set.i64(ptr addrspace(200) [[MODIFIED]], i64 [[VALUE]])
198+
; OFFSET-NEXT: ret ptr addrspace(200) [[RET]]
199+
;
200+
%modified = tail call ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200) %arg, i64 %value)
201+
%ret = tail call ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200) %modified, i64 %value)
202+
ret ptr addrspace(200) %ret
203+
}
204+
205+
206+
;; Negative test - calls with the same base argument are not yet elided if the
207+
;; second argument is different since they could have side-effects such as
208+
;; clearing the tag. For example `setoffset(setoffset(x, <LARGE>), <SMALL>)`
209+
;; would result in an untagged value if the first setoffset went outside the
210+
;; representable range but that detagging would not happen if we elide it.
211+
;; TODO: Maybe we should do this fold since people should not be relying on
212+
;; representability to clear tags of capabilities.
213+
define ptr addrspace(200) @set_different_values(ptr addrspace(200) %arg, i64 %value, i64 %value2) nounwind {
214+
; ADDRESS-LABEL: define {{[^@]+}}@set_different_values
215+
; ADDRESS-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]], i64 [[VALUE2:%.*]]) addrspace(200) #[[ATTR0]] {
216+
; ADDRESS-NEXT: [[MODIFIED:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.address.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
217+
; ADDRESS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.address.set.i64(ptr addrspace(200) [[MODIFIED]], i64 [[VALUE]])
218+
; ADDRESS-NEXT: ret ptr addrspace(200) [[RET]]
219+
;
220+
; FLAGS-LABEL: define {{[^@]+}}@set_different_values
221+
; FLAGS-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]], i64 [[VALUE2:%.*]]) addrspace(200) #[[ATTR0]] {
222+
; FLAGS-NEXT: [[MODIFIED:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.flags.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
223+
; FLAGS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.flags.set.i64(ptr addrspace(200) [[MODIFIED]], i64 [[VALUE]])
224+
; FLAGS-NEXT: ret ptr addrspace(200) [[RET]]
225+
;
226+
; HIGH-LABEL: define {{[^@]+}}@set_different_values
227+
; HIGH-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]], i64 [[VALUE2:%.*]]) addrspace(200) #[[ATTR0]] {
228+
; HIGH-NEXT: [[MODIFIED:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.high.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
229+
; HIGH-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.high.set.i64(ptr addrspace(200) [[MODIFIED]], i64 [[VALUE]])
230+
; HIGH-NEXT: ret ptr addrspace(200) [[RET]]
231+
;
232+
; OFFSET-LABEL: define {{[^@]+}}@set_different_values
233+
; OFFSET-SAME: (ptr addrspace(200) [[ARG:%.*]], i64 [[VALUE:%.*]], i64 [[VALUE2:%.*]]) addrspace(200) #[[ATTR0]] {
234+
; OFFSET-NEXT: [[MODIFIED:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.offset.set.i64(ptr addrspace(200) [[ARG]], i64 [[VALUE]])
235+
; OFFSET-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.offset.set.i64(ptr addrspace(200) [[MODIFIED]], i64 [[VALUE]])
236+
; OFFSET-NEXT: ret ptr addrspace(200) [[RET]]
237+
;
238+
%modified = tail call ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200) %arg, i64 %value)
239+
%ret = tail call ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200) %modified, i64 %value)
240+
ret ptr addrspace(200) %ret
241+
}
242+
243+
define ptr addrspace(200) @fold_set_on_null(i64 %value) nounwind {
244+
; ADDRESS-LABEL: define {{[^@]+}}@fold_set_on_null
245+
; ADDRESS-SAME: (i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
246+
; ADDRESS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.address.set.i64(ptr addrspace(200) null, i64 [[VALUE]])
247+
; ADDRESS-NEXT: ret ptr addrspace(200) [[RET]]
248+
;
249+
; FLAGS-LABEL: define {{[^@]+}}@fold_set_on_null
250+
; FLAGS-SAME: (i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
251+
; FLAGS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.flags.set.i64(ptr addrspace(200) null, i64 [[VALUE]])
252+
; FLAGS-NEXT: ret ptr addrspace(200) [[RET]]
253+
;
254+
; HIGH-LABEL: define {{[^@]+}}@fold_set_on_null
255+
; HIGH-SAME: (i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
256+
; HIGH-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.high.set.i64(ptr addrspace(200) null, i64 [[VALUE]])
257+
; HIGH-NEXT: ret ptr addrspace(200) [[RET]]
258+
;
259+
; OFFSET-LABEL: define {{[^@]+}}@fold_set_on_null
260+
; OFFSET-SAME: (i64 [[VALUE:%.*]]) addrspace(200) #[[ATTR0]] {
261+
; OFFSET-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.offset.set.i64(ptr addrspace(200) null, i64 [[VALUE]])
262+
; OFFSET-NEXT: ret ptr addrspace(200) [[RET]]
263+
;
264+
%ret = tail call ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200) null, i64 %value)
265+
ret ptr addrspace(200) %ret
266+
}
267+
268+
define ptr addrspace(200) @fold_set_on_null_with_gep(i64 %value, i64 %gepoff) nounwind {
269+
; ADDRESS-LABEL: define {{[^@]+}}@fold_set_on_null_with_gep
270+
; ADDRESS-SAME: (i64 [[VALUE:%.*]], i64 [[GEPOFF:%.*]]) addrspace(200) #[[ATTR0]] {
271+
; ADDRESS-NEXT: [[TMP:%.*]] = getelementptr i8, ptr addrspace(200) null, i64 [[GEPOFF]]
272+
; ADDRESS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.address.set.i64(ptr addrspace(200) [[TMP]], i64 [[VALUE]])
273+
; ADDRESS-NEXT: ret ptr addrspace(200) [[RET]]
274+
;
275+
; FLAGS-LABEL: define {{[^@]+}}@fold_set_on_null_with_gep
276+
; FLAGS-SAME: (i64 [[VALUE:%.*]], i64 [[GEPOFF:%.*]]) addrspace(200) #[[ATTR0]] {
277+
; FLAGS-NEXT: [[TMP:%.*]] = getelementptr i8, ptr addrspace(200) null, i64 [[GEPOFF]]
278+
; FLAGS-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.flags.set.i64(ptr addrspace(200) [[TMP]], i64 [[VALUE]])
279+
; FLAGS-NEXT: ret ptr addrspace(200) [[RET]]
280+
;
281+
; HIGH-LABEL: define {{[^@]+}}@fold_set_on_null_with_gep
282+
; HIGH-SAME: (i64 [[VALUE:%.*]], i64 [[GEPOFF:%.*]]) addrspace(200) #[[ATTR0]] {
283+
; HIGH-NEXT: [[TMP:%.*]] = getelementptr i8, ptr addrspace(200) null, i64 [[GEPOFF]]
284+
; HIGH-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.high.set.i64(ptr addrspace(200) [[TMP]], i64 [[VALUE]])
285+
; HIGH-NEXT: ret ptr addrspace(200) [[RET]]
286+
;
287+
; OFFSET-LABEL: define {{[^@]+}}@fold_set_on_null_with_gep
288+
; OFFSET-SAME: (i64 [[VALUE:%.*]], i64 [[GEPOFF:%.*]]) addrspace(200) #[[ATTR0]] {
289+
; OFFSET-NEXT: [[TMP:%.*]] = getelementptr i8, ptr addrspace(200) null, i64 [[GEPOFF]]
290+
; OFFSET-NEXT: [[RET:%.*]] = tail call ptr addrspace(200) @llvm.cheri.cap.offset.set.i64(ptr addrspace(200) [[TMP]], i64 [[VALUE]])
291+
; OFFSET-NEXT: ret ptr addrspace(200) [[RET]]
292+
;
293+
%tmp = getelementptr i8, ptr addrspace(200) null, i64 %gepoff
294+
%ret = tail call ptr addrspace(200) @llvm.cheri.cap.FIELD.set.i64(ptr addrspace(200) %tmp, i64 %value)
295+
ret ptr addrspace(200) %ret
296+
}

0 commit comments

Comments
 (0)