@@ -117,3 +117,179 @@ if.end:
117
117
%size = call i64 @llvm.objectsize.i64.p0 (ptr %p , i1 true , i1 true , i1 false )
118
118
ret i64 %size
119
119
}
120
+
121
+ define i64 @pick_negative_offset (i32 %n ) {
122
+ ; CHECK-LABEL: @pick_negative_offset(
123
+ ; CHECK-NEXT: entry:
124
+ ; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1
125
+ ; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20
126
+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
127
+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
128
+ ; CHECK: if.else:
129
+ ; CHECK-NEXT: [[BUFFER1:%.*]] = alloca i8, i64 20, align 1
130
+ ; CHECK-NEXT: [[OFFSETED1:%.*]] = getelementptr i8, ptr [[BUFFER1]], i64 20
131
+ ; CHECK-NEXT: br label [[IF_END]]
132
+ ; CHECK: if.end:
133
+ ; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED1]], [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY:%.*]] ]
134
+ ; CHECK-NEXT: [[POFFSETED:%.*]] = getelementptr i8, ptr [[P]], i64 -4
135
+ ; CHECK-NEXT: ret i64 4
136
+ ;
137
+ entry:
138
+ %buffer0 = alloca i8 , i64 20
139
+ %offseted0 = getelementptr i8 , ptr %buffer0 , i64 20
140
+ %cond = icmp eq i32 %n , 0
141
+ br i1 %cond , label %if.else , label %if.end
142
+
143
+ if.else:
144
+ %buffer1 = alloca i8 , i64 20
145
+ %offseted1 = getelementptr i8 , ptr %buffer1 , i64 20
146
+ br label %if.end
147
+
148
+ if.end:
149
+ %p = phi ptr [ %offseted1 , %if.else ], [ %offseted0 , %entry ]
150
+ %poffseted = getelementptr i8 , ptr %p , i64 -4
151
+ %size = call i64 @llvm.objectsize.i64.p0 (ptr %poffseted , i1 false , i1 false , i1 false )
152
+ ret i64 %size
153
+ }
154
+
155
+ define i64 @pick_negative_offset_with_nullptr (i32 %n ) {
156
+ ; CHECK-LABEL: @pick_negative_offset_with_nullptr(
157
+ ; CHECK-NEXT: entry:
158
+ ; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1
159
+ ; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20
160
+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
161
+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
162
+ ; CHECK: if.else:
163
+ ; CHECK-NEXT: br label [[IF_END]]
164
+ ; CHECK: if.end:
165
+ ; CHECK-NEXT: [[P0:%.*]] = phi ptr [ [[OFFSETED0]], [[ENTRY:%.*]] ], [ null, [[IF_ELSE]] ]
166
+ ; CHECK-NEXT: [[P1:%.*]] = phi ptr [ null, [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY]] ]
167
+ ; CHECK-NEXT: [[P0OFFSETED:%.*]] = getelementptr i8, ptr [[P0]], i64 -4
168
+ ; CHECK-NEXT: [[P1OFFSETED:%.*]] = getelementptr i8, ptr [[P1]], i64 -4
169
+ ; CHECK-NEXT: ret i64 4
170
+ ;
171
+ entry:
172
+ %buffer0 = alloca i8 , i64 20
173
+ %offseted0 = getelementptr i8 , ptr %buffer0 , i64 20
174
+ %cond = icmp eq i32 %n , 0
175
+ br i1 %cond , label %if.else , label %if.end
176
+
177
+ if.else:
178
+ br label %if.end
179
+
180
+ if.end:
181
+ %p0 = phi ptr [ %offseted0 , %entry ], [ null , %if.else ]
182
+ %p1 = phi ptr [ null , %if.else ], [ %offseted0 , %entry ]
183
+ %p0offseted = getelementptr i8 , ptr %p0 , i64 -4
184
+ %p1offseted = getelementptr i8 , ptr %p1 , i64 -4
185
+ %size0 = call i64 @llvm.objectsize.i64.p0 (ptr %p0offseted , i1 false , i1 false , i1 false )
186
+ %size1 = call i64 @llvm.objectsize.i64.p0 (ptr %p1offseted , i1 false , i1 false , i1 false )
187
+ %size = select i1 %cond , i64 %size0 , i64 %size1
188
+ ret i64 %size
189
+ }
190
+
191
+ define i64 @pick_negative_offset_with_unsized_nullptr (i32 %n ) {
192
+ ; CHECK-LABEL: @pick_negative_offset_with_unsized_nullptr(
193
+ ; CHECK-NEXT: entry:
194
+ ; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1
195
+ ; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20
196
+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
197
+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
198
+ ; CHECK: if.else:
199
+ ; CHECK-NEXT: br label [[IF_END]]
200
+ ; CHECK: if.end:
201
+ ; CHECK-NEXT: [[P0:%.*]] = phi ptr [ [[OFFSETED0]], [[ENTRY:%.*]] ], [ null, [[IF_ELSE]] ]
202
+ ; CHECK-NEXT: [[P1:%.*]] = phi ptr [ null, [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY]] ]
203
+ ; CHECK-NEXT: [[P0OFFSETED:%.*]] = getelementptr i8, ptr [[P0]], i64 -4
204
+ ; CHECK-NEXT: [[P1OFFSETED:%.*]] = getelementptr i8, ptr [[P1]], i64 -4
205
+ ; CHECK-NEXT: ret i64 -1
206
+ ;
207
+ entry:
208
+ %buffer0 = alloca i8 , i64 20
209
+ %offseted0 = getelementptr i8 , ptr %buffer0 , i64 20
210
+ %cond = icmp eq i32 %n , 0
211
+ br i1 %cond , label %if.else , label %if.end
212
+
213
+ if.else:
214
+ br label %if.end
215
+
216
+ if.end:
217
+ %p0 = phi ptr [ %offseted0 , %entry ], [ null , %if.else ]
218
+ %p1 = phi ptr [ null , %if.else ], [ %offseted0 , %entry ]
219
+ %p0offseted = getelementptr i8 , ptr %p0 , i64 -4
220
+ %p1offseted = getelementptr i8 , ptr %p1 , i64 -4
221
+ %size0 = call i64 @llvm.objectsize.i64.p0 (ptr %p0offseted , i1 false , i1 true , i1 false )
222
+ %size1 = call i64 @llvm.objectsize.i64.p0 (ptr %p1offseted , i1 false , i1 true , i1 false )
223
+ %size = select i1 %cond , i64 %size0 , i64 %size1
224
+ ret i64 %size
225
+ }
226
+
227
+ define i64 @chain_pick_negative_offset_with_nullptr (i32 %x ) {
228
+ ; CHECK-LABEL: @chain_pick_negative_offset_with_nullptr(
229
+ ; CHECK-NEXT: entry:
230
+ ; CHECK-NEXT: [[ARRAY:%.*]] = alloca [4 x i32], align 4
231
+ ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
232
+ ; CHECK-NEXT: [[P:%.*]] = getelementptr i8, ptr [[ARRAY]], i64 8
233
+ ; CHECK-NEXT: [[COND:%.*]] = select i1 [[C]], ptr [[P]], ptr null
234
+ ; CHECK-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[COND]], i64 8
235
+ ; CHECK-NEXT: [[COND6:%.*]] = select i1 [[C]], ptr [[P4]], ptr null
236
+ ; CHECK-NEXT: [[P7:%.*]] = getelementptr i8, ptr [[COND6]], i64 -4
237
+ ; CHECK-NEXT: ret i64 4
238
+ ;
239
+ entry:
240
+ %array = alloca [4 x i32 ]
241
+ %c = icmp eq i32 %x , 0
242
+ %p = getelementptr i8 , ptr %array , i64 8
243
+ %cond = select i1 %c , ptr %p , ptr null
244
+ %p4 = getelementptr i8 , ptr %cond , i64 8
245
+ %cond6 = select i1 %c , ptr %p4 , ptr null
246
+ %p7 = getelementptr i8 , ptr %cond6 , i64 -4
247
+ %size = call i64 @llvm.objectsize.i64.p0 (ptr %p7 , i1 false , i1 false , i1 false )
248
+ ret i64 %size
249
+ }
250
+
251
+
252
+ define i64 @negative_offset_dynamic_eval (i32 %x , i64 %i ) {
253
+ ; CHECK-LABEL: @negative_offset_dynamic_eval(
254
+ ; CHECK-NEXT: entry:
255
+ ; CHECK-NEXT: [[ARRAY1:%.*]] = alloca [4 x i32], align 16
256
+ ; CHECK-NEXT: [[ARRAY2:%.*]] = alloca [8 x i32], align 16
257
+ ; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0
258
+ ; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
259
+ ; CHECK: if.then:
260
+ ; CHECK-NEXT: br label [[IF_END:%.*]]
261
+ ; CHECK: if.else:
262
+ ; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[ARRAY2]], i64 16
263
+ ; CHECK-NEXT: br label [[IF_END]]
264
+ ; CHECK: if.end:
265
+ ; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[ARRAY1]], [[IF_THEN]] ], [ [[ADD_PTR]], [[IF_ELSE]] ]
266
+ ; CHECK-NEXT: [[ADD_PTR2_IDX:%.*]] = mul i64 [[I:%.*]], 4
267
+ ; CHECK-NEXT: [[TMP0:%.*]] = add i64 16, [[ADD_PTR2_IDX]]
268
+ ; CHECK-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I]]
269
+ ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 32, [[TMP0]]
270
+ ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 32, [[TMP0]]
271
+ ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 0, i64 [[TMP1]]
272
+ ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i64 [[TMP3]], -1
273
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP4]])
274
+ ; CHECK-NEXT: ret i64 [[TMP3]]
275
+ ;
276
+ entry:
277
+ %array1 = alloca [4 x i32 ], align 16
278
+ %array2 = alloca [8 x i32 ], align 16
279
+ %tobool.not = icmp eq i32 %x , 0
280
+ br i1 %tobool.not , label %if.else , label %if.then
281
+
282
+ if.then:
283
+ br label %if.end
284
+
285
+ if.else:
286
+ %add.ptr = getelementptr inbounds i8 , ptr %array2 , i64 16
287
+ br label %if.end
288
+
289
+ if.end:
290
+ %ptr = phi ptr [ %array1 , %if.then ], [ %add.ptr , %if.else ]
291
+ %add.ptr2 = getelementptr inbounds i32 , ptr %ptr , i64 %i
292
+ %objsize = call i64 @llvm.objectsize.i64.p0 (ptr %add.ptr2 , i1 false , i1 true , i1 true )
293
+ ret i64 %objsize
294
+ }
295
+
0 commit comments