llvm.org GIT mirror llvm / 99ef84f
Add a 'dynamic' parameter to the objectsize intrinsic This is meant to be used with clang's __builtin_dynamic_object_size. When 'true' is passed to this parameter, the intrinsic has the potential to be folded into instructions that will be evaluated at run time. When 'false', the objectsize intrinsic behaviour is unchanged. rdar://32212419 Differential revision: https://reviews.llvm.org/D56761 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352664 91177308-0d34-0410-b5e6-96231b3b80d8 Erik Pilkington 6 months ago
23 changed file(s) with 251 addition(s) and 147 deletion(s). Raw diff Collapse all Expand all
1557415574
1557515575 ::
1557615576
15577 declare i32 @llvm.objectsize.i32(i8* , i1 , i1 )
15578 declare i64 @llvm.objectsize.i64(i8* , i1 , i1 )
15579
15580 Overview:
15581 """""""""
15582
15583 The ``llvm.objectsize`` intrinsic is designed to provide information to
15584 the optimizers to determine at compile time whether a) an operation
15585 (like memcpy) will overflow a buffer that corresponds to an object, or
15586 b) that a runtime check for overflow isn't necessary. An object in this
15587 context means an allocation of a specific class, structure, array, or
15588 other object.
15589
15590 Arguments:
15591 """"""""""
15592
15593 The ``llvm.objectsize`` intrinsic takes three arguments. The first argument is
15594 a pointer to or into the ``object``. The second argument determines whether
15595 ``llvm.objectsize`` returns 0 (if true) or -1 (if false) when the object size
15596 is unknown. The third argument controls how ``llvm.objectsize`` acts when
15597 ``null`` in address space 0 is used as its pointer argument. If it's ``false``,
15577 declare i32 @llvm.objectsize.i32(i8* , i1 , i1 , i1 )
15578 declare i64 @llvm.objectsize.i64(i8* , i1 , i1 , i1 )
15579
15580 Overview:
15581 """""""""
15582
15583 The ``llvm.objectsize`` intrinsic is designed to provide information to the
15584 optimizer to determine whether a) an operation (like memcpy) will overflow a
15585 buffer that corresponds to an object, or b) that a runtime check for overflow
15586 isn't necessary. An object in this context means an allocation of a specific
15587 class, structure, array, or other object.
15588
15589 Arguments:
15590 """"""""""
15591
15592 The ``llvm.objectsize`` intrinsic takes four arguments. The first argument is a
15593 pointer to or into the ``object``. The second argument determines whether
15594 ``llvm.objectsize`` returns 0 (if true) or -1 (if false) when the object size is
15595 unknown. The third argument controls how ``llvm.objectsize`` acts when ``null``
15596 in address space 0 is used as its pointer argument. If it's ``false``,
1559815597 ``llvm.objectsize`` reports 0 bytes available when given ``null``. Otherwise, if
1559915598 the ``null`` is in a non-zero address space or if ``true`` is given for the
15600 third argument of ``llvm.objectsize``, we assume its size is unknown.
15601
15602 The second and third arguments only accept constants.
15603
15604 Semantics:
15605 """"""""""
15606
15607 The ``llvm.objectsize`` intrinsic is lowered to a constant representing
15608 the size of the object concerned. If the size cannot be determined at
15609 compile time, ``llvm.objectsize`` returns ``i32/i64 -1 or 0`` (depending
15610 on the ``min`` argument).
15599 third argument of ``llvm.objectsize``, we assume its size is unknown. The fourth
15600 argument to ``llvm.objectsize`` determines if the value should be evaluated at
15601 runtime.
15602
15603 The second, third, and fourth arguments only accept constants.
15604
15605 Semantics:
15606 """"""""""
15607
15608 The ``llvm.objectsize`` intrinsic is lowered to a value representing the size of
15609 the object concerned. If the size cannot be determined, ``llvm.objectsize``
15610 returns ``i32/i64 -1 or 0`` (depending on the ``min`` argument).
1561115611
1561215612 '``llvm.expect``' Intrinsic
1561315613 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
176176 const TargetLibraryInfo *TLI, ObjectSizeOpts Opts = {});
177177
178178 /// Try to turn a call to \@llvm.objectsize into an integer value of the given
179 /// Type. Returns null on failure.
180 /// If MustSucceed is true, this function will not return null, and may return
181 /// conservative values governed by the second argument of the call to
182 /// objectsize.
183 ConstantInt *lowerObjectSizeCall(IntrinsicInst *ObjectSize,
184 const DataLayout &DL,
185 const TargetLibraryInfo *TLI,
186 bool MustSucceed);
179 /// Type. Returns null on failure. If MustSucceed is true, this function will
180 /// not return null, and may return conservative values governed by the second
181 /// argument of the call to objectsize.
182 Value *lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL,
183 const TargetLibraryInfo *TLI, bool MustSucceed);
184
185
187186
188187 using SizeOffsetType = std::pair;
189188
263262 Value *Zero;
264263 CacheMapTy CacheMap;
265264 PtrSetTy SeenVals;
266 bool RoundToAlign;
267
268 SizeOffsetEvalType unknown() {
265 ObjectSizeOpts EvalOpts;
266
267 SizeOffsetEvalType compute_(Value *V);
268
269 public:
270 static SizeOffsetEvalType unknown() {
269271 return std::make_pair(nullptr, nullptr);
270272 }
271273
272 SizeOffsetEvalType compute_(Value *V);
273
274 public:
275274 ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI,
276 LLVMContext &Context, bool RoundToAlign = false);
275 LLVMContext &Context, ObjectSizeOpts EvalOpts = {});
277276
278277 SizeOffsetEvalType compute(Value *V);
279278
557557
558558 // Internal interface for object size checking
559559 def int_objectsize : Intrinsic<[llvm_anyint_ty],
560 [llvm_anyptr_ty, llvm_i1_ty, llvm_i1_ty],
560 [llvm_anyptr_ty, llvm_i1_ty,
561 llvm_i1_ty, llvm_i1_ty],
561562 [IntrNoMem, IntrSpeculatable]>,
562563 GCCBuiltin<"__builtin_object_size">;
563564
440440 return true;
441441 }
442442
443 ConstantInt *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
444 const DataLayout &DL,
445 const TargetLibraryInfo *TLI,
446 bool MustSucceed) {
443 Value *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
444 const DataLayout &DL,
445 const TargetLibraryInfo *TLI,
446 bool MustSucceed) {
447447 assert(ObjectSize->getIntrinsicID() == Intrinsic::objectsize &&
448448 "ObjectSize must be a call to llvm.objectsize!");
449449
460460 EvalOptions.NullIsUnknownSize =
461461 cast(ObjectSize->getArgOperand(2))->isOne();
462462
463 // FIXME: Does it make sense to just return a failure value if the size won't
464 // fit in the output and `!MustSucceed`?
465 uint64_t Size;
466463 auto *ResultType = cast(ObjectSize->getType());
467 if (getObjectSize(ObjectSize->getArgOperand(0), Size, DL, TLI, EvalOptions) &&
468 isUIntN(ResultType->getBitWidth(), Size))
469 return ConstantInt::get(ResultType, Size);
464 bool StaticOnly = cast(ObjectSize->getArgOperand(3))->isZero();
465 if (StaticOnly) {
466 // FIXME: Does it make sense to just return a failure value if the size won't
467 // fit in the output and `!MustSucceed`?
468 uint64_t Size;
469 if (getObjectSize(ObjectSize->getArgOperand(0), Size, DL, TLI, EvalOptions) &&
470 isUIntN(ResultType->getBitWidth(), Size))
471 return ConstantInt::get(ResultType, Size);
472 } else {
473 LLVMContext &Ctx = ObjectSize->getFunction()->getContext();
474 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, EvalOptions);
475 SizeOffsetEvalType SizeOffsetPair =
476 Eval.compute(ObjectSize->getArgOperand(0));
477
478 if (SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown()) {
479 IRBuilder Builder(Ctx, TargetFolder(DL));
480 Builder.SetInsertPoint(ObjectSize);
481
482 // If we've outside the end of the object, then we can always access
483 // exactly 0 bytes.
484 Value *ResultSize =
485 Builder.CreateSub(SizeOffsetPair.first, SizeOffsetPair.second);
486 Value *UseZero =
487 Builder.CreateICmpULT(SizeOffsetPair.first, SizeOffsetPair.second);
488 return Builder.CreateSelect(UseZero, ConstantInt::get(ResultType, 0),
489 ResultSize);
490 }
491 }
470492
471493 if (!MustSucceed)
472494 return nullptr;
741763
742764 ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(
743765 const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context,
744 bool RoundToAlign)
766 ObjectSizeOpts EvalOpts)
745767 : DL(DL), TLI(TLI), Context(Context), Builder(Context, TargetFolder(DL)),
746 RoundToAlign(RoundToAlign) {
768 EvalOpts(EvalOpts) {
747769 // IntTy and Zero must be set for each compute() since the address space may
748770 // be different for later objects.
749771 }
772794 }
773795
774796 SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
775 ObjectSizeOpts ObjSizeOptions;
776 ObjSizeOptions.RoundToAlign = RoundToAlign;
777
778 ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, ObjSizeOptions);
797 ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, EvalOpts);
779798 SizeOffsetType Const = Visitor.compute(V);
780799 if (Visitor.bothKnown(Const))
781800 return std::make_pair(ConstantInt::get(Context, Const.first),
17041704 default: break;
17051705 case Intrinsic::objectsize: {
17061706 // Lower all uses of llvm.objectsize.*
1707 ConstantInt *RetVal =
1707 Value *RetVal =
17081708 lowerObjectSizeCall(II, *DL, TLInfo, /*MustSucceed=*/true);
17091709
17101710 resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
34583458 Value *NullIsUnknownSize = CI->getNumArgOperands() == 2
34593459 ? Builder.getFalse()
34603460 : CI->getArgOperand(2);
3461 Value *Dynamic =
3462 CI->getNumArgOperands() < 3 ? Builder.getFalse() : CI->getArgOperand(3);
34613463 NewCall = Builder.CreateCall(
3462 NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize});
3464 NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize, Dynamic});
34633465 break;
34643466 }
34653467
917917 );
918918
919919 CallInst *NewCall = Builder.CreateCall(
920 ObjectSize, {Src, Intr->getOperand(1), Intr->getOperand(2)});
920 ObjectSize,
921 {Src, Intr->getOperand(1), Intr->getOperand(2), Intr->getOperand(3)});
921922 Intr->replaceAllUsesWith(NewCall);
922923 Intr->eraseFromParent();
923924 continue;
18931893 switch (II->getIntrinsicID()) {
18941894 default: break;
18951895 case Intrinsic::objectsize:
1896 if (ConstantInt *N =
1897 lowerObjectSizeCall(II, DL, &TLI, /*MustSucceed=*/false))
1898 return replaceInstUsesWith(CI, N);
1896 if (Value *V = lowerObjectSizeCall(II, DL, &TLI, /*MustSucceed=*/false))
1897 return replaceInstUsesWith(CI, V);
18991898 return nullptr;
19001899 case Intrinsic::bswap: {
19011900 Value *IIOperand = II->getArgOperand(0);
22942294
22952295 if (IntrinsicInst *II = dyn_cast(I)) {
22962296 if (II->getIntrinsicID() == Intrinsic::objectsize) {
2297 ConstantInt *Result = lowerObjectSizeCall(II, DL, &TLI,
2298 /*MustSucceed=*/true);
2297 Value *Result =
2298 lowerObjectSizeCall(II, DL, &TLI, /*MustSucceed=*/true);
22992299 replaceInstUsesWith(*I, Result);
23002300 eraseInstFromFunction(*I);
23012301 Users[i] = nullptr; // Skip examining in the next loop.
141141 static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
142142 ScalarEvolution &SE) {
143143 const DataLayout &DL = F.getParent()->getDataLayout();
144 ObjectSizeOffsetEvaluator ObjSizeEval(DL, &TLI, F.getContext(),
145 /*RoundToAlign=*/true);
144 ObjectSizeOpts EvalOpts;
145 EvalOpts.RoundToAlign = true;
146 ObjectSizeOffsetEvaluator ObjSizeEval(DL, &TLI, F.getContext(), EvalOpts);
146147
147148 // check HANDLE_MEMORY_INST in include/llvm/Instruction.def for memory
148149 // touching instructions
5252
5353 define i32 @test.objectsize() {
5454 ; CHECK-LABEL: @test.objectsize(
55 ; CHECK: @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false)
55 ; CHECK: @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
5656 %s = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false)
5757 ret i32 %s
5858 }
6060 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) nounwind readonly
6161 define i64 @test.objectsize.2() {
6262 ; CHECK-LABEL: @test.objectsize.2(
63 ; CHECK: @llvm.objectsize.i64.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false)
63 ; CHECK: @llvm.objectsize.i64.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
6464 %s = call i64 @llvm.objectsize.i64.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false)
6565 ret i64 %s
6666 }
67
6867
6968 declare <2 x double> @llvm.masked.load.v2f64(<2 x double>* %ptrs, i32, <2 x i1> %mask, <2 x double> %src0)
7069
77
88 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) #0
99
10 declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1) #1
10 declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) #1
1111
1212 ; CHECK-LABEL: @promote_with_memcpy(
1313 ; CHECK: getelementptr inbounds [64 x [17 x i32]], [64 x [17 x i32]] addrspace(3)* @promote_with_memcpy.alloca, i32 0, i32 %{{[0-9]+}}
5151
5252 ; CHECK-LABEL: @promote_with_objectsize(
5353 ; CHECK: [[PTR:%[0-9]+]] = getelementptr inbounds [64 x [17 x i32]], [64 x [17 x i32]] addrspace(3)* @promote_with_objectsize.alloca, i32 0, i32 %{{[0-9]+}}
54 ; CHECK: call i32 @llvm.objectsize.i32.p3i8(i8 addrspace(3)* %alloca.bc, i1 false, i1 false)
54 ; CHECK: call i32 @llvm.objectsize.i32.p3i8(i8 addrspace(3)* %alloca.bc, i1 false, i1 false, i1 false)
5555 define amdgpu_kernel void @promote_with_objectsize(i32 addrspace(1)* %out) #0 {
5656 %alloca = alloca [17 x i32], align 4
5757 %alloca.bc = bitcast [17 x i32]* %alloca to i8*
58 %size = call i32 @llvm.objectsize.i32.p0i8(i8* %alloca.bc, i1 false, i1 false)
58 %size = call i32 @llvm.objectsize.i32.p0i8(i8* %alloca.bc, i1 false, i1 false, i1 false)
5959 store i32 %size, i32 addrspace(1)* %out
6060 ret void
6161 }
1414
1515 declare i1 @llvm.is.constant.i32(i32 %a) nounwind readnone
1616 declare i1 @llvm.is.constant.i64(i64 %a) nounwind readnone
17 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1) nounwind readnone
17 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1) nounwind readnone
1818
1919 declare i32 @subfun_1()
2020 declare i32 @subfun_2()
4343 ; CHECK-O2: %bb.0:
4444 ; CHECK-O2: movb $1, %al
4545 ; CHECK-O2-NEXT: retq
46 %os = call i64 @llvm.objectsize.i64.p0i8(i8* %obj, i1 false, i1 false)
46 %os = call i64 @llvm.objectsize.i64.p0i8(i8* %obj, i1 false, i1 false, i1 false)
4747 %v = call i1 @llvm.is.constant.i64(i64 %os)
4848 ret i1 %v
4949 }
1414 %tmp2 = getelementptr inbounds [1024 x i8], [1024 x i8]* %tmp, i64 0, i64 0
1515 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp2, i8* %arg1, i64 1024, i1 false)
1616 ; CHECK: call void @llvm.memcpy
17 %tmp3 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp2, i1 false, i1 true)
17 %tmp3 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp2, i1 false, i1 true, i1 false)
1818 %tmp4 = call i8* @__strncpy_chk(i8* %arg2, i8* %tmp2, i64 1023, i64 %tmp3)
1919 ; CHECK-NOT: call
2020 ; CHECK: call i8* @strncpy(i8* %arg2, i8* nonnull %tmp2, i64 1023)
3232
3333 declare i8* @my_special_strncpy(i8* %arg1, i8* %arg2, i64 %size)
3434
35 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1)
35 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1)
3636
3737 declare i8* @__strncpy_chk(i8*, i8*, i64, i64)
3838
88 ; rdar://8785296
99 define i32 @test1(i8* %ptr) nounwind ssp noredzone align 2 {
1010 entry:
11 %0 = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false, i1 false)
11 %0 = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false, i1 false, i1 false)
1212 %1 = icmp ugt i64 %0, 3
1313 br i1 %1, label %T, label %trap
1414
2828 define i64 @test_objectsize_null_flag(i8* %ptr) {
2929 entry:
3030 ; CHECK: ret i64 -1
31 %0 = tail call i64 @llvm.objectsize.i64(i8* null, i1 false, i1 true)
31 %0 = tail call i64 @llvm.objectsize.i64(i8* null, i1 false, i1 true, i1 false)
3232 ret i64 %0
3333 }
3434
3636 define i64 @test_objectsize_null_flag_min(i8* %ptr) {
3737 entry:
3838 ; CHECK: ret i64 0
39 %0 = tail call i64 @llvm.objectsize.i64(i8* null, i1 true, i1 true)
39 %0 = tail call i64 @llvm.objectsize.i64(i8* null, i1 true, i1 true, i1 false)
4040 ret i64 %0
4141 }
4242
4747 entry:
4848 ; CHECK: ret i64 -1
4949 %0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 false,
50 i1 true)
50 i1 true, i1 false)
5151 ret i64 %0
5252 }
5353
5656 entry:
5757 ; CHECK: ret i64 0
5858 %0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 true,
59 i1 true)
59 i1 true, i1 false)
6060 ret i64 %0
6161 }
6262
6565 entry:
6666 ; CHECK: ret i64 -1
6767 %0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 false,
68 i1 false)
68 i1 false, i1 false)
6969 ret i64 %0
7070 }
7171
7474 entry:
7575 ; CHECK: ret i64 0
7676 %0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 true,
77 i1 false)
77 i1 false, i1 false)
7878 ret i64 %0
7979 }
8080
8181
82 declare i64 @llvm.objectsize.i64(i8*, i1, i1) nounwind readonly
83 declare i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)*, i1, i1) nounwind readonly
82 declare i64 @llvm.objectsize.i64(i8*, i1, i1, i1) nounwind readonly
83 declare i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)*, i1, i1, i1) nounwind readonly
8484
8585 declare void @llvm.trap() nounwind
77 ; CHECK-LABEL: @alloca_overflow_is_unknown(
88 define i16 @alloca_overflow_is_unknown() {
99 %i = alloca i8, i32 65537
10 %j = call i16 @llvm.objectsize.i16.p0i8(i8* %i, i1 false, i1 false)
10 %j = call i16 @llvm.objectsize.i16.p0i8(i8* %i, i1 false, i1 false, i1 false)
1111 ; CHECK: ret i16 -1
1212 ret i16 %j
1313 }
1414
15 declare i16 @llvm.objectsize.i16.p0i8(i8*, i1, i1)
15 declare i16 @llvm.objectsize.i16.p0i8(i8*, i1, i1, i1)
0 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -infer-address-spaces %s | FileCheck %s
11
22 ; CHECK-LABEL: @objectsize_group_to_flat_i32(
3 ; CHECK: %val = call i32 @llvm.objectsize.i32.p3i8(i8 addrspace(3)* %group.ptr, i1 true, i1 false)
3 ; CHECK: %val = call i32 @llvm.objectsize.i32.p3i8(i8 addrspace(3)* %group.ptr, i1 true, i1 false, i1 false)
44 define i32 @objectsize_group_to_flat_i32(i8 addrspace(3)* %group.ptr) #0 {
55 %cast = addrspacecast i8 addrspace(3)* %group.ptr to i8*
6 %val = call i32 @llvm.objectsize.i32.p0i8(i8* %cast, i1 true, i1 false)
6 %val = call i32 @llvm.objectsize.i32.p0i8(i8* %cast, i1 true, i1 false, i1 false)
77 ret i32 %val
88 }
99
1010 ; CHECK-LABEL: @objectsize_global_to_flat_i64(
11 ; CHECK: %val = call i64 @llvm.objectsize.i64.p3i8(i8 addrspace(3)* %global.ptr, i1 true, i1 false)
11 ; CHECK: %val = call i64 @llvm.objectsize.i64.p3i8(i8 addrspace(3)* %global.ptr, i1 true, i1 false, i1 false)
1212 define i64 @objectsize_global_to_flat_i64(i8 addrspace(3)* %global.ptr) #0 {
1313 %cast = addrspacecast i8 addrspace(3)* %global.ptr to i8*
14 %val = call i64 @llvm.objectsize.i64.p0i8(i8* %cast, i1 true, i1 false)
14 %val = call i64 @llvm.objectsize.i64.p0i8(i8* %cast, i1 true, i1 false, i1 false)
1515 ret i64 %val
1616 }
1717
133133 ret i64 %ret
134134 }
135135
136 declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1) #1
137 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1) #1
136 declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) #1
137 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1) #1
138138 declare i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* nocapture, i32, i32, i32, i1) #2
139139 declare i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* nocapture, i64, i32, i32, i1) #2
140140 declare i32 @llvm.amdgcn.atomic.dec.i32.p0i32(i32* nocapture, i32, i32, i32, i1) #2
0 ; RUN: opt -instcombine -S < %s | FileCheck %s --dump-input-on-failure
1
2 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-apple-macosx10.14.0"
4
5 ; Function Attrs: nounwind ssp uwtable
6 define i64 @weird_identity_but_ok(i64 %sz) {
7 entry:
8 %call = tail call i8* @malloc(i64 %sz)
9 %calc_size = tail call i64 @llvm.objectsize.i64.p0i8(i8* %call, i1 false, i1 true, i1 true)
10 tail call void @free(i8* %call)
11 ret i64 %calc_size
12 }
13
14 ; CHECK: define i64 @weird_identity_but_ok(i64 %sz)
15 ; CHECK-NEXT: entry:
16 ; CHECK-NEXT: ret i64 %sz
17 ; CHECK-NEXT: }
18
19 define i64 @phis_are_neat(i1 %which) {
20 entry:
21 br i1 %which, label %first_label, label %second_label
22
23 first_label:
24 %first_call = call i8* @malloc(i64 10)
25 br label %join_label
26
27 second_label:
28 %second_call = call i8* @malloc(i64 30)
29 br label %join_label
30
31 join_label:
32 %joined = phi i8* [ %first_call, %first_label ], [ %second_call, %second_label ]
33 %calc_size = tail call i64 @llvm.objectsize.i64.p0i8(i8* %joined, i1 false, i1 true, i1 true)
34 ret i64 %calc_size
35 }
36
37 ; CHECK: %0 = phi i64 [ 10, %first_label ], [ 30, %second_label ]
38 ; CHECK-NEXT: ret i64 %0
39
40 define i64 @internal_pointer(i64 %sz) {
41 entry:
42 %ptr = call i8* @malloc(i64 %sz)
43 %ptr2 = getelementptr inbounds i8, i8* %ptr, i32 2
44 %calc_size = call i64 @llvm.objectsize.i64.p0i8(i8* %ptr2, i1 false, i1 true, i1 true)
45 ret i64 %calc_size
46 }
47
48 ; CHECK: define i64 @internal_pointer(i64 %sz)
49 ; CHECK-NEXT: entry:
50 ; CHECK-NEXT: %0 = add i64 %sz, -2
51 ; CHECK-NEXT: %1 = icmp ult i64 %sz, 2
52 ; CHECK-NEXT: %2 = select i1 %1, i64 0, i64 %0
53 ; CHECK-NEXT: ret i64 %2
54 ; CHECK-NEXT: }
55
56 define i64 @uses_nullptr_no_fold() {
57 entry:
58 %res = call i64 @llvm.objectsize.i64.p0i8(i8* null, i1 false, i1 true, i1 true)
59 ret i64 %res
60 }
61
62 ; CHECK: %res = call i64 @llvm.objectsize.i64.p0i8(i8* null, i1 false, i1 true, i1 true)
63
64 define i64 @uses_nullptr_fold() {
65 entry:
66 ; NOTE: the third parameter to this call is false, unlike above.
67 %res = call i64 @llvm.objectsize.i64.p0i8(i8* null, i1 false, i1 false, i1 true)
68 ret i64 %res
69 }
70
71 ; CHECK: ret i64 0
72
73 ; Function Attrs: nounwind allocsize(0)
74 declare i8* @malloc(i64)
75
76 declare i8* @get_unknown_buffer()
77
78 ; Function Attrs: nounwind
79 declare void @free(i8* nocapture)
80
81 ; Function Attrs: nounwind readnone speculatable
82 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1)
5454 to label %invoke.cont unwind label %lpad
5555
5656 invoke.cont:
57 ; CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %call, i1 false, i1 false)
57 ; CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %call, i1 false, i1 false, i1 false)
5858 %0 = tail call i64 @llvm.objectsize.i64(i8* %call, i1 false)
5959 ret i64 %0
6060
6868 entry:
6969 %call49 = call i64 @strlen(i8* %a)
7070 %add180 = add i64 %call49, 1
71 %yo107 = call i64 @llvm.objectsize.i64.p0i8(i8* %b, i1 false, i1 false)
71 %yo107 = call i64 @llvm.objectsize.i64.p0i8(i8* %b, i1 false, i1 false, i1 false)
7272 %call50 = call i8* @__memmove_chk(i8* %b, i8* %a, i64 %add180, i64 %yo107)
7373 ; CHECK: %strlen = call i64 @strlen(i8* %b)
7474 ; CHECK-NEXT: %strchr2 = getelementptr i8, i8* %b, i64 %strlen
8686 declare i8* @__memmove_chk(i8*, i8*, i64, i64)
8787 declare i8* @strrchr(i8*, i32)
8888 declare i64 @strlen(i8* nocapture)
89 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1)
89 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1)
9090
9191 declare i8* @__memset_chk(i8*, i32, i64, i64)
9292
9999 br i1 %cmp, label %cleanup, label %if.end
100100 if.end:
101101 %bc = bitcast i8* %call to float*
102 %call2 = tail call i64 @llvm.objectsize.i64.p0i8(i8* nonnull %call, i1 false, i1 false)
102 %call2 = tail call i64 @llvm.objectsize.i64.p0i8(i8* nonnull %call, i1 false, i1 false, i1 false)
103103 %call3 = tail call i8* @__memset_chk(i8* nonnull %call, i32 0, i64 %size, i64 %call2) #1
104104 br label %cleanup
105105 cleanup:
113113 ; CHECK-NEXT: br i1 %cmp, label %cleanup, label %if.end
114114 ; CHECK: if.end:
115115 ; CHECK-NEXT: %bc = bitcast i8* %call to float*
116 ; CHECK-NEXT: %call2 = tail call i64 @llvm.objectsize.i64.p0i8(i8* nonnull %call, i1 false, i1 false)
116 ; CHECK-NEXT: %call2 = tail call i64 @llvm.objectsize.i64.p0i8(i8* nonnull %call, i1 false, i1 false, i1 false)
117117 ; CHECK-NEXT: %call3 = tail call i8* @__memset_chk(i8* nonnull %call, i32 0, i64 %size, i64 %call2)
118118 ; CHECK-NEXT: br label %cleanup
119119 ; CHECK: cleanup:
77 define i32 @foo() nounwind {
88 ; CHECK-LABEL: @foo(
99 ; CHECK-NEXT: ret i32 60
10 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false)
10 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
1111 ret i32 %1
1212 }
1313
1515 ; CHECK-LABEL: @bar(
1616 entry:
1717 %retval = alloca i8*
18 %0 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false)
18 %0 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
1919 %cmp = icmp ne i32 %0, -1
2020 ; CHECK: br i1 true
2121 br i1 %cmp, label %cond.true, label %cond.false
3232 define i32 @f() nounwind {
3333 ; CHECK-LABEL: @f(
3434 ; CHECK-NEXT: ret i32 0
35 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr ([60 x i8], [60 x i8]* @a, i32 1, i32 0), i1 false, i1 false)
35 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr ([60 x i8], [60 x i8]* @a, i32 1, i32 0), i1 false, i1 false, i1 false)
3636 ret i32 %1
3737 }
3838
4141 define i1 @baz() nounwind {
4242 ; CHECK-LABEL: @baz(
4343 ; CHECK-NEXT: objectsize
44 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @window, i32 0, i32 0), i1 false, i1 false)
44 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @window, i32 0, i32 0), i1 false, i1 false, i1 false)
4545 %2 = icmp eq i32 %1, -1
4646 ret i1 %2
4747 }
5050 ; CHECK-LABEL: @test1(
5151 ; CHECK: objectsize.i32.p0i8
5252 entry:
53 %0 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @window, i32 0, i32 10), i1 false, i1 false) ; [#uses=1]
53 %0 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @window, i32 0, i32 10), i1 false, i1 false, i1 false) ; [#uses=1]
5454 %1 = icmp eq i32 %0, -1 ; [#uses=1]
5555 br i1 %1, label %"47", label %"46"
5656
6666 define i32 @test2() nounwind {
6767 ; CHECK-LABEL: @test2(
6868 ; CHECK-NEXT: ret i32 34
69 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr (i8, i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false, i1 false)
69 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr (i8, i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false, i1 false, i1 false)
7070 ret i32 %1
7171 }
7272
7575
7676 declare i8* @__memcpy_chk(i8*, i8*, i32, i32) nounwind
7777
78 declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1) nounwind readonly
79
80 declare i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)*, i1, i1) nounwind readonly
78 declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) nounwind readonly
79
80 declare i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)*, i1, i1, i1) nounwind readonly
8181
8282 declare i8* @__inline_memcpy_chk(i8*, i8*, i32) nounwind inlinehint
8383
8989 bb11:
9090 %0 = getelementptr inbounds float, float* getelementptr inbounds ([480 x float], [480 x float]* @array, i32 0, i32 128), i32 -127 ; [#uses=1]
9191 %1 = bitcast float* %0 to i8* ; [#uses=1]
92 %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false, i1 false) ; [#uses=1]
92 %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false, i1 false, i1 false) ; [#uses=1]
9393 %3 = call i8* @__memcpy_chk(i8* undef, i8* undef, i32 512, i32 %2) nounwind ; [#uses=0]
9494 ; CHECK: unreachable
9595 unreachable
111111 entry:
112112 %0 = alloca %struct.data, align 8
113113 %1 = bitcast %struct.data* %0 to i8*
114 %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false, i1 false) nounwind
114 %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false, i1 false, i1 false) nounwind
115115 ; CHECK-NOT: @llvm.objectsize
116116 ; CHECK: @llvm.memset.p0i8.i32(i8* nonnull align 8 %1, i8 0, i32 1824, i1 false)
117117 %3 = call i8* @__memset_chk(i8* %1, i32 0, i32 1824, i32 %2) nounwind
126126 ; CHECK-LABEL: @test5(
127127 entry:
128128 %0 = tail call noalias i8* @malloc(i32 20) nounwind
129 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false, i1 false)
129 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false, i1 false, i1 false)
130130 %2 = load i8*, i8** @s, align 8
131131 ; CHECK-NOT: @llvm.objectsize
132132 ; CHECK: @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %0, i8* align 1 %1, i32 10, i1 false)
138138 ; CHECK-LABEL: @test6(
139139 entry:
140140 %0 = tail call noalias i8* @malloc(i32 20) nounwind
141 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false, i1 false)
141 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false, i1 false, i1 false)
142142 %2 = load i8*, i8** @s, align 8
143143 ; CHECK-NOT: @llvm.objectsize
144144 ; CHECK: @__memcpy_chk(i8* %0, i8* %1, i32 30, i32 20)
155155 %alloc = call noalias i8* @malloc(i32 48) nounwind
156156 store i8* %alloc, i8** %esc
157157 %gep = getelementptr inbounds i8, i8* %alloc, i32 16
158 %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false, i1 false) nounwind readonly
158 %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false, i1 false, i1 false) nounwind readonly
159159 ; CHECK: ret i32 32
160160 ret i32 %objsize
161161 }
167167 %alloc = call noalias i8* @calloc(i32 5, i32 7) nounwind
168168 store i8* %alloc, i8** %esc
169169 %gep = getelementptr inbounds i8, i8* %alloc, i32 5
170 %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false, i1 false) nounwind readonly
170 %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false, i1 false, i1 false) nounwind readonly
171171 ; CHECK: ret i32 30
172172 ret i32 %objsize
173173 }
179179 define i32 @test9(i8** %esc) {
180180 %call = tail call i8* @strdup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0)) nounwind
181181 store i8* %call, i8** %esc, align 8
182 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false)
182 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false, i1 false)
183183 ; CHECK: ret i32 8
184184 ret i32 %1
185185 }
188188 define i32 @test10(i8** %esc) {
189189 %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i32 3) nounwind
190190 store i8* %call, i8** %esc, align 8
191 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false)
191 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false, i1 false)
192192 ; CHECK: ret i32 4
193193 ret i32 %1
194194 }
197197 define i32 @test11(i8** %esc) {
198198 %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i32 7) nounwind
199199 store i8* %call, i8** %esc, align 8
200 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false)
200 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false, i1 false)
201201 ; CHECK: ret i32 8
202202 ret i32 %1
203203 }
206206 define i32 @test12(i8** %esc) {
207207 %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i32 8) nounwind
208208 store i8* %call, i8** %esc, align 8
209 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false)
209 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false, i1 false)
210210 ; CHECK: ret i32 8
211211 ret i32 %1
212212 }
215215 define i32 @test13(i8** %esc) {
216216 %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i32 57) nounwind
217217 store i8* %call, i8** %esc, align 8
218 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false)
218 %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false, i1 false)
219219 ; CHECK: ret i32 8
220220 ret i32 %1
221221 }
226226 ; CHECK-NEXT: ret i32 60
227227 define i32 @test18() {
228228 %bc = bitcast [60 x i8]* @globalalias to i8*
229 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false, i1 false)
229 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false, i1 false, i1 false)
230230 ret i32 %1
231231 }
232232
236236 ; CHECK: llvm.objectsize
237237 define i32 @test19() {
238238 %bc = bitcast [60 x i8]* @globalalias2 to i8*
239 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false, i1 false)
239 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false, i1 false, i1 false)
240240 ret i32 %1
241241 }
242242
243243 ; CHECK-LABEL: @test20(
244244 ; CHECK: ret i32 0
245245 define i32 @test20() {
246 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1 false)
246 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1 false, i1 false)
247247 ret i32 %1
248248 }
249249
250250 ; CHECK-LABEL: @test21(
251251 ; CHECK: ret i32 0
252252 define i32 @test21() {
253 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1 false)
253 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1 false, i1 false)
254254 ret i32 %1
255255 }
256256
257257 ; CHECK-LABEL: @test22(
258258 ; CHECK: llvm.objectsize
259259 define i32 @test22() {
260 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1 true)
260 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1 true, i1 false)
261261 ret i32 %1
262262 }
263263
264264 ; CHECK-LABEL: @test23(
265265 ; CHECK: llvm.objectsize
266266 define i32 @test23() {
267 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1 true)
267 %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1 true, i1 false)
268268 ret i32 %1
269269 }
270270
273273 ; CHECK: llvm.objectsize
274274 define i32 @test24() {
275275 %1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 false,
276 i1 false)
276 i1 false, i1 false)
277277 ret i32 %1
278278 }
279279
281281 ; CHECK: llvm.objectsize
282282 define i32 @test25() {
283283 %1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 true,
284 i1 false)
284 i1 false, i1 false)
285285 ret i32 %1
286286 }
287287
289289 ; CHECK: llvm.objectsize
290290 define i32 @test26() {
291291 %1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 false,
292 i1 true)
292 i1 true, i1 false)
293293 ret i32 %1
294294 }
295295
297297 ; CHECK: llvm.objectsize
298298 define i32 @test27() {
299299 %1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 true,
300 i1 true)
301 ret i32 %1
302 }
300 i1 true, i1 false)
301 ret i32 %1
302 }
6363 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
6464 %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
6565
66 ; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false)
66 ; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
6767 ; CHECK-NEXT: %1 = call i8* @__memcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i32 %len)
6868 ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
69 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false)
69 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
7070 %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 %len)
7171 ret i8* %ret
7272 }
8080 ; CHECK-NEXT: %strlen = call i32 @strlen(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0))
8181 ; CHECK-NEXT: %1 = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 %strlen
8282 ; CHECK-NEXT: ret i8* %1
83 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false)
83 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
8484 %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %dst, i32 %len)
8585 ret i8* %ret
8686 }
9999 }
100100
101101 declare i8* @__stpcpy_chk(i8*, i8*, i32) nounwind
102 declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1) nounwind readonly
102 declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) nounwind readonly
6363 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
6464 %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
6565
66 ; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false)
66 ; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
6767 ; CHECK-NEXT: %1 = call i8* @__memcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i32 %len)
6868 ; CHECK-NEXT: ret i8* %1
69 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false)
69 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
7070 %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len)
7171 ret i8* %ret
7272 }
7777 ; CHECK-LABEL: @test_simplify6(
7878 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
7979
80 ; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false)
80 ; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
8181 ; CHECK-NEXT: %ret = call i8* @__strcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i32 %len)
8282 ; CHECK-NEXT: ret i8* %ret
83 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false)
83 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
8484 %ret = call i8* @__strcpy_chk(i8* %dst, i8* %dst, i32 %len)
8585 ret i8* %ret
8686 }
9999 }
100100
101101 declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind
102 declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1) nounwind readonly
102 declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) nounwind readonly