Permalink
Browse files

change the objectsize intrinsic signature: add a 3rd parameter to den…

…ote the maximum runtime performance penalty that the user is willing to accept.

This commit only adds the parameter. Code taking advantage of it will follow.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156473 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information...
1 parent 80fa472 commit 30759542aa820b9fc74c77bfa3c011cb0a106ef9 @nunoplopes nunoplopes committed May 9, 2012
View
24 docs/LangRef.html
@@ -8441,8 +8441,8 @@
<h5>Syntax:</h5>
<pre>
- declare i32 @llvm.objectsize.i32(i8* &lt;object&gt;, i1 &lt;type&gt;)
- declare i64 @llvm.objectsize.i64(i8* &lt;object&gt;, i1 &lt;type&gt;)
+ declare i32 @llvm.objectsize.i32(i8* &lt;object&gt;, i1 &lt;min&gt;, i32 &lt;runtime&gt;)
+ declare i64 @llvm.objectsize.i64(i8* &lt;object&gt;, i1 &lt;min&gt;, i32 &lt;runtime&gt;)
</pre>
<h5>Overview:</h5>
@@ -8453,17 +8453,21 @@
an allocation of a specific class, structure, array, or other object.</p>
<h5>Arguments:</h5>
-<p>The <tt>llvm.objectsize</tt> intrinsic takes two arguments. The first
+<p>The <tt>llvm.objectsize</tt> intrinsic takes three arguments. The first
argument is a pointer to or into the <tt>object</tt>. The second argument
- is a boolean 0 or 1. This argument determines whether you want the
- maximum (0) or minimum (1) bytes remaining. This needs to be a literal 0 or
- 1, variables are not allowed.</p>
+ is a boolean and determines whether <tt>llvm.objectsize</tt> returns 0 (if true)
+ or -1 (if false) when the object size is unknown.
+ The third argument, <tt>runtime</tt>, indicates whether the compiler is allowed
+ to return a non-constant value. The higher the value, the higher the potential
+ run-time performance impact.
+ The second and third arguments only accepts constants.</p>
<h5>Semantics:</h5>
-<p>The <tt>llvm.objectsize</tt> intrinsic is lowered to either a constant
- representing the size of the object concerned, or <tt>i32/i64 -1 or 0</tt>,
- depending on the <tt>type</tt> argument, if the size cannot be determined at
- compile time.</p>
+<p>The <tt>llvm.objectsize</tt> intrinsic is lowered to a constant representing
+ the size of the object concerned. If the size cannot be determined at compile
+ time, <tt>llvm.objectsize</tt> either returns <tt>i32/i64 -1 or 0</tt>
+ (depending on the <tt>min</tt> argument) if <tt>runtime</tt> is 0, or a run-time
+ value (if <tt>runtime</tt> &gt; 0 and an expression could be generated).</p>
</div>
<!-- _______________________________________________________________________ -->
View
3 include/llvm/Intrinsics.td
@@ -268,7 +268,8 @@ def int_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>;
def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>;
// Internal interface for object size checking
-def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i1_ty],
+def int_objectsize : Intrinsic<[llvm_anyint_ty],
+ [llvm_ptr_ty, llvm_i1_ty, llvm_i32_ty],
[IntrNoMem]>,
GCCBuiltin<"__builtin_object_size">;
View
26 lib/VMCore/AutoUpgrade.cpp
@@ -52,6 +52,20 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
break;
}
+ case 'o': {
+ // FIXME: remove in LLVM 3.3
+ if (Name.startswith("objectsize.") && F->arg_size() == 2) {
+ Type *Tys[] = {F->getReturnType(),
+ F->arg_begin()->getType(),
+ Type::getInt1Ty(F->getContext()),
+ Type::getInt32Ty(F->getContext())};
+ NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::objectsize,
+ Tys);
+ NewFn->takeName(F);
+ return true;
+ }
+ break;
+ }
case 'x': {
if (Name.startswith("x86.sse2.pcmpeq.") ||
Name.startswith("x86.sse2.pcmpgt.") ||
@@ -195,7 +209,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
llvm_unreachable("Unknown function for CallInst upgrade.");
case Intrinsic::ctlz:
- case Intrinsic::cttz:
+ case Intrinsic::cttz: {
assert(CI->getNumArgOperands() == 1 &&
"Mismatch between function args and call args");
StringRef Name = CI->getName();
@@ -205,6 +219,16 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
CI->eraseFromParent();
return;
}
+ case Intrinsic::objectsize: {
+ StringRef Name = CI->getName();
+ CI->setName(Name + ".old");
+ CI->replaceAllUsesWith(Builder.CreateCall3(NewFn, CI->getArgOperand(0),
+ CI->getArgOperand(1),
+ Builder.getInt32(0), Name));
+ CI->eraseFromParent();
+ return;
+ }
+ }
}
// This tests each Function to determine if it needs upgrading. When we find
View
4 test/CodeGen/ARM/divmod.ll
@@ -43,7 +43,7 @@ bb:
%3 = load i32* @tabsize, align 4
%4 = srem i32 %cols, %3
%5 = sdiv i32 %cols, %3
- %6 = tail call i32 @llvm.objectsize.i32(i8* null, i1 false)
+ %6 = tail call i32 @llvm.objectsize.i32(i8* null, i1 false, i32 0)
%7 = tail call i8* @__memset_chk(i8* null, i32 9, i32 %5, i32 %6) nounwind
br label %bb1
@@ -54,5 +54,5 @@ bb1:
ret void
}
-declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readnone
+declare i32 @llvm.objectsize.i32(i8*, i1, i32) nounwind readnone
declare i8* @__memset_chk(i8*, i32, i32, i32) nounwind
View
4 test/CodeGen/Generic/crash.ll
@@ -23,7 +23,7 @@ bb32: ; preds = %bb6
%3 = load double* %1, align 4
%4 = load double* %0, align 4
call void @Parse_Vector(double* %0) nounwind
-%5 = call i32 @llvm.objectsize.i32(i8* undef, i1 false)
+%5 = call i32 @llvm.objectsize.i32(i8* undef, i1 false, i32 0)
%6 = icmp eq i32 %5, -1
br i1 %6, label %bb34, label %bb33
@@ -36,7 +36,7 @@ unreachable
}
declare void @Parse_Vector(double*)
-declare i32 @llvm.objectsize.i32(i8*, i1)
+declare i32 @llvm.objectsize.i32(i8*, i1, i32)
; PR9578
View
16 test/CodeGen/Generic/objectsize-upgrade.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -verify -S | FileCheck %s
+; check automatic upgrade of objectsize. To be removed in LLVM 3.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"
+
+define i32 @foo() nounwind {
+; CHECK: @foo
+ %1 = alloca i8, align 4
+ %2 = getelementptr inbounds i8* %1, i32 0
+; CHECK: llvm.objectsize.i32(i8* %2, i1 false, i32 0)
+ %3 = call i32 @llvm.objectsize.i32(i8* %2, i1 0)
+ ret i32 %3
+}
+
+; CHECK: @llvm.objectsize.i32(i8*, i1, i32)
+declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
View
6 test/CodeGen/X86/2011-05-26-UnreachableBlockElim.ll
@@ -8,7 +8,7 @@ target triple = "x86_64-apple-macosx10.6.0"
@aux_temp = external global %struct.dfa, align 8
-declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone
+declare i64 @llvm.objectsize.i64(i8*, i1, i32) nounwind readnone
declare void @__memset_chk() nounwind
@@ -21,12 +21,12 @@ if.end.i: ; preds = %entry
br i1 undef, label %land.end.thread.i, label %land.end.i
land.end.thread.i: ; preds = %if.end.i
- %0 = call i64 @llvm.objectsize.i64(i8* undef, i1 false) nounwind
+ %0 = call i64 @llvm.objectsize.i64(i8* undef, i1 false, i32 0) nounwind
%cmp1710.i = icmp eq i64 %0, -1
br i1 %cmp1710.i, label %cond.false156.i, label %cond.true138.i
land.end.i: ; preds = %if.end.i
- %1 = call i64 @llvm.objectsize.i64(i8* undef, i1 false) nounwind
+ %1 = call i64 @llvm.objectsize.i64(i8* undef, i1 false, i32 0) nounwind
%cmp17.i = icmp eq i64 %1, -1
br i1 %cmp17.i, label %cond.false156.i, label %cond.true138.i
View
4 test/CodeGen/X86/crash.ll
@@ -203,7 +203,7 @@ entry:
; <rdar://problem/9187792>
define fastcc void @func_61() nounwind sspreq {
entry:
- %t1 = tail call i64 @llvm.objectsize.i64(i8* undef, i1 false)
+ %t1 = tail call i64 @llvm.objectsize.i64(i8* undef, i1 false, i32 0)
%t2 = icmp eq i64 %t1, -1
br i1 %t2, label %bb2, label %bb1
@@ -214,7 +214,7 @@ bb2:
ret void
}
-declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone
+declare i64 @llvm.objectsize.i64(i8*, i1, i32) nounwind readnone
; PR10277
; This test has dead code elimination caused by remat during spilling.
View
8 test/CodeGen/X86/object-size.ll
@@ -10,7 +10,7 @@ target triple = "x86_64-apple-darwin10.0"
define void @bar() nounwind ssp {
entry:
%tmp = load i8** @p ; <i8*> [#uses=1]
- %0 = call i64 @llvm.objectsize.i64(i8* %tmp, i1 0) ; <i64> [#uses=1]
+ %0 = call i64 @llvm.objectsize.i64(i8* %tmp, i1 0, i32 0) ; <i64> [#uses=1]
%cmp = icmp ne i64 %0, -1 ; <i1> [#uses=1]
; X64: movabsq $-1, [[RAX:%r..]]
; X64: cmpq $-1, [[RAX]]
@@ -19,7 +19,7 @@ entry:
cond.true: ; preds = %entry
%tmp1 = load i8** @p ; <i8*> [#uses=1]
%tmp2 = load i8** @p ; <i8*> [#uses=1]
- %1 = call i64 @llvm.objectsize.i64(i8* %tmp2, i1 1) ; <i64> [#uses=1]
+ %1 = call i64 @llvm.objectsize.i64(i8* %tmp2, i1 1, i32 0) ; <i64> [#uses=1]
%call = call i8* @__strcpy_chk(i8* %tmp1, i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i64 %1) ssp ; <i8*> [#uses=1]
br label %cond.end
@@ -33,7 +33,7 @@ cond.end: ; preds = %cond.false, %cond.t
ret void
}
-declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readonly
+declare i64 @llvm.objectsize.i64(i8*, i1, i32) nounwind readonly
declare i8* @__strcpy_chk(i8*, i8*, i64) ssp
@@ -47,7 +47,7 @@ entry:
%tmp = load i8** %__dest.addr ; <i8*> [#uses=1]
%tmp1 = load i8** %__src.addr ; <i8*> [#uses=1]
%tmp2 = load i8** %__dest.addr ; <i8*> [#uses=1]
- %0 = call i64 @llvm.objectsize.i64(i8* %tmp2, i1 1) ; <i64> [#uses=1]
+ %0 = call i64 @llvm.objectsize.i64(i8* %tmp2, i1 1, i32 0) ; <i64> [#uses=1]
%call = call i8* @__strcpy_chk(i8* %tmp, i8* %tmp1, i64 %0) ssp ; <i8*> [#uses=1]
store i8* %call, i8** %retval
%1 = load i8** %retval ; <i8*> [#uses=1]
View
4 test/CodeGen/X86/unreachable-stack-protector.ll
@@ -2,13 +2,13 @@
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"
target triple = "x86_64-apple-darwin10.0.0"
-declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone
+declare i64 @llvm.objectsize.i64(i8*, i1, i32) nounwind readnone
define void @test5() nounwind optsize noinline ssp {
entry:
; CHECK: movq ___stack_chk_guard@GOTPCREL(%rip)
%buf = alloca [64 x i8], align 16
- %0 = call i64 @llvm.objectsize.i64(i8* undef, i1 false)
+ %0 = call i64 @llvm.objectsize.i64(i8* undef, i1 false, i32 0)
br i1 false, label %if.end, label %if.then
if.then: ; preds = %entry
View
4 test/Transforms/InstCombine/debuginfo.ll
@@ -2,7 +2,7 @@
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
-declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone
+declare i64 @llvm.objectsize.i64(i8*, i1, i32) nounwind readnone
declare i8* @foo(i8*, i32, i64, i64) nounwind
@@ -23,7 +23,7 @@ entry:
%tmp1 = load i32* %__val.addr, align 4, !dbg !21, !tbaa !17
%tmp2 = load i64* %__len.addr, align 8, !dbg !21, !tbaa !19
%tmp3 = load i8** %__dest.addr, align 8, !dbg !21, !tbaa !13
- %0 = call i64 @llvm.objectsize.i64(i8* %tmp3, i1 false), !dbg !21
+ %0 = call i64 @llvm.objectsize.i64(i8* %tmp3, i1 false, i32 0), !dbg !21
%call = call i8* @foo(i8* %tmp, i32 %tmp1, i64 %tmp2, i64 %0), !dbg !21
ret i8* %call, !dbg !21
}
View
28 test/Transforms/InstCombine/objsize.ll
@@ -9,15 +9,15 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
define i32 @foo() nounwind {
; CHECK: @foo
; CHECK-NEXT: ret i32 60
- %1 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
+ %1 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false, i32 0)
ret i32 %1
}
define i8* @bar() nounwind {
; CHECK: @bar
entry:
%retval = alloca i8*
- %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
+ %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false, i32 0)
%cmp = icmp ne i32 %0, -1
; CHECK: br i1 true
br i1 %cmp, label %cond.true, label %cond.false
@@ -34,7 +34,7 @@ cond.false:
define i32 @f() nounwind {
; CHECK: @f
; CHECK-NEXT: ret i32 0
- %1 = call i32 @llvm.objectsize.i32(i8* getelementptr ([60 x i8]* @a, i32 1, i32 0), i1 false)
+ %1 = call i32 @llvm.objectsize.i32(i8* getelementptr ([60 x i8]* @a, i32 1, i32 0), i1 false, i32 0)
ret i32 %1
}
@@ -43,7 +43,7 @@ define i32 @f() nounwind {
define i1 @baz() nounwind {
; CHECK: @baz
; CHECK-NEXT: ret i1 true
- %1 = tail call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 0), i1 false)
+ %1 = tail call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 0), i1 false, i32 0)
%2 = icmp eq i32 %1, -1
ret i1 %2
}
@@ -52,7 +52,7 @@ define void @test1(i8* %q, i32 %x) nounwind noinline {
; CHECK: @test1
; CHECK: objectsize.i32
entry:
- %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 10), i1 false) ; <i64> [#uses=1]
+ %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([0 x i8]* @window, i32 0, i32 10), i1 false, i32 0) ; <i64> [#uses=1]
%1 = icmp eq i32 %0, -1 ; <i1> [#uses=1]
br i1 %1, label %"47", label %"46"
@@ -68,7 +68,7 @@ entry:
define i32 @test2() nounwind {
; CHECK: @test2
; CHECK-NEXT: ret i32 34
- %1 = call i32 @llvm.objectsize.i32(i8* getelementptr (i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false)
+ %1 = call i32 @llvm.objectsize.i32(i8* getelementptr (i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false, i32 0)
ret i32 %1
}
@@ -77,7 +77,7 @@ define i32 @test2() nounwind {
declare i8* @__memcpy_chk(i8*, i8*, i32, i32) nounwind
-declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
+declare i32 @llvm.objectsize.i32(i8*, i1, i32) nounwind readonly
declare i8* @__inline_memcpy_chk(i8*, i8*, i32) nounwind inlinehint
@@ -89,7 +89,7 @@ entry:
bb11:
%0 = getelementptr inbounds float* getelementptr inbounds ([480 x float]* @array, i32 0, i32 128), i32 -127 ; <float*> [#uses=1]
%1 = bitcast float* %0 to i8* ; <i8*> [#uses=1]
- %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false) ; <i32> [#uses=1]
+ %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false, i32 0) ; <i32> [#uses=1]
%3 = call i8* @__memcpy_chk(i8* undef, i8* undef, i32 512, i32 %2) nounwind ; <i8*> [#uses=0]
; CHECK: unreachable
unreachable
@@ -111,7 +111,7 @@ define i32 @test4() nounwind ssp {
entry:
%0 = alloca %struct.data, align 8
%1 = bitcast %struct.data* %0 to i8*
- %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false) nounwind
+ %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false, i32 0) nounwind
; CHECK-NOT: @llvm.objectsize
; CHECK: @llvm.memset.p0i8.i32(i8* %1, i8 0, i32 1824, i32 8, i1 false)
%3 = call i8* @__memset_chk(i8* %1, i32 0, i32 1824, i32 %2) nounwind
@@ -125,7 +125,7 @@ define void @test5(i32 %n) nounwind ssp {
; CHECK: @test5
entry:
%0 = tail call noalias i8* @malloc(i32 20) nounwind
- %1 = tail call i32 @llvm.objectsize.i32(i8* %0, i1 false)
+ %1 = tail call i32 @llvm.objectsize.i32(i8* %0, i1 false, i32 0)
%2 = load i8** @s, align 8
; CHECK-NOT: @llvm.objectsize
; CHECK: @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 10, i32 1, i1 false)
@@ -137,7 +137,7 @@ define void @test6(i32 %n) nounwind ssp {
; CHECK: @test6
entry:
%0 = tail call noalias i8* @malloc(i32 20) nounwind
- %1 = tail call i32 @llvm.objectsize.i32(i8* %0, i1 false)
+ %1 = tail call i32 @llvm.objectsize.i32(i8* %0, i1 false, i32 0)
%2 = load i8** @s, align 8
; CHECK-NOT: @llvm.objectsize
; CHECK: @__memcpy_chk(i8* %0, i8* %1, i32 30, i32 20)
@@ -153,7 +153,7 @@ define i32 @test7() {
; CHECK: @test7
%alloc = call noalias i8* @malloc(i32 48) nounwind
%gep = getelementptr inbounds i8* %alloc, i32 16
- %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false) nounwind readonly
+ %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false, i32 0) nounwind readonly
; CHECK-NEXT: ret i32 32
ret i32 %objsize
}
@@ -164,7 +164,7 @@ define i32 @test8() {
; CHECK: @test8
%alloc = call noalias i8* @calloc(i32 5, i32 7) nounwind
%gep = getelementptr inbounds i8* %alloc, i32 5
- %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false) nounwind readonly
+ %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 false, i32 0) nounwind readonly
; CHECK-NEXT: ret i32 30
ret i32 %objsize
}
@@ -174,7 +174,7 @@ define i32 @test9() {
; CHECK: @test9
%alloc = call noalias i8* @calloc(i32 100000000, i32 100000000) nounwind
%gep = getelementptr inbounds i8* %alloc, i32 2
- %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 true) nounwind readonly
+ %objsize = call i32 @llvm.objectsize.i32(i8* %gep, i1 true, i32 0) nounwind readonly
; CHECK-NEXT: ret i32 0
ret i32 %objsize
}
View
4 test/Transforms/SimplifyLibCalls/StrCpy.ll
@@ -11,7 +11,7 @@ declare i8* @strcpy(i8*, i8*)
declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind
-declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
+declare i32 @llvm.objectsize.i32(i8*, i1, i32) nounwind readonly
; rdar://6839935
@@ -30,7 +30,7 @@ define i32 @t2() {
%target = alloca [1024 x i8]
%arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0
%arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0
- %tmp1 = call i32 @llvm.objectsize.i32(i8* %arg1, i1 false)
+ %tmp1 = call i32 @llvm.objectsize.i32(i8* %arg1, i1 false, i32 0)
%rslt1 = call i8* @__strcpy_chk(i8* %arg1, i8* %arg2, i32 %tmp1)
; CHECK: @__memcpy_chk
ret i32 0

0 comments on commit 3075954

Please sign in to comment.