summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp3
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp3
-rw-r--r--clang/test/CodeGen/alloc-size.c2
-rw-r--r--clang/test/CodeGen/catch-undef-behavior.c2
-rw-r--r--clang/test/CodeGen/object-size.c110
-rw-r--r--clang/test/CodeGen/object-size.cpp14
-rw-r--r--llvm/docs/LangRef.rst38
-rw-r--r--llvm/include/llvm/Analysis/MemoryBuiltins.h27
-rw-r--r--llvm/include/llvm/IR/Intrinsics.td3
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp51
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp2
-rw-r--r--llvm/lib/IR/AutoUpgrade.cpp4
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp3
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp5
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp4
-rw-r--r--llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp5
-rw-r--r--llvm/test/Assembler/auto_upgrade_intrinsics.ll5
-rw-r--r--llvm/test/CodeGen/AMDGPU/promote-alloca-mem-intrinsics.ll6
-rw-r--r--llvm/test/CodeGen/X86/is-constant.ll4
-rw-r--r--llvm/test/Other/cgscc-libcall-update.ll4
-rw-r--r--llvm/test/Transforms/CodeGenPrepare/basic.ll18
-rw-r--r--llvm/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll4
-rw-r--r--llvm/test/Transforms/InferAddressSpaces/AMDGPU/intrinsics.ll12
-rw-r--r--llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll83
-rw-r--r--llvm/test/Transforms/InstCombine/invoke.ll2
-rw-r--r--llvm/test/Transforms/InstCombine/memset_chk-1.ll8
-rw-r--r--llvm/test/Transforms/InstCombine/objsize.ll58
-rw-r--r--llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll8
-rw-r--r--llvm/test/Transforms/InstCombine/strcpy_chk-1.ll10
29 files changed, 302 insertions, 196 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index ce109bc0d4e..f1014b61831 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -549,7 +549,8 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
Value *Min = Builder.getInt1((Type & 2) != 0);
// For GCC compatibility, __builtin_object_size treat NULL as unknown size.
Value *NullIsUnknown = Builder.getTrue();
- return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown});
+ Value *Dynamic = Builder.getFalse();
+ return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic});
}
namespace {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index be30e8215ad..4bd454411a2 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -727,9 +727,10 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
llvm::Value *Min = Builder.getFalse();
llvm::Value *NullIsUnknown = Builder.getFalse();
+ llvm::Value *Dynamic = Builder.getFalse();
llvm::Value *CastAddr = Builder.CreateBitCast(Ptr, Int8PtrTy);
llvm::Value *LargeEnough = Builder.CreateICmpUGE(
- Builder.CreateCall(F, {CastAddr, Min, NullIsUnknown}), Size);
+ Builder.CreateCall(F, {CastAddr, Min, NullIsUnknown, Dynamic}), Size);
Checks.push_back(std::make_pair(LargeEnough, SanitizerKind::ObjectSize));
}
}
diff --git a/clang/test/CodeGen/alloc-size.c b/clang/test/CodeGen/alloc-size.c
index 1c98b6874da..7953d02923b 100644
--- a/clang/test/CodeGen/alloc-size.c
+++ b/clang/test/CodeGen/alloc-size.c
@@ -231,7 +231,7 @@ void test7() {
void test8() {
// Non-const pointers aren't currently supported.
void *buf = my_calloc(100, 5);
- // CHECK: @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
gi = __builtin_object_size(buf, 0);
// CHECK: @llvm.objectsize
gi = __builtin_object_size(buf, 1);
diff --git a/clang/test/CodeGen/catch-undef-behavior.c b/clang/test/CodeGen/catch-undef-behavior.c
index 7915ed9db1c..e4861aef525 100644
--- a/clang/test/CodeGen/catch-undef-behavior.c
+++ b/clang/test/CodeGen/catch-undef-behavior.c
@@ -35,7 +35,7 @@ void foo() {
union { int i; } u;
// CHECK-COMMON: %[[I8PTR:.*]] = bitcast i32* %[[PTR:.*]] to i8*
- // CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i1 false, i1 false)
+ // CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i1 false, i1 false, i1 false)
// CHECK-COMMON-NEXT: %[[OK:.*]] = icmp uge i64 %[[SIZE]], 4
// CHECK-UBSAN: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize
diff --git a/clang/test/CodeGen/object-size.c b/clang/test/CodeGen/object-size.c
index a1095798c16..9014e04cc52 100644
--- a/clang/test/CodeGen/object-size.c
+++ b/clang/test/CodeGen/object-size.c
@@ -40,7 +40,7 @@ void test4() {
// CHECK-LABEL: define void @test5
void test5() {
// CHECK: = load i8*, i8** @gp
- // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
strcpy(gp, "Hi there");
}
@@ -254,31 +254,31 @@ struct Test23Ty { int a; int t[10]; };
// CHECK-LABEL: @test23
void test23(struct Test23Ty *p) {
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(p, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(p, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(p, 2);
// Note: this is currently fixed at 0 because LLVM doesn't have sufficient
// data to correctly handle type=3
// CHECK: store i32 0
gi = __builtin_object_size(p, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(&p->a, 0);
// CHECK: store i32 4
gi = __builtin_object_size(&p->a, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(&p->a, 2);
// CHECK: store i32 4
gi = __builtin_object_size(&p->a, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(&p->t[5], 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(&p->t[5], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(&p->t[5], 2);
// CHECK: store i32 20
gi = __builtin_object_size(&p->t[5], 3);
@@ -287,11 +287,11 @@ void test23(struct Test23Ty *p) {
// PR24493 -- ICE if __builtin_object_size called with NULL and (Type & 1) != 0
// CHECK-LABEL: @test24
void test24() {
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size((void*)0, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size((void*)0, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size((void*)0, 2);
// Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
// Hopefully will be lowered properly in the future.
@@ -301,22 +301,22 @@ void test24() {
// CHECK-LABEL: @test25
void test25() {
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size((void*)0x1000, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size((void*)0x1000, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size((void*)0x1000, 2);
// Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
// Hopefully will be lowered properly in the future.
// CHECK: store i32 0
gi = __builtin_object_size((void*)0x1000, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size((void*)0 + 0x1000, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size((void*)0 + 0x1000, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size((void*)0 + 0x1000, 2);
// Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
// Hopefully will be lowered properly in the future.
@@ -342,22 +342,22 @@ struct Test27IncompleteTy;
// CHECK-LABEL: @test27
void test27(struct Test27IncompleteTy *t) {
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(t, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(t, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(t, 2);
// Note: this is currently fixed at 0 because LLVM doesn't have sufficient
// data to correctly handle type=3
// CHECK: store i32 0
gi = __builtin_object_size(t, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(&test27, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(&test27, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(&test27, 2);
// Note: this is currently fixed at 0 because LLVM doesn't have sufficient
// data to correctly handle type=3
@@ -415,38 +415,38 @@ struct StaticStruct {
// CHECK-LABEL: @test29
void test29(struct DynStructVar *dv, struct DynStruct0 *d0,
struct DynStruct1 *d1, struct StaticStruct *ss) {
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(dv->snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(dv->snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(dv->snd, 2);
// CHECK: store i32 0
gi = __builtin_object_size(dv->snd, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(d0->snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(d0->snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(d0->snd, 2);
// CHECK: store i32 0
gi = __builtin_object_size(d0->snd, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(d1->snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(d1->snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(d1->snd, 2);
// CHECK: store i32 1
gi = __builtin_object_size(d1->snd, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(ss->snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(ss->snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(ss->snd, 2);
// CHECK: store i32 2
gi = __builtin_object_size(ss->snd, 3);
@@ -456,39 +456,39 @@ void test29(struct DynStructVar *dv, struct DynStruct0 *d0,
void test30() {
struct { struct DynStruct1 fst, snd; } *nested;
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(nested->fst.snd, 0);
// CHECK: store i32 1
gi = __builtin_object_size(nested->fst.snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(nested->fst.snd, 2);
// CHECK: store i32 1
gi = __builtin_object_size(nested->fst.snd, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(nested->snd.snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(nested->snd.snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(nested->snd.snd, 2);
// CHECK: store i32 1
gi = __builtin_object_size(nested->snd.snd, 3);
union { struct DynStruct1 d1; char c[1]; } *u;
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(u->c, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(u->c, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(u->c, 2);
// CHECK: store i32 1
gi = __builtin_object_size(u->c, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(u->d1.snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(u->d1.snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(u->d1.snd, 2);
// CHECK: store i32 1
gi = __builtin_object_size(u->d1.snd, 3);
@@ -502,19 +502,19 @@ void test31() {
struct DynStruct1 *ds1;
struct StaticStruct *ss;
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(ds1[9].snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(&ss[9].snd[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(&ds1[9].snd[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(&ds0[9].snd[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(&dsv[9].snd[0], 1);
}
@@ -527,11 +527,11 @@ void PR30346() {
};
struct sockaddr *sa;
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(sa->sa_data, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
gi = __builtin_object_size(sa->sa_data, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
gi = __builtin_object_size(sa->sa_data, 2);
// CHECK: store i32 14
gi = __builtin_object_size(sa->sa_data, 3);
diff --git a/clang/test/CodeGen/object-size.cpp b/clang/test/CodeGen/object-size.cpp
index 725c49214dd..3c8390f5f09 100644
--- a/clang/test/CodeGen/object-size.cpp
+++ b/clang/test/CodeGen/object-size.cpp
@@ -35,29 +35,29 @@ void test2() {
struct B : A {};
struct C { int i; B bs[1]; } *c;
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
gi = __builtin_object_size(&c->bs[0], 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
gi = __builtin_object_size(&c->bs[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1 false)
gi = __builtin_object_size(&c->bs[0], 2);
// CHECK: store i32 16
gi = __builtin_object_size(&c->bs[0], 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
gi = __builtin_object_size((A*)&c->bs[0], 0);
// CHECK: store i32 16
gi = __builtin_object_size((A*)&c->bs[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1 false)
gi = __builtin_object_size((A*)&c->bs[0], 2);
// CHECK: store i32 16
gi = __builtin_object_size((A*)&c->bs[0], 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
gi = __builtin_object_size(&c->bs[0].buf[0], 0);
// CHECK: store i32 16
gi = __builtin_object_size(&c->bs[0].buf[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1 false)
gi = __builtin_object_size(&c->bs[0].buf[0], 2);
// CHECK: store i32 16
gi = __builtin_object_size(&c->bs[0].buf[0], 3);
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 27f5e0cbec7..85c04f16822 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -15575,40 +15575,40 @@ Syntax:
::
- declare i32 @llvm.objectsize.i32(i8* <object>, i1 <min>, i1 <nullunknown>)
- declare i64 @llvm.objectsize.i64(i8* <object>, i1 <min>, i1 <nullunknown>)
+ declare i32 @llvm.objectsize.i32(i8* <object>, i1 <min>, i1 <nullunknown>, i1 <dynamic>)
+ declare i64 @llvm.objectsize.i64(i8* <object>, i1 <min>, i1 <nullunknown>, i1 <dynamic>)
Overview:
"""""""""
-The ``llvm.objectsize`` intrinsic is designed to provide information to
-the optimizers to determine at compile time whether a) an operation
-(like memcpy) will overflow a buffer that corresponds to an object, or
-b) that a runtime check for overflow isn't necessary. An object in this
-context means an allocation of a specific class, structure, array, or
-other object.
+The ``llvm.objectsize`` intrinsic is designed to provide information to the
+optimizer to determine whether a) an operation (like memcpy) will overflow a
+buffer that corresponds to an object, or b) that a runtime check for overflow
+isn't necessary. An object in this context means an allocation of a specific
+class, structure, array, or other object.
Arguments:
""""""""""
-The ``llvm.objectsize`` intrinsic takes three arguments. The first argument is
-a pointer to or into the ``object``. The second argument determines whether
-``llvm.objectsize`` returns 0 (if true) or -1 (if false) when the object size
-is unknown. The third argument controls how ``llvm.objectsize`` acts when
-``null`` in address space 0 is used as its pointer argument. If it's ``false``,
+The ``llvm.objectsize`` intrinsic takes four arguments. The first argument is a
+pointer to or into the ``object``. The second argument determines whether
+``llvm.objectsize`` returns 0 (if true) or -1 (if false) when the object size is
+unknown. The third argument controls how ``llvm.objectsize`` acts when ``null``
+in address space 0 is used as its pointer argument. If it's ``false``,
``llvm.objectsize`` reports 0 bytes available when given ``null``. Otherwise, if
the ``null`` is in a non-zero address space or if ``true`` is given for the
-third argument of ``llvm.objectsize``, we assume its size is unknown.
+third argument of ``llvm.objectsize``, we assume its size is unknown. The fourth
+argument to ``llvm.objectsize`` determines if the value should be evaluated at
+runtime.
-The second and third arguments only accept constants.
+The second, third, and fourth arguments only accept constants.
Semantics:
""""""""""
-The ``llvm.objectsize`` intrinsic is lowered to a constant representing
-the size of the object concerned. If the size cannot be determined at
-compile time, ``llvm.objectsize`` returns ``i32/i64 -1 or 0`` (depending
-on the ``min`` argument).
+The ``llvm.objectsize`` intrinsic is lowered to a value representing the size of
+the object concerned. If the size cannot be determined, ``llvm.objectsize``
+returns ``i32/i64 -1 or 0`` (depending on the ``min`` argument).
'``llvm.expect``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h
index eb88717edbd..49b87a43a48 100644
--- a/llvm/include/llvm/Analysis/MemoryBuiltins.h
+++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h
@@ -177,14 +177,13 @@ bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
const TargetLibraryInfo *TLI, ObjectSizeOpts Opts = {});
/// Try to turn a call to \@llvm.objectsize into an integer value of the given
-/// Type. Returns null on failure.
-/// If MustSucceed is true, this function will not return null, and may return
-/// conservative values governed by the second argument of the call to
-/// objectsize.
-ConstantInt *lowerObjectSizeCall(IntrinsicInst *ObjectSize,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI,
- bool MustSucceed);
+/// Type. Returns null on failure. If MustSucceed is true, this function will
+/// not return null, and may return conservative values governed by the second
+/// argument of the call to objectsize.
+Value *lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL,
+ const TargetLibraryInfo *TLI, bool MustSucceed);
+
+
using SizeOffsetType = std::pair<APInt, APInt>;
@@ -264,17 +263,17 @@ class ObjectSizeOffsetEvaluator
Value *Zero;
CacheMapTy CacheMap;
PtrSetTy SeenVals;
- bool RoundToAlign;
-
- SizeOffsetEvalType unknown() {
- return std::make_pair(nullptr, nullptr);
- }
+ ObjectSizeOpts EvalOpts;
SizeOffsetEvalType compute_(Value *V);
public:
+ static SizeOffsetEvalType unknown() {
+ return std::make_pair(nullptr, nullptr);
+ }
+
ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI,
- LLVMContext &Context, bool RoundToAlign = false);
+ LLVMContext &Context, ObjectSizeOpts EvalOpts = {});
SizeOffsetEvalType compute(Value *V);
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 5f256275b87..f15c5955967 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -558,7 +558,8 @@ def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>;
// Internal interface for object size checking
def int_objectsize : Intrinsic<[llvm_anyint_ty],
- [llvm_anyptr_ty, llvm_i1_ty, llvm_i1_ty],
+ [llvm_anyptr_ty, llvm_i1_ty,
+ llvm_i1_ty, llvm_i1_ty],
[IntrNoMem, IntrSpeculatable]>,
GCCBuiltin<"__builtin_object_size">;
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 64643535f64..56332bb5fe8 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -441,10 +441,10 @@ bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
return true;
}
-ConstantInt *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI,
- bool MustSucceed) {
+Value *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
+ const DataLayout &DL,
+ const TargetLibraryInfo *TLI,
+ bool MustSucceed) {
assert(ObjectSize->getIntrinsicID() == Intrinsic::objectsize &&
"ObjectSize must be a call to llvm.objectsize!");
@@ -461,13 +461,35 @@ ConstantInt *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
EvalOptions.NullIsUnknownSize =
cast<ConstantInt>(ObjectSize->getArgOperand(2))->isOne();
- // FIXME: Does it make sense to just return a failure value if the size won't
- // fit in the output and `!MustSucceed`?
- uint64_t Size;
auto *ResultType = cast<IntegerType>(ObjectSize->getType());
- if (getObjectSize(ObjectSize->getArgOperand(0), Size, DL, TLI, EvalOptions) &&
- isUIntN(ResultType->getBitWidth(), Size))
- return ConstantInt::get(ResultType, Size);
+ bool StaticOnly = cast<ConstantInt>(ObjectSize->getArgOperand(3))->isZero();
+ if (StaticOnly) {
+ // FIXME: Does it make sense to just return a failure value if the size won't
+ // fit in the output and `!MustSucceed`?
+ uint64_t Size;
+ if (getObjectSize(ObjectSize->getArgOperand(0), Size, DL, TLI, EvalOptions) &&
+ isUIntN(ResultType->getBitWidth(), Size))
+ return ConstantInt::get(ResultType, Size);
+ } else {
+ LLVMContext &Ctx = ObjectSize->getFunction()->getContext();
+ ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, EvalOptions);
+ SizeOffsetEvalType SizeOffsetPair =
+ Eval.compute(ObjectSize->getArgOperand(0));
+
+ if (SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown()) {
+ IRBuilder<TargetFolder> Builder(Ctx, TargetFolder(DL));
+ Builder.SetInsertPoint(ObjectSize);
+
+ // If we've outside the end of the object, then we can always access
+ // exactly 0 bytes.
+ Value *ResultSize =
+ Builder.CreateSub(SizeOffsetPair.first, SizeOffsetPair.second);
+ Value *UseZero =
+ Builder.CreateICmpULT(SizeOffsetPair.first, SizeOffsetPair.second);
+ return Builder.CreateSelect(UseZero, ConstantInt::get(ResultType, 0),
+ ResultSize);
+ }
+ }
if (!MustSucceed)
return nullptr;
@@ -742,9 +764,9 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {
ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(
const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context,
- bool RoundToAlign)
+ ObjectSizeOpts EvalOpts)
: DL(DL), TLI(TLI), Context(Context), Builder(Context, TargetFolder(DL)),
- RoundToAlign(RoundToAlign) {
+ EvalOpts(EvalOpts) {
// IntTy and Zero must be set for each compute() since the address space may
// be different for later objects.
}
@@ -773,10 +795,7 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute(Value *V) {
}
SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
- ObjectSizeOpts ObjSizeOptions;
- ObjSizeOptions.RoundToAlign = RoundToAlign;
-
- ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, ObjSizeOptions);
+ ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, EvalOpts);
SizeOffsetType Const = Visitor.compute(V);
if (Visitor.bothKnown(Const))
return std::make_pair(ConstantInt::get(Context, Const.first),
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 486290d09a4..24c926c01a5 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -1705,7 +1705,7 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool &ModifiedDT) {
default: break;
case Intrinsic::objectsize: {
// Lower all uses of llvm.objectsize.*
- ConstantInt *RetVal =
+ Value *RetVal =
lowerObjectSizeCall(II, *DL, TLInfo, /*MustSucceed=*/true);
resetIteratorIfInvalidatedWhileCalling(BB, [&]() {
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 396a425aef6..aa132fa86d5 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -3459,8 +3459,10 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Value *NullIsUnknownSize = CI->getNumArgOperands() == 2
? Builder.getFalse()
: CI->getArgOperand(2);
+ Value *Dynamic =
+ CI->getNumArgOperands() < 3 ? Builder.getFalse() : CI->getArgOperand(3);
NewCall = Builder.CreateCall(
- NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize});
+ NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize, Dynamic});
break;
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
index cce17d02bef..8bf2b13c654 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
@@ -918,7 +918,8 @@ bool AMDGPUPromoteAlloca::handleAlloca(AllocaInst &I, bool SufficientLDS) {
);
CallInst *NewCall = Builder.CreateCall(
- ObjectSize, {Src, Intr->getOperand(1), Intr->getOperand(2)});
+ ObjectSize,
+ {Src, Intr->getOperand(1), Intr->getOperand(2), Intr->getOperand(3)});
Intr->replaceAllUsesWith(NewCall);
Intr->eraseFromParent();
continue;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index ec4b7635ce3..a705d7ac75f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1894,9 +1894,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
switch (II->getIntrinsicID()) {
default: break;
case Intrinsic::objectsize:
- if (ConstantInt *N =
- lowerObjectSizeCall(II, DL, &TLI, /*MustSucceed=*/false))
- return replaceInstUsesWith(CI, N);
+ if (Value *V = lowerObjectSizeCall(II, DL, &TLI, /*MustSucceed=*/false))
+ return replaceInstUsesWith(CI, V);
return nullptr;
case Intrinsic::bswap: {
Value *IIOperand = II->getArgOperand(0);
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 9a2a3b2dc5d..b30b3eeadcc 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2295,8 +2295,8 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) {
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
if (II->getIntrinsicID() == Intrinsic::objectsize) {
- ConstantInt *Result = lowerObjectSizeCall(II, DL, &TLI,
- /*MustSucceed=*/true);
+ Value *Result =
+ lowerObjectSizeCall(II, DL, &TLI, /*MustSucceed=*/true);
replaceInstUsesWith(*I, Result);
eraseInstFromFunction(*I);
Users[i] = nullptr; // Skip examining in the next loop.
diff --git a/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp b/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
index 547c43c5ddd..4dc9b611c15 100644
--- a/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
+++ b/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
@@ -142,8 +142,9 @@ static void insertBoundsCheck(Value *Or, BuilderTy IRB, GetTrapBBT GetTrapBB) {
static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
ScalarEvolution &SE) {
const DataLayout &DL = F.getParent()->getDataLayout();
- ObjectSizeOffsetEvaluator ObjSizeEval(DL, &TLI, F.getContext(),
- /*RoundToAlign=*/true);
+ ObjectSizeOpts EvalOpts;
+ EvalOpts.RoundToAlign = true;
+ ObjectSizeOffsetEvaluator ObjSizeEval(DL, &TLI, F.getContext(), EvalOpts);
// check HANDLE_MEMORY_INST in include/llvm/Instruction.def for memory
// touching instructions
diff --git a/llvm/test/Assembler/auto_upgrade_intrinsics.ll b/llvm/test/Assembler/auto_upgrade_intrinsics.ll
index 87ad371deaa..bd2a779800a 100644
--- a/llvm/test/Assembler/auto_upgrade_intrinsics.ll
+++ b/llvm/test/Assembler/auto_upgrade_intrinsics.ll
@@ -53,7 +53,7 @@ entry:
define i32 @test.objectsize() {
; CHECK-LABEL: @test.objectsize(
-; CHECK: @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false)
+; 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)
%s = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false)
ret i32 %s
}
@@ -61,12 +61,11 @@ define i32 @test.objectsize() {
declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) nounwind readonly
define i64 @test.objectsize.2() {
; CHECK-LABEL: @test.objectsize.2(
-; CHECK: @llvm.objectsize.i64.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false)
+; 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)
%s = call i64 @llvm.objectsize.i64.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false)
ret i64 %s
}
-
declare <2 x double> @llvm.masked.load.v2f64(<2 x double>* %ptrs, i32, <2 x i1> %mask, <2 x double> %src0)
define <2 x double> @tests.masked.load(<2 x double>* %ptr, <2 x i1> %mask, <2 x double> %passthru) {
diff --git a/llvm/test/CodeGen/AMDGPU/promote-alloca-mem-intrinsics.ll b/llvm/test/CodeGen/AMDGPU/promote-alloca-mem-intrinsics.ll
index fcf64ce8016..4515447b749 100644
--- a/llvm/test/CodeGen/AMDGPU/promote-alloca-mem-intrinsics.ll
+++ b/llvm/test/CodeGen/AMDGPU/promote-alloca-mem-intrinsics.ll
@@ -8,7 +8,7 @@ declare void @llvm.memmove.p1i8.p0i8.i32(i8 addrspace(1)* nocapture, i8* nocaptu
declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) #0
-declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1) #1
+declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) #1
; CHECK-LABEL: @promote_with_memcpy(
; CHECK: getelementptr inbounds [64 x [17 x i32]], [64 x [17 x i32]] addrspace(3)* @promote_with_memcpy.alloca, i32 0, i32 %{{[0-9]+}}
@@ -52,11 +52,11 @@ define amdgpu_kernel void @promote_with_memset(i32 addrspace(1)* %out, i32 addrs
; CHECK-LABEL: @promote_with_objectsize(
; 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]+}}
-; CHECK: call i32 @llvm.objectsize.i32.p3i8(i8 addrspace(3)* %alloca.bc, i1 false, i1 false)
+; CHECK: call i32 @llvm.objectsize.i32.p3i8(i8 addrspace(3)* %alloca.bc, i1 false, i1 false, i1 false)
define amdgpu_kernel void @promote_with_objectsize(i32 addrspace(1)* %out) #0 {
%alloca = alloca [17 x i32], align 4
%alloca.bc = bitcast [17 x i32]* %alloca to i8*
- %size = call i32 @llvm.objectsize.i32.p0i8(i8* %alloca.bc, i1 false, i1 false)
+ %size = call i32 @llvm.objectsize.i32.p0i8(i8* %alloca.bc, i1 false, i1 false, i1 false)
store i32 %size, i32 addrspace(1)* %out
ret void
}
diff --git a/llvm/test/CodeGen/X86/is-constant.ll b/llvm/test/CodeGen/X86/is-constant.ll
index d02bbae2085..b4c1f351a2a 100644
--- a/llvm/test/CodeGen/X86/is-constant.ll
+++ b/llvm/test/CodeGen/X86/is-constant.ll
@@ -15,7 +15,7 @@ target triple = "x86_64-unknown-linux-gnu"
declare i1 @llvm.is.constant.i32(i32 %a) nounwind readnone
declare i1 @llvm.is.constant.i64(i64 %a) nounwind readnone
-declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1) nounwind readnone
+declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1) nounwind readnone
declare i32 @subfun_1()
declare i32 @subfun_2()
@@ -44,7 +44,7 @@ define i1 @test_objectsize(i8* %obj) nounwind {
; CHECK-O2: %bb.0:
; CHECK-O2: movb $1, %al
; CHECK-O2-NEXT: retq
- %os = call i64 @llvm.objectsize.i64.p0i8(i8* %obj, i1 false, i1 false)
+ %os = call i64 @llvm.objectsize.i64.p0i8(i8* %obj, i1 false, i1 false, i1 false)
%v = call i1 @llvm.is.constant.i64(i64 %os)
ret i1 %v
}
diff --git a/llvm/test/Other/cgscc-libcall-update.ll b/llvm/test/Other/cgscc-libcall-update.ll
index 1bf482af795..5aa61df6a57 100644
--- a/llvm/test/Other/cgscc-libcall-update.ll
+++ b/llvm/test/Other/cgscc-libcall-update.ll
@@ -15,7 +15,7 @@ bb:
%tmp2 = getelementptr inbounds [1024 x i8], [1024 x i8]* %tmp, i64 0, i64 0
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp2, i8* %arg1, i64 1024, i1 false)
; CHECK: call void @llvm.memcpy
- %tmp3 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp2, i1 false, i1 true)
+ %tmp3 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp2, i1 false, i1 true, i1 false)
%tmp4 = call i8* @__strncpy_chk(i8* %arg2, i8* %tmp2, i64 1023, i64 %tmp3)
; CHECK-NOT: call
; CHECK: call i8* @strncpy(i8* %arg2, i8* nonnull %tmp2, i64 1023)
@@ -33,7 +33,7 @@ bb:
declare i8* @my_special_strncpy(i8* %arg1, i8* %arg2, i64 %size)
-declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1)
+declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1)
declare i8* @__strncpy_chk(i8*, i8*, i64, i64)
diff --git a/llvm/test/Transforms/CodeGenPrepare/basic.ll b/llvm/test/Transforms/CodeGenPrepare/basic.ll
index 768209abcdf..1a58d61b6e9 100644
--- a/llvm/test/Transforms/CodeGenPrepare/basic.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/basic.ll
@@ -9,7 +9,7 @@ target triple = "x86_64-apple-darwin10.0.0"
; rdar://8785296
define i32 @test1(i8* %ptr) nounwind ssp noredzone align 2 {
entry:
- %0 = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false, i1 false)
+ %0 = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false, i1 false, i1 false)
%1 = icmp ugt i64 %0, 3
br i1 %1, label %T, label %trap
@@ -29,7 +29,7 @@ T:
define i64 @test_objectsize_null_flag(i8* %ptr) {
entry:
; CHECK: ret i64 -1
- %0 = tail call i64 @llvm.objectsize.i64(i8* null, i1 false, i1 true)
+ %0 = tail call i64 @llvm.objectsize.i64(i8* null, i1 false, i1 true, i1 false)
ret i64 %0
}
@@ -37,7 +37,7 @@ entry:
define i64 @test_objectsize_null_flag_min(i8* %ptr) {
entry:
; CHECK: ret i64 0
- %0 = tail call i64 @llvm.objectsize.i64(i8* null, i1 true, i1 true)
+ %0 = tail call i64 @llvm.objectsize.i64(i8* null, i1 true, i1 true, i1 false)
ret i64 %0
}
@@ -48,7 +48,7 @@ define i64 @test_objectsize_null_flag_noas0() {
entry:
; CHECK: ret i64 -1
%0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 false,
- i1 true)
+ i1 true, i1 false)
ret i64 %0
}
@@ -57,7 +57,7 @@ define i64 @test_objectsize_null_flag_min_noas0() {
entry:
; CHECK: ret i64 0
%0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 true,
- i1 true)
+ i1 true, i1 false)
ret i64 %0
}
@@ -66,7 +66,7 @@ define i64 @test_objectsize_null_known_flag_noas0() {
entry:
; CHECK: ret i64 -1
%0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 false,
- i1 false)
+ i1 false, i1 false)
ret i64 %0
}
@@ -75,12 +75,12 @@ define i64 @test_objectsize_null_known_flag_min_noas0() {
entry:
; CHECK: ret i64 0
%0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 true,
- i1 false)
+ i1 false, i1 false)
ret i64 %0
}
-declare i64 @llvm.objectsize.i64(i8*, i1, i1) nounwind readonly
-declare i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)*, i1, i1) nounwind readonly
+declare i64 @llvm.objectsize.i64(i8*, i1, i1, i1) nounwind readonly
+declare i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)*, i1, i1, i1) nounwind readonly
declare void @llvm.trap() nounwind
diff --git a/llvm/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll b/llvm/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll
index 3808c0e61c1..5049207ec27 100644
--- a/llvm/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/crash-on-large-allocas.ll
@@ -8,9 +8,9 @@ target datalayout = "p:16:16"
; CHECK-LABEL: @alloca_overflow_is_unknown(
define i16 @alloca_overflow_is_unknown() {
%i = alloca i8, i32 65537
- %j = call i16 @llvm.objectsize.i16.p0i8(i8* %i, i1 false, i1 false)
+ %j = call i16 @llvm.objectsize.i16.p0i8(i8* %i, i1 false, i1 false, i1 false)
; CHECK: ret i16 -1
ret i16 %j
}
-declare i16 @llvm.objectsize.i16.p0i8(i8*, i1, i1)
+declare i16 @llvm.objectsize.i16.p0i8(i8*, i1, i1, i1)
diff --git a/llvm/test/Transforms/InferAddressSpaces/AMDGPU/intrinsics.ll b/llvm/test/Transforms/InferAddressSpaces/AMDGPU/intrinsics.ll
index 723ce41588a..166e90ab7b6 100644
--- a/llvm/test/Transforms/InferAddressSpaces/AMDGPU/intrinsics.ll
+++ b/llvm/test/Transforms/InferAddressSpaces/AMDGPU/intrinsics.ll
@@ -1,18 +1,18 @@
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -infer-address-spaces %s | FileCheck %s
; CHECK-LABEL: @objectsize_group_to_flat_i32(
-; CHECK: %val = call i32 @llvm.objectsize.i32.p3i8(i8 addrspace(3)* %group.ptr, i1 true, i1 false)
+; CHECK: %val = call i32 @llvm.objectsize.i32.p3i8(i8 addrspace(3)* %group.ptr, i1 true, i1 false, i1 false)
define i32 @objectsize_group_to_flat_i32(i8 addrspace(3)* %group.ptr) #0 {
%cast = addrspacecast i8 addrspace(3)* %group.ptr to i8*
- %val = call i32 @llvm.objectsize.i32.p0i8(i8* %cast, i1 true, i1 false)
+ %val = call i32 @llvm.objectsize.i32.p0i8(i8* %cast, i1 true, i1 false, i1 false)
ret i32 %val
}
; CHECK-LABEL: @objectsize_global_to_flat_i64(
-; CHECK: %val = call i64 @llvm.objectsize.i64.p3i8(i8 addrspace(3)* %global.ptr, i1 true, i1 false)
+; CHECK: %val = call i64 @llvm.objectsize.i64.p3i8(i8 addrspace(3)* %global.ptr, i1 true, i1 false, i1 false)
define i64 @objectsize_global_to_flat_i64(i8 addrspace(3)* %global.ptr) #0 {
%cast = addrspacecast i8 addrspace(3)* %global.ptr to i8*
- %val = call i64 @llvm.objectsize.i64.p0i8(i8* %cast, i1 true, i1 false)
+ %val = call i64 @llvm.objectsize.i64.p0i8(i8* %cast, i1 true, i1 false, i1 false)
ret i64 %val
}
@@ -134,8 +134,8 @@ define i64 @invalid_variable_volatile_atomicinc_group_to_flat_i64(i64 addrspace(
ret i64 %ret
}
-declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1) #1
-declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1) #1
+declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) #1
+declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1) #1
declare i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* nocapture, i32, i32, i32, i1) #2
declare i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* nocapture, i64, i32, i32, i1) #2
declare i32 @llvm.amdgcn.atomic.dec.i32.p0i32(i32* nocapture, i32, i32, i32, i1) #2
diff --git a/llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll b/llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll
new file mode 100644
index 00000000000..a0c2d139916
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll
@@ -0,0 +1,83 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s --dump-input-on-failure
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.14.0"
+
+; Function Attrs: nounwind ssp uwtable
+define i64 @weird_identity_but_ok(i64 %sz) {
+entry:
+ %call = tail call i8* @malloc(i64 %sz)
+ %calc_size = tail call i64 @llvm.objectsize.i64.p0i8(i8* %call, i1 false, i1 true, i1 true)
+ tail call void @free(i8* %call)
+ ret i64 %calc_size
+}
+
+; CHECK: define i64 @weird_identity_but_ok(i64 %sz)
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i64 %sz
+; CHECK-NEXT: }
+
+define i64 @phis_are_neat(i1 %which) {
+entry:
+ br i1 %which, label %first_label, label %second_label
+
+first_label:
+ %first_call = call i8* @malloc(i64 10)
+ br label %join_label
+
+second_label:
+ %second_call = call i8* @malloc(i64 30)
+ br label %join_label
+
+join_label:
+ %joined = phi i8* [ %first_call, %first_label ], [ %second_call, %second_label ]
+ %calc_size = tail call i64 @llvm.objectsize.i64.p0i8(i8* %joined, i1 false, i1 true, i1 true)
+ ret i64 %calc_size
+}
+
+; CHECK: %0 = phi i64 [ 10, %first_label ], [ 30, %second_label ]
+; CHECK-NEXT: ret i64 %0
+
+define i64 @internal_pointer(i64 %sz) {
+entry:
+ %ptr = call i8* @malloc(i64 %sz)
+ %ptr2 = getelementptr inbounds i8, i8* %ptr, i32 2
+ %calc_size = call i64 @llvm.objectsize.i64.p0i8(i8* %ptr2, i1 false, i1 true, i1 true)
+ ret i64 %calc_size
+}
+
+; CHECK: define i64 @internal_pointer(i64 %sz)
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %0 = add i64 %sz, -2
+; CHECK-NEXT: %1 = icmp ult i64 %sz, 2
+; CHECK-NEXT: %2 = select i1 %1, i64 0, i64 %0
+; CHECK-NEXT: ret i64 %2
+; CHECK-NEXT: }
+
+define i64 @uses_nullptr_no_fold() {
+entry:
+ %res = call i64 @llvm.objectsize.i64.p0i8(i8* null, i1 false, i1 true, i1 true)
+ ret i64 %res
+}
+
+; CHECK: %res = call i64 @llvm.objectsize.i64.p0i8(i8* null, i1 false, i1 true, i1 true)
+
+define i64 @uses_nullptr_fold() {
+entry:
+ ; NOTE: the third parameter to this call is false, unlike above.
+ %res = call i64 @llvm.objectsize.i64.p0i8(i8* null, i1 false, i1 false, i1 true)
+ ret i64 %res
+}
+
+; CHECK: ret i64 0
+
+; Function Attrs: nounwind allocsize(0)
+declare i8* @malloc(i64)
+
+declare i8* @get_unknown_buffer()
+
+; Function Attrs: nounwind
+declare void @free(i8* nocapture)
+
+; Function Attrs: nounwind readnone speculatable
+declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1)
diff --git a/llvm/test/Transforms/InstCombine/invoke.ll b/llvm/test/Transforms/InstCombine/invoke.ll
index fb54c4f77c4..deb4a2b87a4 100644
--- a/llvm/test/Transforms/InstCombine/invoke.ll
+++ b/llvm/test/Transforms/InstCombine/invoke.ll
@@ -55,7 +55,7 @@ entry:
to label %invoke.cont unwind label %lpad
invoke.cont:
-; CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %call, i1 false, i1 false)
+; CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %call, i1 false, i1 false, i1 false)
%0 = tail call i64 @llvm.objectsize.i64(i8* %call, i1 false)
ret i64 %0
diff --git a/llvm/test/Transforms/InstCombine/memset_chk-1.ll b/llvm/test/Transforms/InstCombine/memset_chk-1.ll
index 7f680ea48b6..71f95b02457 100644
--- a/llvm/test/Transforms/InstCombine/memset_chk-1.ll
+++ b/llvm/test/Transforms/InstCombine/memset_chk-1.ll
@@ -69,7 +69,7 @@ define i32 @test_rauw(i8* %a, i8* %b, i8** %c) {
entry:
%call49 = call i64 @strlen(i8* %a)
%add180 = add i64 %call49, 1
- %yo107 = call i64 @llvm.objectsize.i64.p0i8(i8* %b, i1 false, i1 false)
+ %yo107 = call i64 @llvm.objectsize.i64.p0i8(i8* %b, i1 false, i1 false, i1 false)
%call50 = call i8* @__memmove_chk(i8* %b, i8* %a, i64 %add180, i64 %yo107)
; CHECK: %strlen = call i64 @strlen(i8* %b)
; CHECK-NEXT: %strchr2 = getelementptr i8, i8* %b, i64 %strlen
@@ -87,7 +87,7 @@ entry:
declare i8* @__memmove_chk(i8*, i8*, i64, i64)
declare i8* @strrchr(i8*, i32)
declare i64 @strlen(i8* nocapture)
-declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1)
+declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1)
declare i8* @__memset_chk(i8*, i32, i64, i64)
@@ -100,7 +100,7 @@ entry:
br i1 %cmp, label %cleanup, label %if.end
if.end:
%bc = bitcast i8* %call to float*
- %call2 = tail call i64 @llvm.objectsize.i64.p0i8(i8* nonnull %call, i1 false, i1 false)
+ %call2 = tail call i64 @llvm.objectsize.i64.p0i8(i8* nonnull %call, i1 false, i1 false, i1 false)
%call3 = tail call i8* @__memset_chk(i8* nonnull %call, i32 0, i64 %size, i64 %call2) #1
br label %cleanup
cleanup:
@@ -114,7 +114,7 @@ cleanup:
; CHECK-NEXT: br i1 %cmp, label %cleanup, label %if.end
; CHECK: if.end:
; CHECK-NEXT: %bc = bitcast i8* %call to float*
-; CHECK-NEXT: %call2 = tail call i64 @llvm.objectsize.i64.p0i8(i8* nonnull %call, i1 false, i1 false)
+; CHECK-NEXT: %call2 = tail call i64 @llvm.objectsize.i64.p0i8(i8* nonnull %call, i1 false, i1 false, i1 false)
; CHECK-NEXT: %call3 = tail call i8* @__memset_chk(i8* nonnull %call, i32 0, i64 %size, i64 %call2)
; CHECK-NEXT: br label %cleanup
; CHECK: cleanup:
diff --git a/llvm/test/Transforms/InstCombine/objsize.ll b/llvm/test/Transforms/InstCombine/objsize.ll
index a86f39c508d..97c708fb6bf 100644
--- a/llvm/test/Transforms/InstCombine/objsize.ll
+++ b/llvm/test/Transforms/InstCombine/objsize.ll
@@ -8,7 +8,7 @@ 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-LABEL: @foo(
; CHECK-NEXT: ret i32 60
- %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)
+ %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)
ret i32 %1
}
@@ -16,7 +16,7 @@ define i8* @bar() nounwind {
; CHECK-LABEL: @bar(
entry:
%retval = alloca i8*
- %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)
+ %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)
%cmp = icmp ne i32 %0, -1
; CHECK: br i1 true
br i1 %cmp, label %cond.true, label %cond.false
@@ -33,7 +33,7 @@ cond.false:
define i32 @f() nounwind {
; CHECK-LABEL: @f(
; CHECK-NEXT: ret i32 0
- %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr ([60 x i8], [60 x i8]* @a, i32 1, i32 0), i1 false, i1 false)
+ %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)
ret i32 %1
}
@@ -42,7 +42,7 @@ define i32 @f() nounwind {
define i1 @baz() nounwind {
; CHECK-LABEL: @baz(
; CHECK-NEXT: objectsize
- %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)
+ %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)
%2 = icmp eq i32 %1, -1
ret i1 %2
}
@@ -51,7 +51,7 @@ define void @test1(i8* %q, i32 %x) nounwind noinline {
; CHECK-LABEL: @test1(
; CHECK: objectsize.i32.p0i8
entry:
- %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) ; <i64> [#uses=1]
+ %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) ; <i64> [#uses=1]
%1 = icmp eq i32 %0, -1 ; <i1> [#uses=1]
br i1 %1, label %"47", label %"46"
@@ -67,7 +67,7 @@ entry:
define i32 @test2() nounwind {
; CHECK-LABEL: @test2(
; CHECK-NEXT: ret i32 34
- %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr (i8, i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false, i1 false)
+ %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)
ret i32 %1
}
@@ -76,9 +76,9 @@ define i32 @test2() nounwind {
declare i8* @__memcpy_chk(i8*, i8*, i32, i32) nounwind
-declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1) nounwind readonly
+declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) nounwind readonly
-declare i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)*, i1, i1) nounwind readonly
+declare i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)*, i1, i1, i1) nounwind readonly
declare i8* @__inline_memcpy_chk(i8*, i8*, i32) nounwind inlinehint
@@ -90,7 +90,7 @@ entry:
bb11:
%0 = getelementptr inbounds float, float* getelementptr inbounds ([480 x float], [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.p0i8(i8* %1, i1 false, i1 false) ; <i32> [#uses=1]
+ %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false, i1 false, i1 false) ; <i32> [#uses=1]
%3 = call i8* @__memcpy_chk(i8* undef, i8* undef, i32 512, i32 %2) nounwind ; <i8*> [#uses=0]
; CHECK: unreachable
unreachable
@@ -112,7 +112,7 @@ define i32 @test4(i8** %esc) nounwind ssp {
entry:
%0 = alloca %struct.data, align 8
%1 = bitcast %struct.data* %0 to i8*
- %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false, i1 false) nounwind
+ %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false, i1 false, i1 false) nounwind
; CHECK-NOT: @llvm.objectsize
; CHECK: @llvm.memset.p0i8.i32(i8* nonnull align 8 %1, i8 0, i32 1824, i1 false)
%3 = call i8* @__memset_chk(i8* %1, i32 0, i32 1824, i32 %2) nounwind
@@ -127,7 +127,7 @@ define i8* @test5(i32 %n) nounwind ssp {
; CHECK-LABEL: @test5(
entry:
%0 = tail call noalias i8* @malloc(i32 20) nounwind
- %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false, i1 false)
+ %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false, i1 false, i1 false)
%2 = load i8*, i8** @s, align 8
; CHECK-NOT: @llvm.objectsize
; CHECK: @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %0, i8* align 1 %1, i32 10, i1 false)
@@ -139,7 +139,7 @@ define void @test6(i32 %n) nounwind ssp {
; CHECK-LABEL: @test6(
entry:
%0 = tail call noalias i8* @malloc(i32 20) nounwind
- %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false, i1 false)
+ %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false, i1 false, i1 false)
%2 = load i8*, i8** @s, align 8
; CHECK-NOT: @llvm.objectsize
; CHECK: @__memcpy_chk(i8* %0, i8* %1, i32 30, i32 20)
@@ -156,7 +156,7 @@ define i32 @test7(i8** %esc) {
%alloc = call noalias i8* @malloc(i32 48) nounwind
store i8* %alloc, i8** %esc
%gep = getelementptr inbounds i8, i8* %alloc, i32 16
- %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false, i1 false) nounwind readonly
+ %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false, i1 false, i1 false) nounwind readonly
; CHECK: ret i32 32
ret i32 %objsize
}
@@ -168,7 +168,7 @@ define i32 @test8(i8** %esc) {
%alloc = call noalias i8* @calloc(i32 5, i32 7) nounwind
store i8* %alloc, i8** %esc
%gep = getelementptr inbounds i8, i8* %alloc, i32 5
- %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false, i1 false) nounwind readonly
+ %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false, i1 false, i1 false) nounwind readonly
; CHECK: ret i32 30
ret i32 %objsize
}
@@ -180,7 +180,7 @@ declare noalias i8* @strndup(i8* nocapture, i32) nounwind
define i32 @test9(i8** %esc) {
%call = tail call i8* @strdup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0)) nounwind
store i8* %call, i8** %esc, align 8
- %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false)
+ %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false, i1 false)
; CHECK: ret i32 8
ret i32 %1
}
@@ -189,7 +189,7 @@ define i32 @test9(i8** %esc) {
define i32 @test10(i8** %esc) {
%call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i32 3) nounwind
store i8* %call, i8** %esc, align 8
- %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false)
+ %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false, i1 false)
; CHECK: ret i32 4
ret i32 %1
}
@@ -198,7 +198,7 @@ define i32 @test10(i8** %esc) {
define i32 @test11(i8** %esc) {
%call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i32 7) nounwind
store i8* %call, i8** %esc, align 8
- %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false)
+ %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false, i1 false)
; CHECK: ret i32 8
ret i32 %1
}
@@ -207,7 +207,7 @@ define i32 @test11(i8** %esc) {
define i32 @test12(i8** %esc) {
%call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i32 8) nounwind
store i8* %call, i8** %esc, align 8
- %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false)
+ %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false, i1 false)
; CHECK: ret i32 8
ret i32 %1
}
@@ -216,7 +216,7 @@ define i32 @test12(i8** %esc) {
define i32 @test13(i8** %esc) {
%call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i32 57) nounwind
store i8* %call, i8** %esc, align 8
- %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false)
+ %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true, i1 false, i1 false)
; CHECK: ret i32 8
ret i32 %1
}
@@ -227,7 +227,7 @@ define i32 @test13(i8** %esc) {
; CHECK-NEXT: ret i32 60
define i32 @test18() {
%bc = bitcast [60 x i8]* @globalalias to i8*
- %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false, i1 false)
+ %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false, i1 false, i1 false)
ret i32 %1
}
@@ -237,35 +237,35 @@ define i32 @test18() {
; CHECK: llvm.objectsize
define i32 @test19() {
%bc = bitcast [60 x i8]* @globalalias2 to i8*
- %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false, i1 false)
+ %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false, i1 false, i1 false)
ret i32 %1
}
; CHECK-LABEL: @test20(
; CHECK: ret i32 0
define i32 @test20() {
- %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1 false)
+ %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1 false, i1 false)
ret i32 %1
}
; CHECK-LABEL: @test21(
; CHECK: ret i32 0
define i32 @test21() {
- %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1 false)
+ %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1 false, i1 false)
ret i32 %1
}
; CHECK-LABEL: @test22(
; CHECK: llvm.objectsize
define i32 @test22() {
- %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1 true)
+ %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1 true, i1 false)
ret i32 %1
}
; CHECK-LABEL: @test23(
; CHECK: llvm.objectsize
define i32 @test23() {
- %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1 true)
+ %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1 true, i1 false)
ret i32 %1
}
@@ -274,7 +274,7 @@ define i32 @test23() {
; CHECK: llvm.objectsize
define i32 @test24() {
%1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 false,
- i1 false)
+ i1 false, i1 false)
ret i32 %1
}
@@ -282,7 +282,7 @@ define i32 @test24() {
; CHECK: llvm.objectsize
define i32 @test25() {
%1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 true,
- i1 false)
+ i1 false, i1 false)
ret i32 %1
}
@@ -290,7 +290,7 @@ define i32 @test25() {
; CHECK: llvm.objectsize
define i32 @test26() {
%1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 false,
- i1 true)
+ i1 true, i1 false)
ret i32 %1
}
@@ -298,6 +298,6 @@ define i32 @test26() {
; CHECK: llvm.objectsize
define i32 @test27() {
%1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 true,
- i1 true)
+ i1 true, i1 false)
ret i32 %1
}
diff --git a/llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll b/llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll
index aae0d48e41b..b2e0416ae3d 100644
--- a/llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll
+++ b/llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll
@@ -64,10 +64,10 @@ define i8* @test_simplify5() {
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
-; 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)
+; 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)
; 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)
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
- %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false)
+ %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 %len)
ret i8* %ret
}
@@ -81,7 +81,7 @@ define i8* @test_simplify6() {
; CHECK-NEXT: %strlen = call i32 @strlen(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0))
; CHECK-NEXT: %1 = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 %strlen
; CHECK-NEXT: ret i8* %1
- %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false)
+ %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
%ret = call i8* @__stpcpy_chk(i8* %dst, i8* %dst, i32 %len)
ret i8* %ret
}
@@ -100,4 +100,4 @@ define i8* @test_no_simplify1() {
}
declare i8* @__stpcpy_chk(i8*, i8*, i32) nounwind
-declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1) nounwind readonly
+declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) nounwind readonly
diff --git a/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll b/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll
index a9a1f46b7e2..859d810d3c4 100644
--- a/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll
+++ b/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll
@@ -64,10 +64,10 @@ define i8* @test_simplify5() {
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
%src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
-; 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)
+; 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)
; 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)
; CHECK-NEXT: ret i8* %1
- %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false)
+ %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
%ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len)
ret i8* %ret
}
@@ -78,10 +78,10 @@ define i8* @test_simplify6() {
; CHECK-LABEL: @test_simplify6(
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
-; 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)
+; 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)
; 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)
; CHECK-NEXT: ret i8* %ret
- %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false)
+ %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
%ret = call i8* @__strcpy_chk(i8* %dst, i8* %dst, i32 %len)
ret i8* %ret
}
@@ -100,4 +100,4 @@ define i8* @test_no_simplify1() {
}
declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind
-declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1) nounwind readonly
+declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) nounwind readonly
OpenPOWER on IntegriCloud