llvm.org GIT mirror llvm / 23e75da
revert my previous patches that introduced an additional parameter to the objectsize intrinsic. After a lot of discussion, we realized it's not the best option for run-time bounds checking git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157255 91177308-0d34-0410-b5e6-96231b3b80d8 Nuno Lopes 8 years ago
15 changed file(s) with 109 addition(s) and 280 deletion(s). Raw diff Collapse all Expand all
84668466
84678467
Syntax:
84688468

                  
                
8469 declare i32 @llvm.objectsize.i32(i8* <object>, i1 <min>, i32 <runtime>)
8470 declare i64 @llvm.objectsize.i64(i8* <object>, i1 <min>, i32 <runtime>)
8469 declare i32 @llvm.objectsize.i32(i8* <object>, i1 <min>)
8470 declare i64 @llvm.objectsize.i64(i8* <object>, i1 <min>)
84718471
84728472
84738473
Overview:
84788478 an allocation of a specific class, structure, array, or other object.

84798479
84808480
Arguments:
8481

The llvm.objectsize intrinsic takes three arguments. The first

8481

The llvm.objectsize intrinsic takes two arguments. The first

84828482 argument is a pointer to or into the object. The second argument
8483 is a boolean and determines whether llvm.objectsize returns 0 (if true)
8484 or -1 (if false) when the object size is unknown.
8485 The third argument, runtime, indicates whether the compiler is allowed
8486 to return a non-constant value. The higher the value, the higher the potential
8487 run-time performance impact.
8488 The second and third arguments only accepts constants.

8483 is a boolean and determines whether llvm.objectsize returns 0 (if
8484 true) or -1 (if false) when the object size is unknown.
8485 The second argument only accepts constants.

84898486
84908487
Semantics:
84918488

The llvm.objectsize intrinsic is lowered to a constant representing

84928489 the size of the object concerned. If the size cannot be determined at compile
8493 time, llvm.objectsize either returns i32/i64 -1 or 0
8494 (depending on the min argument) if runtime is 0, or a run-time
8495 value (if runtime > 0 and an expression could be generated).>
8490 time, llvm.objectsize returns i32/i64 -1 or 0>
8491 (depending on the min argument).

