Skip to content

Commit 0f235c3

Browse files
authored
[LowerConstantIntrinsics] Improve tests related to llvm.objectsize. NFC (#132364)
Adding some new test cases (including FIXME:s) to highlight some bugs related to lowering of llvm.objectsize. One special case is when there are getelementptr instruction with index types that are larger than the index type size for the pointer being analysed. This will add a couple of tests to show what happens both when using a smaller and larger index type, and when having out-of-bounds indices (both too large and negative).
1 parent aeea056 commit 0f235c3

File tree

2 files changed

+315
-4
lines changed

2 files changed

+315
-4
lines changed
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -passes=lower-constant-intrinsics -S < %s | FileCheck %s
3+
4+
; Some extra tests using 16-bit pointers and 16-bit index type size. This
5+
; allows us to for example test what happens when the index type used in a
6+
; getelementptr does not match with the index type size (e.g. when not running
7+
; full opt pipeline before the lower-constant-intrinsics pass).
8+
9+
target datalayout = "e-p:16:16:16"
10+
11+
12+
define i32 @possible_out_of_bounds_gep_i8(i1 %c0, i1 %c1) {
13+
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i8(
14+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
15+
; CHECK-NEXT: [[ENTRY:.*:]]
16+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
17+
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i8 2, i8 10
18+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i8 [[OFFSET]]
19+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
20+
; CHECK-NEXT: ret i32 [[RES]]
21+
;
22+
entry:
23+
%obj = alloca [5 x i8]
24+
%offset = select i1 %c0, i8 2, i8 10
25+
%ptr.slide = getelementptr i8, ptr %obj, i8 %offset
26+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
27+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
28+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
29+
ret i32 %res
30+
}
31+
32+
define i32 @possible_out_of_bounds_gep_i16(i1 %c0, i1 %c1) {
33+
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i16(
34+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
35+
; CHECK-NEXT: [[ENTRY:.*:]]
36+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
37+
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i16 2, i16 10
38+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i16 [[OFFSET]]
39+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
40+
; CHECK-NEXT: ret i32 [[RES]]
41+
;
42+
entry:
43+
%obj = alloca [5 x i8]
44+
%offset = select i1 %c0, i16 2, i16 10
45+
%ptr.slide = getelementptr i8, ptr %obj, i16 %offset
46+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
47+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
48+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
49+
ret i32 %res
50+
}
51+
52+
define i32 @possible_out_of_bounds_gep_i32(i1 %c0, i1 %c1) {
53+
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i32(
54+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
55+
; CHECK-NEXT: [[ENTRY:.*:]]
56+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
57+
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i32 2, i32 10
58+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 [[OFFSET]]
59+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 0
60+
; CHECK-NEXT: ret i32 [[RES]]
61+
;
62+
entry:
63+
%obj = alloca [5 x i8]
64+
%offset = select i1 %c0, i32 2, i32 10
65+
%ptr.slide = getelementptr i8, ptr %obj, i32 %offset
66+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
67+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
68+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
69+
ret i32 %res
70+
}
71+
72+
; SROA would produce IR like this if applied to @possible_out_of_bounds_gep_i16.
73+
; FIXME: The %objsize_min result here is invalid.
74+
define i32 @possible_out_of_bounds_gep_i16_sroa(i1 %c0, i1 %c1) {
75+
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i16_sroa(
76+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
77+
; CHECK-NEXT: [[ENTRY:.*:]]
78+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
79+
; CHECK-NEXT: [[DOTSROA_GEP:%.*]] = getelementptr i8, ptr [[OBJ]], i16 2
80+
; CHECK-NEXT: [[DOTSROA_GEP1:%.*]] = getelementptr i8, ptr [[OBJ]], i16 10
81+
; CHECK-NEXT: [[OFFSET_SROA_SEL:%.*]] = select i1 [[C0]], ptr [[DOTSROA_GEP]], ptr [[DOTSROA_GEP1]]
82+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 3, i32 65531
83+
; CHECK-NEXT: ret i32 [[RES]]
84+
;
85+
entry:
86+
%obj = alloca [5 x i8], align 1
87+
%.sroa.gep = getelementptr i8, ptr %obj, i16 2
88+
%.sroa.gep1 = getelementptr i8, ptr %obj, i16 10
89+
%offset.sroa.sel = select i1 %c0, ptr %.sroa.gep, ptr %.sroa.gep1
90+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %offset.sroa.sel, i1 false, i1 true, i1 false)
91+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %offset.sroa.sel, i1 true, i1 true, i1 false)
92+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
93+
ret i32 %res
94+
}
95+
96+
; Indices are truncated to the pointer size in a gep. So "i32 -65526" should
97+
; be treated as "i16 10" and we expect same result as for
98+
; @possible_out_of_bounds_gep_i16 above.
99+
; FIXME: The result here is incorrect (max/min is swapped).
100+
define i32 @possible_out_of_bounds_gep_i32_trunc(i1 %c0, i1 %c1) {
101+
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i32_trunc(
102+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
103+
; CHECK-NEXT: [[ENTRY:.*:]]
104+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
105+
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i32 2, i32 -65526
106+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 [[OFFSET]]
107+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 0, i32 3
108+
; CHECK-NEXT: ret i32 [[RES]]
109+
;
110+
entry:
111+
%obj = alloca [5 x i8]
112+
%offset = select i1 %c0, i32 2, i32 -65526 ; 0xffff000a
113+
%ptr.slide = getelementptr i8, ptr %obj, i32 %offset
114+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
115+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
116+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
117+
ret i32 %res
118+
}
119+
120+
define i32 @out_of_bounds_gep_i8(i1 %c0, i1 %c1) {
121+
; CHECK-LABEL: define i32 @out_of_bounds_gep_i8(
122+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
123+
; CHECK-NEXT: [[ENTRY:.*:]]
124+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
125+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i8 -128
126+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 0
127+
; CHECK-NEXT: ret i32 [[RES]]
128+
;
129+
entry:
130+
%obj = alloca [5 x i8]
131+
%ptr.slide = getelementptr i8, ptr %obj, i8 -128
132+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
133+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
134+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
135+
ret i32 %res
136+
}
137+
138+
define i32 @out_of_bounds_gep_i32(i1 %c0, i1 %c1) {
139+
; CHECK-LABEL: define i32 @out_of_bounds_gep_i32(
140+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
141+
; CHECK-NEXT: [[ENTRY:.*:]]
142+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
143+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 10
144+
; CHECK-NEXT: ret i32 0
145+
;
146+
entry:
147+
%obj = alloca [5 x i8]
148+
%ptr.slide = getelementptr i8, ptr %obj, i32 10
149+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
150+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
151+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
152+
ret i32 %res
153+
}
154+
155+
define i32 @out_of_bounds_gep_i32_trunc(i1 %c0, i1 %c1) {
156+
; CHECK-LABEL: define i32 @out_of_bounds_gep_i32_trunc(
157+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
158+
; CHECK-NEXT: [[ENTRY:.*:]]
159+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
160+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 -65526
161+
; CHECK-NEXT: ret i32 0
162+
;
163+
entry:
164+
%obj = alloca [5 x i8]
165+
%ptr.slide = getelementptr i8, ptr %obj, i32 -65526
166+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
167+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
168+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
169+
ret i32 %res
170+
}
171+
172+
; In this test the index will be out-of-bounds, but the current analysis won't
173+
; detect that. The analysis will find out that %offset is in the range [-2,
174+
; 10] which includes valid offsets that aren't out-of-bounds. Therefore we can
175+
; expect to get -1 for %objsize_max even if an advanced analysis should be
176+
; able to derive that we are out-of-bounds (returning 0 also for
177+
; %objsize_max).
178+
define i32 @out_of_bounds_gep_i16_pos_neg(i1 %c0, i1 %c1) {
179+
; CHECK-LABEL: define i32 @out_of_bounds_gep_i16_pos_neg(
180+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
181+
; CHECK-NEXT: [[ENTRY:.*:]]
182+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
183+
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i32 10, i32 -2
184+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 [[OFFSET]]
185+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 0
186+
; CHECK-NEXT: ret i32 [[RES]]
187+
;
188+
entry:
189+
%obj = alloca [5 x i8]
190+
%offset = select i1 %c0, i32 10, i32 -2
191+
%ptr.slide = getelementptr i8, ptr %obj, i32 %offset
192+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
193+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
194+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
195+
ret i32 %res
196+
}
197+
198+
; With 16-bit index size %offset is either 32767 or -32768. Thus, when
199+
; aggregating the possible offsets it we know that it is in the range [-32768,
200+
; 32767], which includes valid offsets that aren't out-of-bounds. This is
201+
; similar to the out_of_bounds_gep_i16_pos_neg test above, and the current
202+
; implementation is expected to derive the result -1 for %objsize_max.
203+
define i32 @out_of_bounds_gep_i32_trunc_select(i1 %c0, i1 %c1) {
204+
; CHECK-LABEL: define i32 @out_of_bounds_gep_i32_trunc_select(
205+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
206+
; CHECK-NEXT: [[ENTRY:.*:]]
207+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
208+
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i32 32767, i32 32768
209+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i32 [[OFFSET]]
210+
; CHECK-NEXT: ret i32 0
211+
;
212+
entry:
213+
%obj = alloca [5 x i8]
214+
%offset = select i1 %c0, i32 32767, i32 32768
215+
%ptr.slide = getelementptr i8, ptr %obj, i32 %offset
216+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
217+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
218+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
219+
ret i32 %res
220+
}
221+
222+
; FIXME: Is 3 really correct for %objsize_min here?
223+
define i32 @possible_out_of_bounds_gep_i8_neg(i1 %c0, i1 %c1) {
224+
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i8_neg(
225+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
226+
; CHECK-NEXT: [[ENTRY:.*:]]
227+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
228+
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i8 2, i8 -10
229+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i8 [[OFFSET]]
230+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 3
231+
; CHECK-NEXT: ret i32 [[RES]]
232+
;
233+
entry:
234+
%obj = alloca [5 x i8]
235+
%offset = select i1 %c0, i8 2, i8 -10
236+
%ptr.slide = getelementptr i8, ptr %obj, i8 %offset
237+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
238+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
239+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
240+
ret i32 %res
241+
}
242+
243+
; FIXME: Is 3 really correct for %objsize_min here?
244+
define i32 @possible_out_of_bounds_gep_i16_neg(i1 %c0, i1 %c1) {
245+
; CHECK-LABEL: define i32 @possible_out_of_bounds_gep_i16_neg(
246+
; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) {
247+
; CHECK-NEXT: [[ENTRY:.*:]]
248+
; CHECK-NEXT: [[OBJ:%.*]] = alloca [5 x i8], align 1
249+
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0]], i16 2, i16 -10
250+
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i16 [[OFFSET]]
251+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i32 -1, i32 3
252+
; CHECK-NEXT: ret i32 [[RES]]
253+
;
254+
entry:
255+
%obj = alloca [5 x i8]
256+
%offset = select i1 %c0, i16 2, i16 -10
257+
%ptr.slide = getelementptr i8, ptr %obj, i16 %offset
258+
%objsize_max = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
259+
%objsize_min = call i32 @llvm.objectsize.i32.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
260+
%res = select i1 %c1, i32 %objsize_max, i32 %objsize_min
261+
ret i32 %res
262+
}

llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-phi.ll

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,12 @@ if.end:
200200
ret i64 %size
201201
}
202202

203-
define i64 @pick_negative_offset_different_width(i32 %n) {
204-
; CHECK-LABEL: @pick_negative_offset_different_width(
203+
; FIXME: The result here looks weird. Either we reference into buffer0 with an
204+
; oob offset. Or we reference buffer1 (8 bytes) with a 4 byte
205+
; offset. The result 5 is wrong in both cases. Probably better to
206+
; return -1 here since we do not know if we have an oob pointer.
207+
define i64 @pick_negative_offset_different_width_index_maybe_too_small(i32 %n, i1 %c) {
208+
; CHECK-LABEL: @pick_negative_offset_different_width_index_maybe_too_small(
205209
; CHECK-NEXT: entry:
206210
; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 4, align 1
207211
; CHECK-NEXT: [[BUFFER1:%.*]] = alloca i8, i64 8, align 1
@@ -216,7 +220,8 @@ define i64 @pick_negative_offset_different_width(i32 %n) {
216220
; CHECK: if.end:
217221
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED0]], [[IF_ELSE]] ], [ [[OFFSETED1]], [[IF_END]] ]
218222
; CHECK-NEXT: [[POFFSETED:%.*]] = getelementptr i8, ptr [[P]], i64 -2
219-
; CHECK-NEXT: ret i64 5
223+
; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 5, i64 0
224+
; CHECK-NEXT: ret i64 [[SIZE]]
220225
;
221226
entry:
222227
%buffer0 = alloca i8, i64 4
@@ -235,7 +240,51 @@ if.else:
235240
if.end:
236241
%p = phi ptr [ %offseted0, %if.then ], [ %offseted1, %if.else ]
237242
%poffseted = getelementptr i8, ptr %p, i64 -2
238-
%size = call i64 @llvm.objectsize.i64.p0(ptr %poffseted, i1 false, i1 false, i1 false)
243+
%sizemax = call i64 @llvm.objectsize.i64.p0(ptr %poffseted, i1 false, i1 false, i1 false)
244+
%sizemin = call i64 @llvm.objectsize.i64.p0(ptr %poffseted, i1 true, i1 false, i1 false)
245+
%size = select i1 %c, i64 %sizemax, i64 %sizemin
246+
ret i64 %size
247+
}
248+
249+
define i64 @pick_negative_offset_different_width_index_maybe_too_large(i32 %n, i1 %c) {
250+
; CHECK-LABEL: @pick_negative_offset_different_width_index_maybe_too_large(
251+
; CHECK-NEXT: entry:
252+
; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 4, align 1
253+
; CHECK-NEXT: [[BUFFER1:%.*]] = alloca i8, i64 8, align 1
254+
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
255+
; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
256+
; CHECK: if.then:
257+
; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 1
258+
; CHECK-NEXT: br label [[IF_END:%.*]]
259+
; CHECK: if.else:
260+
; CHECK-NEXT: [[OFFSETED1:%.*]] = getelementptr i8, ptr [[BUFFER1]], i64 6
261+
; CHECK-NEXT: br label [[IF_END]]
262+
; CHECK: if.end:
263+
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED0]], [[IF_THEN]] ], [ [[OFFSETED1]], [[IF_ELSE]] ]
264+
; CHECK-NEXT: [[POFFSETED:%.*]] = getelementptr i8, ptr [[P]], i64 2
265+
; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 1, i64 0
266+
; CHECK-NEXT: ret i64 [[SIZE]]
267+
;
268+
entry:
269+
%buffer0 = alloca i8, i64 4
270+
%buffer1 = alloca i8, i64 8
271+
%cond = icmp eq i32 %n, 0
272+
br i1 %cond, label %if.then, label %if.else
273+
274+
if.then:
275+
%offseted0 = getelementptr i8, ptr %buffer0, i64 1
276+
br label %if.end
277+
278+
if.else:
279+
%offseted1 = getelementptr i8, ptr %buffer1, i64 6
280+
br label %if.end
281+
282+
if.end:
283+
%p = phi ptr [ %offseted0, %if.then ], [ %offseted1, %if.else ]
284+
%poffseted = getelementptr i8, ptr %p, i64 2
285+
%sizemax = call i64 @llvm.objectsize.i64.p0(ptr %poffseted, i1 false, i1 false, i1 false)
286+
%sizemin = call i64 @llvm.objectsize.i64.p0(ptr %poffseted, i1 true, i1 false, i1 false)
287+
%size = select i1 %c, i64 %sizemax, i64 %sizemin
239288
ret i64 %size
240289
}
241290

0 commit comments

Comments
 (0)