Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -277,10 +277,22 @@ switch (II->getIntrinsicID()) { default: break; case Intrinsic::objectsize: { + bool MinTrue = CI.getArgOperand(1) == ConstantInt::getTrue(CI.getContext()); + Constant *SizeC = nullptr; uint64_t Size; + // Try to lower objectsize. If the size is unknown, lower it to 0 or -1, + // depending on the min argument. + // One could argue this is a bit early to do the lowering, since the size + // might be made apparent by later optimizations. In practice however, + // the overwhelming majority of cases has a never-known objectsize, and in + // a lot of the remaining few, the size is immediately apparent (say from a + // global value, or an alloca). + // Keeping the intrinsic call intact mostly prevents optimizations. if (getObjectSize(II->getArgOperand(0), Size, DL, TLI)) - return ReplaceInstUsesWith(CI, ConstantInt::get(CI.getType(), Size)); - return nullptr; + SizeC = ConstantInt::get(CI.getType(), Size); + else + SizeC = ConstantInt::get(CI.getType(), MinTrue ? 0 : -1); + return ReplaceInstUsesWith(CI, SizeC); } case Intrinsic::bswap: { Value *IIOperand = II->getArgOperand(0); Index: test/Transforms/InstCombine/objsize.ll =================================================================== --- test/Transforms/InstCombine/objsize.ll +++ test/Transforms/InstCombine/objsize.ll @@ -41,7 +41,7 @@ define i1 @baz() nounwind { ; CHECK-LABEL: @baz( -; CHECK-NEXT: objectsize +; CHECK-NEXT: ret i1 true %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 0), i1 false) %2 = icmp eq i32 %1, -1 ret i1 %2 @@ -49,7 +49,7 @@ define void @test1(i8* %q, i32 %x) nounwind noinline { ; CHECK-LABEL: @test1( -; CHECK: objectsize.i32.p0i8 +; CHECK: br i1 true, label %"47", label %"46" entry: %0 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 10), i1 false) ; [#uses=1] %1 = icmp eq i32 %0, -1 ; [#uses=1] @@ -231,7 +231,7 @@ %0 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %select, i1 true) %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %select2, i1 true) %2 = add i32 %0, %1 -; CHECK: ret i32 undef +; CHECK: ret i32 0 ret i32 %2 return: @@ -249,7 +249,7 @@ %gep2 = getelementptr i8* %gep, i32 1 %gep = getelementptr i8* %gep2, i32 1 %o = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 true) -; CHECK: ret i32 undef +; CHECK: ret i32 0 ret i32 %o return: @@ -269,7 +269,7 @@ @globalalias2 = weak alias [60 x i8]* @a ; CHECK-LABEL: @test19( -; CHECK: llvm.objectsize +; CHECK: ret i32 -1 define i32 @test19() { %bc = bitcast [60 x i8]* @globalalias2 to i8* %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false) Index: test/Transforms/InstCombine/stpcpy_chk-1.ll =================================================================== --- test/Transforms/InstCombine/stpcpy_chk-1.ll +++ test/Transforms/InstCombine/stpcpy_chk-1.ll @@ -60,7 +60,7 @@ %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0 -; CHECK: @__memcpy_chk +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i32 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false) %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 %len) ; CHECK: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 11) Index: test/Transforms/InstCombine/strcpy_chk-1.ll =================================================================== --- test/Transforms/InstCombine/strcpy_chk-1.ll +++ test/Transforms/InstCombine/strcpy_chk-1.ll @@ -60,7 +60,7 @@ %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0 -; CHECK: @__memcpy_chk +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i32 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false) call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len) ret void