84968492
84978493
84988494
271271 def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>;
272272
273273 // Internal interface for object size checking
274 def int_objectsize : Intrinsic<[llvm_anyint_ty],
275 [llvm_ptr_ty, llvm_i1_ty, llvm_i32_ty],
274 def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i1_ty],
276275 [IntrNoMem]>,
277276 GCCBuiltin<"__builtin_object_size">;
278277
164164 return 0;
165165 }
166166
167 /// computeAllocSize - compute the object size allocated by an allocation
168 /// site. Returns 0 if the size is not constant (in SizeValue), 1 if the size
169 /// is constant (in Size), and 2 if the size could not be determined within the
170 /// given maximum Penalty that the computation would incurr at run-time.
171 static int computeAllocSize(Value *Alloc, uint64_t &Size, Value* &SizeValue,
172 uint64_t Penalty, TargetData *TD,
173 InstCombiner::BuilderTy *Builder) {
174 if (GlobalVariable *GV = dyn_cast(Alloc)) {
175 if (GV->hasDefinitiveInitializer()) {
176 Constant *C = GV->getInitializer();
177 Size = TD->getTypeAllocSize(C->getType());
178 return 1;
179 }
180 // Can't determine size of the GV.
181 return 2;
182
183 } else if (AllocaInst *AI = dyn_cast(Alloc)) {
184 if (!AI->getAllocatedType()->isSized())
185 return 2;
186
187 Size = TD->getTypeAllocSize(AI->getAllocatedType());
188 if (!AI->isArrayAllocation())
189 return 1; // we are done
190
191 Value *ArraySize = AI->getArraySize();
192 if (const ConstantInt *C = dyn_cast(ArraySize)) {
193 Size *= C->getZExtValue();
194 return 1;
195 }
196
197 if (Penalty < 2)
198 return 2;
199
200 SizeValue = ConstantInt::get(ArraySize->getType(), Size);
201 SizeValue = Builder->CreateMul(SizeValue, ArraySize);
202 return 0;
203
204 } else if (CallInst *MI = extractMallocCall(Alloc)) {
205 SizeValue = MI->getArgOperand(0);
206 if (ConstantInt *CI = dyn_cast(SizeValue)) {
207 Size = CI->getZExtValue();
208 return 1;
209 }
210 return Penalty >= 2 ? 0 : 2;
211
212 } else if (CallInst *MI = extractCallocCall(Alloc)) {
213 Value *Arg1 = MI->getArgOperand(0);
214 Value *Arg2 = MI->getArgOperand(1);
215 if (ConstantInt *CI1 = dyn_cast(Arg1)) {
216 if (ConstantInt *CI2 = dyn_cast(Arg2)) {
217 Size = (CI1->getValue() * CI2->getValue()).getZExtValue();
218 return 1;
219 }
220 }
221
222 if (Penalty < 2)
223 return 2;
224
225 SizeValue = Builder->CreateMul(Arg1, Arg2);
226 return 0;
227 }
228
229 DEBUG(errs() << "computeAllocSize failed:\n");
230 DEBUG(Alloc->dump());
231 return 2;
232 }
233
234167 /// visitCallInst - CallInst simplification. This mostly only handles folding
235168 /// of intrinsic instructions. For normal calls, it allows visitCallSite to do
236169 /// the heavy lifting.
316249 if (!TD) return 0;
317250
318251 Type *ReturnTy = CI.getType();
319 uint64_t Penalty = cast(II->getArgOperand(2))->getZExtValue();
252 uint64_t DontKnow = II->getArgOperand(1) == Builder->getTrue() ? 0 : -1ULL;
320253
321254 // Get to the real allocated thing and offset as fast as possible.
322255 Value *Op1 = II->getArgOperand(0)->stripPointerCasts();
323 GEPOperator *GEP;
324
325 if ((GEP = dyn_cast(Op1))) {
326 // check if we will be able to get the offset
327 if (!GEP->hasAllConstantIndices() && Penalty < 2)
256
257 uint64_t Offset = 0;
258 uint64_t Size = -1ULL;
259
260 // Try to look through constant GEPs.
261 if (GEPOperator *GEP = dyn_cast(Op1)) {
262 if (!GEP->hasAllConstantIndices()) return 0;
263
264 // Get the current byte offset into the thing. Use the original
265 // operand in case we're looking through a bitcast.
266 SmallVector Ops(GEP->idx_begin(), GEP->idx_end());
267 if (!GEP->getPointerOperandType()->isPointerTy())
328268 return 0;
269 Offset = TD->getIndexedOffset(GEP->getPointerOperandType(), Ops);
270
329271 Op1 = GEP->getPointerOperand()->stripPointerCasts();
330 }
331
332 uint64_t Size;
333 Value *SizeValue;
334 int ConstAlloc = computeAllocSize(Op1, Size, SizeValue, Penalty, TD,
335 Builder);
272
273 // Make sure we're not a constant offset from an external
274 // global.
275 if (GlobalVariable *GV = dyn_cast(Op1))
276 if (!GV->hasDefinitiveInitializer()) return 0;
277 }
278
279 // If we've stripped down to a single global variable that we
280 // can know the size of then just return that.
281 if (GlobalVariable *GV = dyn_cast(Op1)) {
282 if (GV->hasDefinitiveInitializer()) {
283 Constant *C = GV->getInitializer();
284 Size = TD->getTypeAllocSize(C->getType());
285 } else {
286 // Can't determine size of the GV.
287 Constant *RetVal = ConstantInt::get(ReturnTy, DontKnow);
288 return ReplaceInstUsesWith(CI, RetVal);
289 }
290 } else if (AllocaInst *AI = dyn_cast(Op1)) {
291 // Get alloca size.
292 if (AI->getAllocatedType()->isSized()) {
293 Size = TD->getTypeAllocSize(AI->getAllocatedType());
294 if (AI->isArrayAllocation()) {
295 const ConstantInt *C = dyn_cast(AI->getArraySize());
296 if (!C) return 0;
297 Size *= C->getZExtValue();
298 }
299 }
300 } else if (CallInst *MI = extractMallocCall(Op1)) {
301 // Get allocation size.
302 Value *Arg = MI->getArgOperand(0);
303 if (ConstantInt *CI = dyn_cast(Arg))
304 Size = CI->getZExtValue();
305
306 } else if (CallInst *MI = extractCallocCall(Op1)) {
307 // Get allocation size.
308 Value *Arg1 = MI->getArgOperand(0);
309 Value *Arg2 = MI->getArgOperand(1);
310 if (ConstantInt *CI1 = dyn_cast(Arg1))
311 if (ConstantInt *CI2 = dyn_cast(Arg2))
312 Size = (CI1->getValue() * CI2->getValue()).getZExtValue();
313 }
336314
337315 // Do not return "I don't know" here. Later optimization passes could
338316 // make it possible to evaluate objectsize to a constant.
339 if (ConstAlloc == 2)
317 if (Size == -1ULL)
340318 return 0;
341319
342 uint64_t Offset = 0;
343 Value *OffsetValue = 0;
344
345 if (GEP) {
346 if (GEP->hasAllConstantIndices()) {
347 SmallVector Ops(GEP->idx_begin(), GEP->idx_end());
348 assert(GEP->getPointerOperandType()->isPointerTy());
349 Offset = TD->getIndexedOffset(GEP->getPointerOperandType(), Ops);
350 } else
351 OffsetValue = EmitGEPOffset(GEP, true /*NoNUW*/);
352 }
353
354 if (!OffsetValue && ConstAlloc) {
355 if (Size < Offset) {
356 // Out of bounds
357 return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, 0));
358 }
359 return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, Size-Offset));
360 }
361
362 if (!OffsetValue)
363 OffsetValue = ConstantInt::get(ReturnTy, Offset);
364 if (ConstAlloc)
365 SizeValue = ConstantInt::get(ReturnTy, Size);
366
367 Value *Val = Builder->CreateSub(SizeValue, OffsetValue);
368 // return 0 if there's an overflow
369 Value *Cmp = Builder->CreateICmpULT(SizeValue, OffsetValue);
370 Val = Builder->CreateSelect(Cmp, ConstantInt::get(ReturnTy, 0), Val);
371 return ReplaceInstUsesWith(CI, Val);
320 if (Size < Offset) {
321 // Out of bound reference? Negative index normalized to large
322 // index? Just return "I don't know".
323 return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, DontKnow));
324 }
325 return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, Size-Offset));
372326 }
373327 case Intrinsic::bswap:
374328 // bswap(bswap(x)) -> x
4747 F->setName(Name + ".old");
4848 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
4949 F->arg_begin()->getType());
50 return true;
51 }
52 break;
53 }
54 case 'o': {
55 // FIXME: remove in LLVM 3.3
56 if (Name.startswith("objectsize.") && F->arg_size() == 2) {
57 Type *Tys[] = {F->getReturnType(),
58 F->arg_begin()->getType(),
59 Type::getInt1Ty(F->getContext()),
60 Type::getInt32Ty(F->getContext())};
61 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::objectsize,
62 Tys);
63 NewFn->takeName(F);
6450 return true;
6551 }
6652 break;
208194 llvm_unreachable("Unknown function for CallInst upgrade.");
209195
210196 case Intrinsic::ctlz:
211 case Intrinsic::cttz: {
197 case Intrinsic::cttz:
212198 assert(CI->getNumArgOperands() == 1 &&
213199 "Mismatch between function args and call args");
214200 StringRef Name = CI->getName();
217203 Builder.getFalse(), Name));
218204 CI->eraseFromParent();
219205 return;
220 }
221 case Intrinsic::objectsize: {
222 StringRef Name = CI->getName();
223 CI->setName(Name + ".old");
224 CI->replaceAllUsesWith(Builder.CreateCall3(NewFn, CI->getArgOperand(0),
225 CI->getArgOperand(1),
226 Builder.getInt32(0), Name));
227 CI->eraseFromParent();
228 return;
229 }
230206 }
231207 }
232208
4242 %3 = load i32* @tabsize, align 4
4343 %4 = srem i32 %cols, %3
4444 %5 = sdiv i32 %cols, %3
45 %6 = tail call i32 @llvm.objectsize.i32(i8* null, i1 false, i32 0)
45 %6 = tail call i32 @llvm.objectsize.i32(i8* null, i1 false)
4646 %7 = tail call i8* @__memset_chk(i8* null, i32 9, i32 %5, i32 %6) nounwind
4747 br label %bb1
4848
5353 ret void
5454 }
5555
56 declare i32 @llvm.objectsize.i32(i8*, i1, i32) nounwind readnone
56 declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readnone
5757 declare i8* @__memset_chk(i8*, i32, i32, i32) nounwind
2222 %3 = load double* %1, align 4
2323 %4 = load double* %0, align 4
2424 call void @Parse_Vector(double* %0) nounwind
25 %5 = call i32 @llvm.objectsize.i32(i8* undef, i1 false, i32 0)
25 %5 = call i32 @llvm.objectsize.i32(i8* undef, i1 false)
2626 %6 = icmp eq i32 %5, -1
2727 br i1 %6, label %bb34, label %bb33
2828
3535 }
3636
3737 declare void @Parse_Vector(double*)
38 declare i32 @llvm.objectsize.i32(i8*, i1, i32)
38 declare i32 @llvm.objectsize.i32(i8*, i1)
3939
4040
4141 ; PR9578
+0
-16
test/CodeGen/Generic/objectsize-upgrade.ll less more
None ; RUN: opt < %s -verify -S | FileCheck %s
1 ; check automatic upgrade of objectsize. To be removed in LLVM 3.3.
2
3 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
4
5 define i32 @foo() nounwind {
6 ; CHECK: @foo
7 %1 = alloca i8, align 4
8 %2 = getelementptr inbounds i8* %1, i32 0
9 ; CHECK: llvm.objectsize.i32(i8* %2, i1 false, i32 0)
10 %3 = call i32 @llvm.objectsize.i32(i8* %2, i1 0)
11 ret i32 %3
12 }
13
14 ; CHECK: @llvm.objectsize.i32(i8*, i1, i32)
15 declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
77
88 @aux_temp = external global %struct.dfa, align 8
99
10 declare i64 @llvm.objectsize.i64(i8*, i1, i32) nounwind readnone
10 declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone
1111
1212 declare void @__memset_chk() nounwind
1313
2020 br i1 undef, label %land.end.thread.i, label %land.end.i
2121
2222 land.end.thread.i: ; preds = %if.end.i
23 %0 = call i64 @llvm.objectsize.i64(i8* undef, i1 false, i32 0) nounwind
23 %0 = call i64 @llvm.objectsize.i64(i8* undef, i1 false) nounwind
2424 %cmp1710.i = icmp eq i64 %0, -1
2525 br i1 %cmp1710.i, label %cond.false156.i, label %cond.true138.i
2626
2727 land.end.i: ; preds = %if.end.i
28 %1 = call i64 @llvm.objectsize.i64(i8* undef, i1 false, i32 0) nounwind
28 %1 = call i64 @llvm.objectsize.i64(i8* undef, i1 false) nounwind
2929 %cmp17.i = icmp eq i64 %1, -1
3030 br i1 %cmp17.i, label %cond.false156.i, label %cond.true138.i
3131
202202 ;
203203 define fastcc void @func_61() nounwind sspreq {
204204 entry:
205 %t1 = tail call i64 @llvm.objectsize.i64(i8* undef, i1 false, i32 0)
205 %t1 = tail call i64 @llvm.objectsize.i64(i8* undef, i1 false)
206206 %t2 = icmp eq i64 %t1, -1
207207 br i1 %t2, label %bb2, label %bb1
208208
213213 ret void
214214 }
215215
216 declare i64 @llvm.objectsize.i64(i8*, i1, i32) nounwind readnone
216 declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone
217217
218218 ; PR10277
219219 ; This test has dead code elimination caused by remat during spilling.
99 define void @bar() nounwind ssp {
1010 entry:
1111 %tmp = load i8** @p ; [#uses=1]
12 %0 = call i64 @llvm.objectsize.i64(i8* %tmp, i1 0, i32 0) ; [#uses=1]
12 %0 = call i64 @llvm.objectsize.i64(i8* %tmp, i1 0) ; [#uses=1]
1313 %cmp = icmp ne i64 %0, -1 ; [#uses=1]
1414 ; X64: movabsq $-1, [[RAX:%r..]]
1515 ; X64: cmpq $-1, [[RAX]]
1818 cond.true: ; preds = %entry
1919 %tmp1 = load i8** @p ; [#uses=1]
2020 %tmp2 = load i8** @p ; [#uses=1]
21 %1 = call i64 @llvm.objectsize.i64(i8* %tmp2, i1 1, i32 0) ; [#uses=1]
21 %1 = call i64 @llvm.objectsize.i64(i8* %tmp2, i1 1) ; [#uses=1]
2222 %call = call i8* @__strcpy_chk(i8* %tmp1, i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i64 %1) ssp ; [#uses=1]
2323 br label %cond.end
2424
3232 ret void
3333 }
3434
35 declare i64 @llvm.objectsize.i64(i8*, i1, i32) nounwind readonly
35 declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readonly
3636
3737 declare i8* @__strcpy_chk(i8*, i8*, i64) ssp
3838
4646 %tmp = load i8** %__dest.addr ; [#uses=1]
4747 %tmp1 = load i8** %__src.addr ; [#uses=1]
4848 %tmp2 = load i8** %__dest.addr ; [#uses=1]
49 %0 = call i64 @llvm.objectsize.i64(i8* %tmp2, i1 1, i32 0) ; [#uses=1]
49 %0 = call i64 @llvm.objectsize.i64(i8* %tmp2, i1 1) ; [#uses=1]
5050 %call = call i8* @__strcpy_chk(i8* %tmp, i8* %tmp1, i64 %0) ssp ; [#uses=1]
5151 store i8* %call, i8** %retval
5252 %1 = load i8** %retval ; [#uses=1]
11 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
22 target triple = "x86_64-apple-darwin10.0.0"
33
4 declare i64 @llvm.objectsize.i64(i8*, i1, i32) nounwind readnone
4 declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone
55
66 define void @test5() nounwind optsize noinline ssp {
77 entry:
88 ; CHECK: movq ___stack_chk_guard@GOTPCREL(%rip)
99 %buf = alloca [64 x i8], align 16
10 %0 = call i64 @llvm.objectsize.i64(i8* undef, i1 false, i32 0)
10 %0 = call i64 @llvm.objectsize.i64(i8* undef, i1 false)
1111 br i1 false, label %if.end, label %if.then
1212
1313 if.then: ; preds = %entry
11
22 declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
33
4 declare i64 @llvm.objectsize.i64(i8*, i1, i32) nounwind readnone
4 declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone
55
66 declare i8* @foo(i8*, i32, i64, i64) nounwind
77
2222 %tmp1 = load i32* %__val.addr, align 4, !dbg !21, !tbaa !17
2323 %tmp2 = load i64* %__len.addr, align 8, !dbg !21, !tbaa !19
2424 %tmp3 = load i8** %__dest.addr, align 8, !dbg !21, !tbaa !13
25 %0 = call i64 @llvm.objectsize.i64(i8* %tmp3, i1 false, i32 0), !dbg !21
25 %0 = call i64 @llvm.objectsize.i64(i8* %tmp3, i1 false), !dbg !21
2626 %call = call i8* @foo(i8* %tmp, i32 %tmp1, i64 %tmp2, i64 %0), !dbg !21
2727 ret i8* %call, !dbg !21
2828 }
88 define i32 @foo() nounwind {
99 ; CHECK: @foo
1010 ; CHECK-NEXT: ret i32 60
11 %1 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false, i32 0)
11 %1 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
1212 ret i32 %1
1313 }
1414
1616 ; CHECK: @bar
1717 entry:
1818 %retval = alloca i8*
19 %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false, i32 0)
19 %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
2020 %cmp = icmp ne i32 %0, -1
2121 ; CHECK: br i1 true
2222 br i1 %cmp, label %cond.true, label %cond.false
3333 define i32 @f() nounwind {
3434 ; CHECK: @f
3535 ; CHECK-NEXT: ret i32 0
36 %1 = call i32 @llvm.objectsize.i32(i8* getelementptr ([60 x i8]* @a, i32 1, i32 0), i1 false, i32 0)
36 %1 = call i32 @llvm.objectsize.i32(i8* getelementptr ([60 x i8]* @a, i32 1, i32 0), i1 false)
3737 ret i32 %1
3838 }
3939
4141
4242 define i1 @baz() nounwind {
4343 ; CHECK: @baz
44 ; CHECK-NEXT: objectsize
45 %1 = tail call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 0), i1 false, i32 0)
44 ; CHECK-NEXT: ret i1 true
45 %1 = tail call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 0), i1 false)
4646 %2 = icmp eq i32 %1, -1
4747 ret i1 %2
4848 }
5151 ; CHECK: @test1
5252 ; CHECK: objectsize.i32
5353 entry:
54 %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 10), i1 false, i32 0) ; [#uses=1]
54 %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 10), i1 false) ; [#uses=1]
5555 %1 = icmp eq i32 %0, -1 ; [#uses=1]
5656 br i1 %1, label %"47", label %"46"
5757
6767 define i32 @test2() nounwind {
6868 ; CHECK: @test2
6969 ; CHECK-NEXT: ret i32 34
70 %1 = call i32 @llvm.objectsize.i32(i8* getelementptr (i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false, i32 0)
70 %1 = call i32 @llvm.objectsize.i32(i8* getelementptr (i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false)
7171 ret i32 %1
7272 }
7373
7676
7777 declare i8* @__memcpy_chk(i8*, i8*, i32, i32) nounwind
7878
79 declare i32 @llvm.objectsize.i32(i8*, i1, i32) nounwind readonly
79 declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
8080
8181 declare i8* @__inline_memcpy_chk(i8*, i8*, i32) nounwind inlinehint
8282
8888 bb11:
8989 %0 = getelementptr inbounds float* getelementptr inbounds ([480 x float]* @array, i32 0, i32 128), i32 -127 ; [#uses=1]
9090 %1 = bitcast float* %0 to i8* ; [#uses=1]
91 %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false, i32 0) ; [#uses=1]
91 %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false) ; [#uses=1]
9292 %3 = call i8* @__memcpy_chk(i8* undef, i8* undef, i32 512, i32 %2) nounwind ; [#uses=0]
9393 ; CHECK: unreachable
9494 unreachable
110110 entry:
111111 %0 = alloca %struct.data, align 8
112112 %1 = bitcast %struct.data* %0 to i8*
113 %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false, i32 0) nounwind
113 %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false) nounwind
114114 ; CHECK-NOT: @llvm.objectsize
115115 ; CHECK: @llvm.memset.p0i8.i32(i8* %1, i8 0, i32 1824, i32 8, i1 false)
116116 %3 = call i8* @__memset_chk(i8* %1, i32 0, i32 1824, i32 %2) nounwind
124124 ; CHECK: @test5
125125 entry:
126126 %0 = tail call noalias i8* @malloc(i32 20) nounwind
127 %1 = tail call i32 @llvm.objectsize.i32(i8* %0, i1 false, i32 0)
127 %1 = tail call i32 @llvm.objectsize.i32(i8* %0, i1 false)
128128 %2 = load i8** @s, align 8
129129 ; CHECK-NOT: @llvm.objectsize
130130 ; CHECK: @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 10, i32 1, i1 false)
136136 ; CHECK: @test6
137137 entry:
138138 %0 = tail call noalias i8* @malloc(i32 20) nounwind
139 %1 = tail call i32 @llvm.objectsize.i32(i8* %0, i1 false, i32 0)
139 %1 = tail call i32 @llvm.objectsize.i32(i8* %0, i1 false)
140140 %2 = load i8** @s, align 8
141141 ; CHECK-NOT: @llvm.objectsize
142142 ; CHECK: @__memcpy_chk(i8* %0, i8* %1, i32 30, i32 20)
152152 ; CHECK: @test7
153153 %alloc = call noalias i8* @malloc(i32 48) nounwind
154154 %gep = getelementptr inbounds i8* %alloc, i32 16
155 %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false, i32 0) nounwind readonly
155 %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false) nounwind readonly
156156 ; CHECK-NEXT: ret i32 32
157157 ret i32 %objsize
158158 }
163163 ; CHECK: @test8
164164 %alloc = call noalias i8* @calloc(i32 5, i32 7) nounwind
165165 %gep = getelementptr inbounds i8* %alloc, i32 5
166 %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false, i32 0) nounwind readonly
166 %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false) nounwind readonly
167167 ; CHECK-NEXT: ret i32 30
168168 ret i32 %objsize
169169 }
170
171 ; CHECK: @test9
172 define i32 @test9(i32 %x, i32 %y) nounwind {
173 %a = alloca [3 x [4 x double]], align 8
174 %1 = getelementptr inbounds [3 x [4 x double]]* %a, i32 0, i32 %x
175 %2 = getelementptr inbounds [4 x double]* %1, i32 0, i32 %y
176 %3 = bitcast double* %2 to i8*
177 %objsize = call i32 @llvm.objectsize.i32(i8* %3, i1 false, i32 2)
178 ret i32 %objsize
179 ; CHECK-NEXT: shl i32 %x, 5
180 ; CHECK-NEXT: shl i32 %y, 3
181 ; CHECK-NEXT: add i32
182 ; CHECK-NEXT: sub i32 96,
183 ; CHECK-NEXT: icmp ugt i32 {{.*}}, 96
184 ; CHECK-NEXT: select i1 {{.*}}, i32 0,
185 }
186
187 ; CHECK: @test10
188 define i32 @test10(i32 %x, i32 %y) nounwind {
189 %alloc = call noalias i8* @calloc(i32 %x, i32 %y) nounwind
190 %gep = getelementptr inbounds i8* %alloc, i32 5
191 %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false, i32 2)
192 ret i32 %objsize
193 ; CHECK-NEXT: mul i32
194 ; CHECK-NEXT: add i32 {{.*}}, -5
195 ; CHECK-NEXT: icmp ult i32 {{.*}}, 5
196 ; CHECK-NEXT: select i1
197 ; CHECK-NEXT: ret
198 }
199
200 ; CHECK: @test11
201 define i32 @test11(i32 %x, i32 %y) nounwind {
202 %alloc = call i8* @malloc(i32 %x)
203 %allocd = bitcast i8* %alloc to double*
204 %gep = getelementptr double* %allocd, i32 %y
205 %gepi8 = bitcast double* %gep to i8*
206 %objsize = call i32 @llvm.objectsize.i32(i8* %gepi8, i1 false, i32 2)
207 ret i32 %objsize
208 ; CHECK-NEXT: shl i32
209 ; CHECK-NEXT: sub i32
210 ; CHECK-NEXT: icmp ugt i32
211 ; CHECK-NEXT: select i1
212 ; CHECK-NEXT: ret
213 }
214
215 ; CHECK: @test12
216 define i32 @test12(i32 %x) nounwind {
217 %alloc = alloca i32, i32 %x, align 16
218 %gep = getelementptr i32* %alloc, i32 7
219 %gepi8 = bitcast i32* %gep to i8*
220 %objsize = call i32 @llvm.objectsize.i32(i8* %gepi8, i1 false, i32 2)
221 ret i32 %objsize
222 ; CHECK-NEXT: shl i32
223 ; CHECK-NEXT: add i32 {{.*}}, -28
224 ; CHECK-NEXT: icmp ult i32 {{.*}}, 28
225 ; CHECK-NEXT: select i1
226 ; CHECK-NEXT: ret
227 }
228
229 ; CHECK: @test13
230 define i32 @test13(i32 %x, i32 %y) nounwind {
231 %alloc = call i8* @calloc(i32 %x, i32 %y)
232 %alloc2 = call i8* @malloc(i32 %x)
233 %objsize = call i32 @llvm.objectsize.i32(i8* %alloc, i1 false, i32 1)
234 %objsize2 = call i32 @llvm.objectsize.i32(i8* %alloc2, i1 false, i32 1)
235 %add = add i32 %objsize, %objsize2
236 ret i32 %add
237 ; CHECK: objectsize
238 ; CHECK: objectsize
239 ; CHECK: add
240 }
241
242 ; CHECK: @overflow
243 define i32 @overflow() {
244 %alloc = call noalias i8* @malloc(i32 21) nounwind
245 %gep = getelementptr inbounds i8* %alloc, i32 50
246 %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false, i32 0) nounwind readonly
247 ; CHECK-NEXT: ret i32 0
248 ret i32 %objsize
249 }
1010
1111 declare i8* @__stpcpy_chk(i8*, i8*, i32) nounwind
1212
13 declare i32 @llvm.objectsize.i32(i8*, i1, i32) nounwind readonly
13 declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
1414
1515 define i32 @t1() {
1616 ; CHECK: @t1
2727 %target = alloca [1024 x i8]
2828 %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0
2929 %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0
30 %tmp1 = call i32 @llvm.objectsize.i32(i8* %arg1, i1 false, i32 0)
30 %tmp1 = call i32 @llvm.objectsize.i32(i8* %arg1, i1 false)
3131 %rslt1 = call i8* @__stpcpy_chk(i8* %arg1, i8* %arg2, i32 %tmp1)
3232 ; CHECK: @__memcpy_chk
3333 ret i32 0
1010
1111 declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind
1212
13 declare i32 @llvm.objectsize.i32(i8*, i1, i32) nounwind readonly
13 declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
1414
1515 ; rdar://6839935
1616
2929 %target = alloca [1024 x i8]
3030 %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0
3131 %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0
32 %tmp1 = call i32 @llvm.objectsize.i32(i8* %arg1, i1 false, i32 0)
32 %tmp1 = call i32 @llvm.objectsize.i32(i8* %arg1, i1 false)
3333 %rslt1 = call i8* @__strcpy_chk(i8* %arg1, i8* %arg2, i32 %tmp1)
3434 ; CHECK: @__memcpy_chk
3535 ret i32 0