diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 93ab465079777..7461d0ee00bdc 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -26,6 +26,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/OSLog.h" #include "clang/AST/OperationKinds.h" +#include "clang/AST/StmtVisitor.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" @@ -1052,11 +1053,130 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, IsSigned)); } +namespace { + +/// SubobjectFinder - A simple visitor to find the "sub-object" pointed to by a +/// __builtin_dynamic_object_size call. Information gathered from the +/// sub-object is used by the back-end to determine the correct size when the +/// 'TYPE' of the __bdos call has the least significant bit set (i.e. asking +/// for the sub-object size). +/// +/// The expectation is that we'll eventually hit one of three expression types: +/// +/// 1. DeclRefExpr - This is the expression for the base of the structure. +/// 2. MemberExpr - This is the field in the structure. +/// 3. CompoundLiteralExpr - This is for people who create something +/// heretical like (struct foo has a flexible array member): +/// +/// (struct foo){ 1, 2 }.blah[idx]; +/// +/// All other expressions can be correctly handled with the current code. +struct SubobjectFinder + : public ConstStmtVisitor { + SubobjectFinder() = default; + + //===--------------------------------------------------------------------===// + // Visitor Methods + //===--------------------------------------------------------------------===// + + const Expr *VisitStmt(const Stmt *S) { return nullptr; } + + const Expr *VisitDeclRefExpr(const DeclRefExpr *E) { return E; } + const Expr *VisitMemberExpr(const MemberExpr *E) { return E; } + const Expr *VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { + return E; + } + + const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { + return Visit(E->getBase()); + } + const Expr *VisitCastExpr(const CastExpr *E) { + return Visit(E->getSubExpr()); + } + const Expr *VisitParenExpr(const ParenExpr *E) { + return Visit(E->getSubExpr()); + } + const Expr *VisitUnaryAddrOf(const clang::UnaryOperator *E) { + return Visit(E->getSubExpr()); + } + const Expr *VisitUnaryDeref(const clang::UnaryOperator *E) { + return Visit(E->getSubExpr()); + } +}; + +} // end anonymous namespace + +/// getFieldInfo - Gather the size of the field \p VD in \p RD. +static uint64_t getFieldInfo(CodeGenFunction &CGF, const RecordDecl *RD, + const ValueDecl *VD) { + if (!RD) + return 0; + + ASTContext &Ctx = CGF.getContext(); + + for (const Decl *D : RD->decls()) { + if (const auto *Record = dyn_cast(D)) { + uint64_t Res = getFieldInfo(CGF, Record->getDefinition(), VD); + if (Res != 0) + return Res; + continue; + } + + if (const auto *FD = dyn_cast(D); FD == VD) + return Ctx.getTypeSizeInChars(FD->getType()).getQuantity(); + } + + return 0; +} + +/// getSubobjectInfo - Find the sub-object that \p E points to. If it lives +/// inside a struct, return the "size" and "offset" of that sub-object. +static uint64_t getSubobjectInfo(CodeGenFunction &CGF, const Expr *E) { + const Expr *Subobject = SubobjectFinder().Visit(E); + if (!Subobject) + return 0; + + const RecordDecl *OuterRD = nullptr; + const ValueDecl *VD = nullptr; + + if (const auto *DRE = dyn_cast(Subobject)) { + // We're pointing to the beginning of the struct. + VD = DRE->getDecl(); + QualType Ty = VD->getType(); + if (Ty->isPointerType()) + Ty = Ty->getPointeeType(); + OuterRD = Ty->getAsRecordDecl(); + } else if (const auto *ME = dyn_cast(Subobject)) { + VD = ME->getMemberDecl(); + OuterRD = VD->getDeclContext()->getOuterLexicalRecordContext(); + } else { + if (!isa(Subobject)) + llvm_unreachable("unexpected expression"); + + // We encounter a CompoundLiteralExpr if we have something like this: + // + // __builtin_dynamic_object_size(&(struct x){ 1, 2, 3 }, 1) + // + // In that case, we want the size of the whole struct. So we don't have to + // worry about finding a suboject. + return 0; + } + + if (!VD || !OuterRD) + // The expression is referencing an object that's not in a struct. + return 0; + + return getFieldInfo(CGF, OuterRD->getDefinition(), VD); +} + /// Returns a Value corresponding to the size of the given expression. /// This Value may be either of the following: -/// - A llvm::Argument (if E is a param with the pass_object_size attribute on -/// it) -/// - A call to the @llvm.objectsize intrinsic +/// +/// - An Argument if E is a param with the pass_object_size attribute on +/// it, +/// - An Instruction representing the calculation of the value, when a +/// flexible array member is involved, or +/// - A call to the @llvm.objectsize intrinsic. /// /// EmittedE is the result of emitting `E` as a scalar expr. If it's non-null /// and we wouldn't otherwise try to reference a pass_object_size parameter, @@ -1084,18 +1204,29 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type, } } + // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't + // evaluate E for side-effects. In either case, we shouldn't lower to + // @llvm.objectsize. + if (Type == 3 || (!EmittedE && E->HasSideEffects(getContext()))) + return getDefaultBuiltinObjectSizeResult(Type, ResType); + + Value *SubobjectSize = Builder.getInt64(0); + if (IsDynamic) { // Emit special code for a flexible array member with the "counted_by" // attribute. if (Value *V = emitFlexibleArrayMemberSize(E, Type, ResType)) return V; - } - // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't - // evaluate E for side-effects. In either case, we shouldn't lower to - // @llvm.objectsize. - if (Type == 3 || (!EmittedE && E->HasSideEffects(getContext()))) - return getDefaultBuiltinObjectSizeResult(Type, ResType); + if ((Type & 1) != 0) { + // The object size is constrained to the sub-object containing the + // element. If it's in a structure, get the size and offset information + // for back-end processing. + uint64_t Info = getSubobjectInfo(*this, E); + if (Info != 0) + SubobjectSize = Builder.getInt64(Info); + } + } Value *Ptr = EmittedE ? EmittedE : EmitScalarExpr(E); assert(Ptr->getType()->isPointerTy() && @@ -1109,7 +1240,12 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type, // For GCC compatibility, __builtin_object_size treat NULL as unknown size. Value *NullIsUnknown = Builder.getTrue(); Value *Dynamic = Builder.getInt1(IsDynamic); - return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}); + // If the least significant bit is clear, objects are whole variables. If + // it's set, a closest surrounding subobject is considered the object a + // pointer points to. + Value *WholeObj = Builder.getInt1((Type & 1) == 0); + return Builder.CreateCall( + F, {Ptr, Min, NullIsUnknown, Dynamic, WholeObj, SubobjectSize}); } namespace { diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 59a7fe8925001..d94a775cab65a 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -742,13 +742,17 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, // FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation // to check this. // FIXME: Get object address space - llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy }; - llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys); + llvm::Function *F = + CGM.getIntrinsic(llvm::Intrinsic::objectsize, {IntPtrTy, Int8PtrTy}); llvm::Value *Min = Builder.getFalse(); llvm::Value *NullIsUnknown = Builder.getFalse(); llvm::Value *Dynamic = Builder.getFalse(); + llvm::Value *WholeObj = Builder.getTrue(); + llvm::Value *SubobjectSize = Builder.getInt64(0); llvm::Value *LargeEnough = Builder.CreateICmpUGE( - Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size); + Builder.CreateCall( + F, {Ptr, Min, NullIsUnknown, Dynamic, WholeObj, SubobjectSize}), + Size); Checks.push_back(std::make_pair(LargeEnough, SanitizerKind::ObjectSize)); } } diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c index e5685e39173b0..4516de52beddd 100644 --- a/clang/test/CodeGen/attr-counted-by.c +++ b/clang/test/CodeGen/attr-counted-by.c @@ -66,7 +66,7 @@ struct anon_struct { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10:[0-9]+]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9:[0-9]+]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 @@ -114,7 +114,7 @@ void test1(struct annotated *p, int index, int val) { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ugt i64 [[TMP0]], [[INDEX]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[INDEX]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[INDEX]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 @@ -203,7 +203,7 @@ size_t test2_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ugt i64 [[TMP0]], [[INDEX]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[INDEX]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[INDEX]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 @@ -308,7 +308,7 @@ size_t test3_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT4:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont4: // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], 2 @@ -325,7 +325,7 @@ size_t test3_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp ult i64 [[IDXPROM13]], [[TMP6]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP7]], label [[CONT20:%.*]], label [[HANDLER_OUT_OF_BOUNDS16:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds16: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[IDXPROM13]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[IDXPROM13]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont20: // SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD7]], 3 @@ -342,7 +342,7 @@ size_t test3_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = icmp ult i64 [[IDXPROM30]], [[TMP12]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP13]], label [[CONT37:%.*]], label [[HANDLER_OUT_OF_BOUNDS33:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds33: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[IDXPROM30]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[IDXPROM30]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont37: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM30]] @@ -494,7 +494,7 @@ size_t test4_bdos(struct annotated *p, int index) { // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[DOT_COUNTED_BY_LOAD]], [[IDXPROM]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 16 @@ -590,7 +590,7 @@ size_t test5_bdos(struct anon_struct *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[DOT_COUNTED_BY_LOAD]], [[IDXPROM]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 16 @@ -683,7 +683,7 @@ size_t test6_bdos(struct anon_struct *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont7: // SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 @@ -756,7 +756,7 @@ size_t test7_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT9:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont9: // SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 @@ -837,7 +837,7 @@ size_t test8_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB14:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB14:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont7: // SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 @@ -910,7 +910,7 @@ size_t test9_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT9:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont9: // SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 @@ -997,7 +997,7 @@ size_t test10_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB16:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB16:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 @@ -1079,13 +1079,13 @@ int test12_a, test12_b; // SANITIZE-WITH-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[BAZ:%.*]] = alloca [[STRUCT_HANG:%.*]], align 4 -// SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR11:[0-9]+]] +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR10:[0-9]+]] // SANITIZE-WITH-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT9:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[INDEX]], 6 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB18:[0-9]+]], i64 [[TMP1]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB18:[0-9]+]], i64 [[TMP1]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[TMP1]] @@ -1095,10 +1095,10 @@ int test12_a, test12_b; // SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 0 // SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF10:![0-9]+]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds4: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB19:[0-9]+]], i64 0) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB19:[0-9]+]], i64 0) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.type_mismatch6: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0) to i64)) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0) to i64)) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test12( @@ -1121,13 +1121,13 @@ int test12_a, test12_b; // SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[BAZ:%.*]] = alloca [[STRUCT_HANG:%.*]], align 4 -// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR7:[0-9]+]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR6:[0-9]+]] // SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT7:![0-9]+]] // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[INDEX]], 6 // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[INDEX]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META9:![0-9]+]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP1]]) #[[ATTR8:[0-9]+]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP1]]) #[[ATTR7:[0-9]+]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont: // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[TMP1]] @@ -1137,10 +1137,10 @@ int test12_a, test12_b; // SANITIZE-WITHOUT-ATTR-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 0 // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF10:![0-9]+]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds4: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 0) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.type_mismatch6: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0) to i64)) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0) to i64)) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i32 @test12( @@ -1188,7 +1188,7 @@ struct test13_bar { // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[TMP1]], [[INDEX]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB23:[0-9]+]], i64 [[INDEX]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB23:[0-9]+]], i64 [[INDEX]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 16 @@ -1215,7 +1215,7 @@ struct test13_bar { // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[TMP1]], [[INDEX]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[INDEX]]) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont5: // SANITIZE-WITHOUT-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 16 @@ -1245,15 +1245,21 @@ struct test14_foo { // SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test14( // SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOMPOUNDLITERAL:%.*]] = alloca [[STRUCT_TEST14_FOO:%.*]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 1, ptr [[DOTCOMPOUNDLITERAL]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: [[Y:%.*]] = getelementptr inbounds i8, ptr [[DOTCOMPOUNDLITERAL]], i64 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 2, ptr [[Y]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp eq i32 [[IDX]], 0 -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB24:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB24:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: trap: -// SANITIZE-WITH-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR10]] -// SANITIZE-WITH-ATTR-NEXT: unreachable +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds i8, ptr [[DOTCOMPOUNDLITERAL]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP1]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test14( // NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR4]] { @@ -1271,15 +1277,21 @@ struct test14_foo { // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test14( // SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOMPOUNDLITERAL:%.*]] = alloca [[STRUCT_TEST14_FOO:%.*]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 1, ptr [[DOTCOMPOUNDLITERAL]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[Y:%.*]] = getelementptr inbounds i8, ptr [[DOTCOMPOUNDLITERAL]], i64 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 2, ptr [[Y]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp eq i32 [[IDX]], 0 -// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR: trap: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR8]] -// SANITIZE-WITHOUT-ATTR-NEXT: unreachable +// SANITIZE-WITHOUT-ATTR: cont3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds i8, ptr [[DOTCOMPOUNDLITERAL]], i64 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP1]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test14( // NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { @@ -1301,15 +1313,23 @@ int test14(int idx) { // SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test15( // SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp eq i32 [[IDX]], 0 -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds: +// SANITIZE-WITH-ATTR-NEXT: [[FOO:%.*]] = alloca [[STRUCT_ANON_8:%.*]], align 4 +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr nonnull [[FOO]]) #[[ATTR10]] +// SANITIZE-WITH-ATTR-NEXT: store i32 1, ptr [[FOO]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 2, ptr [[TMP0]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB25:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq i32 [[IDX]], 0 +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB25:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: trap: -// SANITIZE-WITH-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR10]] -// SANITIZE-WITH-ATTR-NEXT: unreachable +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr nonnull [[FOO]]) #[[ATTR10]] +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP2]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test15( // NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR4]] { @@ -1329,15 +1349,23 @@ int test14(int idx) { // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test15( // SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp eq i32 [[IDX]], 0 -// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: +// SANITIZE-WITHOUT-ATTR-NEXT: [[FOO:%.*]] = alloca [[STRUCT_ANON_8:%.*]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr nonnull [[FOO]]) #[[ATTR6]] +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 1, ptr [[FOO]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 2, ptr [[TMP0]], align 4 // SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = icmp eq i32 [[IDX]], 0 +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP1]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR: trap: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR8]] -// SANITIZE-WITHOUT-ATTR-NEXT: unreachable +// SANITIZE-WITHOUT-ATTR: cont1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr nonnull [[FOO]]) #[[ATTR6]] +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP2]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test15( // NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { @@ -1501,7 +1529,7 @@ struct tests_foo { // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[DOTCOUNTED_BY_LOAD]], 10 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT4:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB26:[0-9]+]], i64 10) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB26:[0-9]+]], i64 10) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont4: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[VAR]], i64 84 @@ -1542,7 +1570,7 @@ int test24(int c, struct tests_foo *var) { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[DOTCOUNTED_BY_LOAD]], 10 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB27:[0-9]+]], i64 10) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB27:[0-9]+]], i64 10) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 44 @@ -1594,7 +1622,7 @@ struct test26_foo { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB28:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB28:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 8 @@ -1665,7 +1693,7 @@ struct test27_foo { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB30:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB30:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 24 @@ -1731,7 +1759,7 @@ struct test28_foo { // SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT17:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB31:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB31:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont17: // SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 12 @@ -1793,7 +1821,7 @@ struct annotated_struct_array { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[IDX1]] to i64 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB33:[0-9]+]], i64 [[TMP1]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB33:[0-9]+]], i64 [[TMP1]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[TMP1]] @@ -1805,7 +1833,7 @@ struct annotated_struct_array { // SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[IDXPROM15]], [[TMP3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT20:%.*]], label [[HANDLER_OUT_OF_BOUNDS16:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds16: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB34:[0-9]+]], i64 [[IDXPROM15]]) #[[ATTR10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB34:[0-9]+]], i64 [[IDXPROM15]]) #[[ATTR9]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont20: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 12 @@ -1840,7 +1868,7 @@ struct annotated_struct_array { // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[IDX1]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT21:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[TMP1]]) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont21: // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[TMP1]] diff --git a/clang/test/CodeGen/catch-undef-behavior.c b/clang/test/CodeGen/catch-undef-behavior.c index af37ef9e8565b..a2c3768bee993 100644 --- a/clang/test/CodeGen/catch-undef-behavior.c +++ b/clang/test/CodeGen/catch-undef-behavior.c @@ -35,7 +35,7 @@ void foo(void) { union { int i; } u; - // CHECK-COMMON: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0(ptr %[[PTR:.*]], i1 false, i1 false, i1 false) + // CHECK-COMMON: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0(ptr %[[PTR:.*]], i1 false, i1 false, i1 false, i1 true, i64 0) // 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-sub-object.c b/clang/test/CodeGen/object-size-sub-object.c new file mode 100644 index 0000000000000..28a12ffb60462 --- /dev/null +++ b/clang/test/CodeGen/object-size-sub-object.c @@ -0,0 +1,311 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s + +typedef __SIZE_TYPE__ size_t; + +#define __bdos(a) __builtin_dynamic_object_size(a, 1) + +struct U { + double d; + int i; +}; + +struct test_struct { + struct test_struct *vptr; + char buf1[5]; + struct i { + char a; + int b[2][13]; + int c, d; + } z; + struct U *u_ptr; + unsigned _a : 1; + unsigned _b : 2; + struct { + struct { + char x_1; + char x_2[37]; + }; + }; + union { + struct { char _z[20]; } m; + struct { char _y[13]; } n; + } u; + char buf2[7]; +}; + +size_t ret; + +// CHECK-LABEL: define dso_local i64 @test1( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true, i1 false, i64 0) +// CHECK-NEXT: ret i64 [[TMP1]] +// +size_t test1(struct test_struct *p, int idx) { + return __bdos(p); +} + +// CHECK-LABEL: define dso_local i64 @test2( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[BUF1:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 1 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [5 x i8], ptr [[BUF1]], i64 0, i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 5) +// CHECK-NEXT: ret i64 [[TMP2]] +// +size_t test2(struct test_struct *p, int idx) { + return __bdos(&p->buf1[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test3( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 2 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[Z]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 116) +// CHECK-NEXT: ret i64 [[TMP2]] +// +size_t test3(struct test_struct *p, int idx) { + return __bdos(&((char *)&p->z)[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test4( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 2 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[Z]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 116) +// CHECK-NEXT: ret i64 [[TMP2]] +// +size_t test4(struct test_struct *p, int idx) { + return __bdos(&((char *)&p->z)[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test5( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 2 +// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_I:%.*]], ptr [[Z]], i32 0, i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 1) +// CHECK-NEXT: ret i64 [[TMP2]] +// +size_t test5(struct test_struct *p, int idx) { + return __bdos(&((char *)&p->z.a)[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test6( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 2 +// CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_I:%.*]], ptr [[Z]], i32 0, i32 1 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 104) +// CHECK-NEXT: ret i64 [[TMP2]] +// +size_t test6(struct test_struct *p, int idx) { + return __bdos(&((char *)&p->z.b)[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test7( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 2 +// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_I:%.*]], ptr [[Z]], i32 0, i32 2 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 4) +// CHECK-NEXT: ret i64 [[TMP2]] +// +size_t test7(struct test_struct *p, int idx) { + return __bdos(&((char *)&p->z.c)[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test8( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 2 +// CHECK-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_I:%.*]], ptr [[Z]], i32 0, i32 3 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[D]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 4) +// CHECK-NEXT: ret i64 [[TMP2]] +// +size_t test8(struct test_struct *p, int idx) { + return __bdos(&((char *)&p->z.d)[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test9( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[U_PTR:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 3 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[U_PTR]], align 8 +// CHECK-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_U:%.*]], ptr [[TMP1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP2]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[D]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 8) +// CHECK-NEXT: ret i64 [[TMP3]] +// +size_t test9(struct test_struct *p, int idx) { + return __bdos(&((char *)&p->u_ptr->d)[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test10( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 5 +// CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP1]], i32 0, i32 0 +// CHECK-NEXT: [[X_1:%.*]] = getelementptr inbounds [[STRUCT_ANON_0:%.*]], ptr [[TMP2]], i32 0, i32 0 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP3]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[X_1]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 1) +// CHECK-NEXT: ret i64 [[TMP4]] +// +size_t test10(struct test_struct *p, int idx) { + return __bdos(&((char *)&p->x_1)[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test11( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 5 +// CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP1]], i32 0, i32 0 +// CHECK-NEXT: [[X_2:%.*]] = getelementptr inbounds [[STRUCT_ANON_0:%.*]], ptr [[TMP2]], i32 0, i32 1 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP3]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[X_2]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 37) +// CHECK-NEXT: ret i64 [[TMP4]] +// +size_t test11(struct test_struct *p, int idx) { + return __bdos(&((char *)&p->x_2)[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test12( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[U:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 6 +// CHECK-NEXT: [[_Z:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], ptr [[U]], i32 0, i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [20 x i8], ptr [[_Z]], i64 0, i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 20) +// CHECK-NEXT: ret i64 [[TMP2]] +// +size_t test12(struct test_struct *p, int idx) { + return __bdos(&p->u.m._z[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test13( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[U:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 6 +// CHECK-NEXT: [[_Y:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], ptr [[U]], i32 0, i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [13 x i8], ptr [[_Y]], i64 0, i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 13) +// CHECK-NEXT: ret i64 [[TMP2]] +// +size_t test13(struct test_struct *p, int idx) { + return __bdos(&p->u.n._y[idx]); +} + +// CHECK-LABEL: define dso_local i64 @test14( +// CHECK-SAME: ptr noundef [[P:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// CHECK-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// CHECK-NEXT: [[BUF2:%.*]] = getelementptr inbounds [[STRUCT_TEST_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 7 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [7 x i8], ptr [[BUF2]], i64 0, i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true, i1 false, i64 7) +// CHECK-NEXT: ret i64 [[TMP2]] +// +size_t test14(struct test_struct *p, int idx) { + return __bdos(&p->buf2[idx]); +} diff --git a/clang/test/CodeGen/object-size.c b/clang/test/CodeGen/object-size.c index b39b15fcc65b9..26ba735caac13 100644 --- a/clang/test/CodeGen/object-size.c +++ b/clang/test/CodeGen/object-size.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s -// RUN: %clang_cc1 -no-enable-noundef-analysis -DDYNAMIC -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s +// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck --check-prefix=STATIC %s +// RUN: %clang_cc1 -no-enable-noundef-analysis -DDYNAMIC -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck --check-prefix=DYNAMIC %s #ifndef DYNAMIC #define OBJECT_SIZE_BUILTIN __builtin_object_size @@ -20,381 +20,612 @@ char gbuf[63]; char *gp; int gi, gj; -// CHECK-LABEL: define{{.*}} void @test1 void test1(void) { - // CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 4), ptr @.str, i64 59) + // STATIC-LABEL: define{{.*}} void @test1 + // STATIC: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 4), ptr @.str, i64 59) + + // DYNAMIC-LABEL: define{{.*}} void @test1 + // DYNAMIC: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 4), ptr @.str, i64 59) + strcpy(&gbuf[4], "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test2 void test2(void) { - // CHECK: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63) + // STATIC-LABEL: define{{.*}} void @test2 + // STATIC: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63) + + // DYNAMIC-LABEL: define{{.*}} void @test2 + // DYNAMIC: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63) + strcpy(gbuf, "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test3 void test3(void) { - // CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 1, i64 37), ptr @.str, i64 0) + // STATIC-LABEL: define{{.*}} void @test3 + // STATIC: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 1, i64 37), ptr @.str, i64 0) + + // DYNAMIC-LABEL: define{{.*}} void @test3 + // DYNAMIC: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 1, i64 37), ptr @.str, i64 0) + strcpy(&gbuf[100], "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test4 void test4(void) { - // CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 -1), ptr @.str, i64 0) + // STATIC-LABEL: define{{.*}} void @test4 + // STATIC: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 -1), ptr @.str, i64 0) + + // DYNAMIC-LABEL: define{{.*}} void @test4 + // DYNAMIC: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 -1), ptr @.str, i64 0) + strcpy((char*)(void*)&gbuf[-1], "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test5 void test5(void) { - // CHECK: = load ptr, ptr @gp - // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC-LABEL: define{{.*}} void @test5 + // STATIC: = load ptr, ptr @gp + // STATIC-NEXT:= call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + + // DYNAMIC-LABEL: define{{.*}} void @test5 + // DYNAMIC: = load ptr, ptr @gp + // DYNAMIC-NEXT:= call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + strcpy(gp, "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test6 void test6(void) { char buf[57]; - // CHECK: = call ptr @__strcpy_chk(ptr %{{.*}}, ptr @.str, i64 53) + // STATIC-LABEL: define{{.*}} void @test6 + // STATIC: = call ptr @__strcpy_chk(ptr %{{.*}}, ptr @.str, i64 53) + + // DYNAMIC-LABEL: define{{.*}} void @test6 + // DYNAMIC: = call ptr @__strcpy_chk(ptr %{{.*}}, ptr @.str, i64 53) + strcpy(&buf[4], "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test7 void test7(void) { - int i; // Ensure we only evaluate the side-effect once. - // CHECK: = add - // CHECK-NOT: = add - // CHECK: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63) + int i; + + // STATIC-LABEL: define{{.*}} void @test7 + // STATIC: = add + // STATIC-NOT: = add + // STATIC: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63) + + // DYNAMIC-LABEL: define{{.*}} void @test7 + // DYNAMIC: = add + // DYNAMIC-NOT: = add + // DYNAMIC: = call ptr @__strcpy_chk(ptr @gbuf, ptr @.str, i64 63) + strcpy((++i, gbuf), "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test8 void test8(void) { char *buf[50]; - // CHECK-NOT: __strcpy_chk - // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + // STATIC-LABEL: define{{.*}} void @test8 + // STATIC-NOT: __strcpy_chk + // STATIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + + // DYNAMIC-LABEL: define{{.*}} void @test8 + // DYNAMIC-NOT: __strcpy_chk + // DYNAMIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + strcpy(buf[++gi], "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test9 void test9(void) { - // CHECK-NOT: __strcpy_chk - // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + // STATIC-LABEL: define{{.*}} void @test9 + // STATIC-NOT: __strcpy_chk + // STATIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + + // DYNAMIC-LABEL: define{{.*}} void @test9 + // DYNAMIC-NOT: __strcpy_chk + // DYNAMIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + strcpy((char *)((++gi) + gj), "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test10 char **p; void test10(void) { - // CHECK-NOT: __strcpy_chk - // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + // STATIC-LABEL: define{{.*}} void @test10 + // STATIC-NOT: __strcpy_chk + // STATIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + + // DYNAMIC-LABEL: define{{.*}} void @test10 + // DYNAMIC-NOT: __strcpy_chk + // DYNAMIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + strcpy(*(++p), "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test11 void test11(void) { - // CHECK-NOT: __strcpy_chk - // CHECK: = call ptr @__inline_strcpy_chk(ptr @gbuf, ptr @.str) + // STATIC-LABEL: define{{.*}} void @test11 + // STATIC-NOT: __strcpy_chk + // STATIC: = call ptr @__inline_strcpy_chk(ptr @gbuf, ptr @.str) + + // DYNAMIC-LABEL: define{{.*}} void @test11 + // DYNAMIC-NOT: __strcpy_chk + // DYNAMIC: = call ptr @__inline_strcpy_chk(ptr @gbuf, ptr @.str) + strcpy(gp = gbuf, "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test12 void test12(void) { - // CHECK-NOT: __strcpy_chk - // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + // STATIC-LABEL: define{{.*}} void @test12 + // STATIC-NOT: __strcpy_chk + // STATIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + + // DYNAMIC-LABEL: define{{.*}} void @test12 + // DYNAMIC-NOT: __strcpy_chk + // DYNAMIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + strcpy(++gp, "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test13 void test13(void) { - // CHECK-NOT: __strcpy_chk - // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + // STATIC-LABEL: define{{.*}} void @test13 + // STATIC-NOT: __strcpy_chk + // STATIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + + // DYNAMIC-LABEL: define{{.*}} void @test13 + // DYNAMIC-NOT: __strcpy_chk + // DYNAMIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + strcpy(gp++, "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test14 void test14(void) { - // CHECK-NOT: __strcpy_chk - // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + // STATIC-LABEL: define{{.*}} void @test14 + // STATIC-NOT: __strcpy_chk + // STATIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + + // DYNAMIC-LABEL: define{{.*}} void @test14 + // DYNAMIC-NOT: __strcpy_chk + // DYNAMIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + strcpy(--gp, "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test15 void test15(void) { - // CHECK-NOT: __strcpy_chk - // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{..*}}, ptr @.str) + // STATIC-LABEL: define{{.*}} void @test15 + // STATIC-NOT: __strcpy_chk + // STATIC: = call ptr @__inline_strcpy_chk(ptr %{{..*}}, ptr @.str) + + // DYNAMIC-LABEL: define{{.*}} void @test15 + // DYNAMIC-NOT: __strcpy_chk + // DYNAMIC: = call ptr @__inline_strcpy_chk(ptr %{{..*}}, ptr @.str) + strcpy(gp--, "Hi there"); } -// CHECK-LABEL: define{{.*}} void @test16 void test16(void) { - // CHECK-NOT: __strcpy_chk - // CHECK: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + // STATIC-LABEL: define{{.*}} void @test16 + // STATIC-NOT: __strcpy_chk + // STATIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + + // DYNAMIC-LABEL: define{{.*}} void @test16 + // DYNAMIC-NOT: __strcpy_chk + // DYNAMIC: = call ptr @__inline_strcpy_chk(ptr %{{.*}}, ptr @.str) + strcpy(gp += 1, "Hi there"); } -// CHECK-LABEL: @test17 void test17(void) { - // CHECK: store i32 -1 + // STATIC-LABEL: @test17 + // STATIC: store i32 -1 + // STATIC: store i32 -1 + // STATIC: store i32 0 + // STATIC: store i32 0 + + // DYNAMIC-LABEL: @test17 + // DYNAMIC: store i32 -1 + // DYNAMIC: store i32 -1 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(gp++, 0); - // CHECK: store i32 -1 gi = OBJECT_SIZE_BUILTIN(gp++, 1); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(gp++, 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(gp++, 3); } -// CHECK-LABEL: @test18 unsigned test18(int cond) { int a[4], b[4]; - // CHECK: phi ptr - // CHECK: call i64 @llvm.objectsize.i64 + // STATIC-LABEL: @test18 + // STATIC: phi ptr + // STATIC: call i64 @llvm.objectsize.i64 + + // DYNAMIC-LABEL: @test18 + // DYNAMIC: phi ptr + // DYNAMIC: call i64 @llvm.objectsize.i64 + return OBJECT_SIZE_BUILTIN(cond ? a : b, 0); } -// CHECK-LABEL: @test19 void test19(void) { struct { int a, b; } foo; - // CHECK: store i32 8 + // STATIC-LABEL: @test19 + // STATIC: store i32 8 + // STATIC: store i32 4 + // STATIC: store i32 8 + // STATIC: store i32 4 + + // DYNAMIC-LABEL: @test19 + // DYNAMIC: store i32 8 + // DYNAMIC: store i32 4 + // DYNAMIC: store i32 8 + // DYNAMIC: store i32 4 + gi = OBJECT_SIZE_BUILTIN(&foo.a, 0); - // CHECK: store i32 4 gi = OBJECT_SIZE_BUILTIN(&foo.a, 1); - // CHECK: store i32 8 gi = OBJECT_SIZE_BUILTIN(&foo.a, 2); - // CHECK: store i32 4 gi = OBJECT_SIZE_BUILTIN(&foo.a, 3); - // CHECK: store i32 4 + // STATIC: store i32 4 + // STATIC: store i32 4 + // STATIC: store i32 4 + // STATIC: store i32 4 + + // DYNAMIC: store i32 4 + // DYNAMIC: store i32 4 + // DYNAMIC: store i32 4 + // DYNAMIC: store i32 4 + gi = OBJECT_SIZE_BUILTIN(&foo.b, 0); - // CHECK: store i32 4 gi = OBJECT_SIZE_BUILTIN(&foo.b, 1); - // CHECK: store i32 4 gi = OBJECT_SIZE_BUILTIN(&foo.b, 2); - // CHECK: store i32 4 gi = OBJECT_SIZE_BUILTIN(&foo.b, 3); } -// CHECK-LABEL: @test20 void test20(void) { struct { int t[10]; } t[10]; - // CHECK: store i32 380 + // STATIC-LABEL: @test20 + // STATIC: store i32 380 + // STATIC: store i32 20 + // STATIC: store i32 380 + // STATIC: store i32 20 + + // DYNAMIC-LABEL: @test20 + // DYNAMIC: store i32 380 + // DYNAMIC: store i32 20 + // DYNAMIC: store i32 380 + + // DYNAMIC: store i32 20 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 0); - // CHECK: store i32 20 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 1); - // CHECK: store i32 380 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 2); - // CHECK: store i32 20 gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 3); } -// CHECK-LABEL: @test21 void test21(void) { struct { int t; } t; - // CHECK: store i32 0 + // STATIC-LABEL: @test21 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + + // DYNAMIC-LABEL: @test21 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(&t + 1, 0); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t + 1, 1); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t + 1, 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t + 1, 3); - // CHECK: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 0); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 1); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 3); } -// CHECK-LABEL: @test22 void test22(void) { struct { int t[10]; } t[10]; - // CHECK: store i32 0 + // STATIC-LABEL: @test22 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + + // DYNAMIC-LABEL: @test22 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(&t[10], 0); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t[10], 1); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t[10], 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t[10], 3); - // CHECK: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 0); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 1); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 3); - // CHECK: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 0); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 1); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 3); - // CHECK: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + // STATIC: store i32 0 + + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 0); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 1); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 3); } struct Test23Ty { int a; int t[10]; }; -// CHECK-LABEL: @test23 void test23(struct Test23Ty *p) { - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC-LABEL: @test23 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // Note: this is currently fixed at 0 because LLVM doesn't have sufficient + // data to correctly handle type=3 + // STATIC: store i32 0 + + // DYNAMIC-LABEL: @test23 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // Note: this is currently fixed at 0 because LLVM doesn't have sufficient + // data to correctly handle type=3 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(p, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(p, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(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 = OBJECT_SIZE_BUILTIN(p, 3); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 4 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 4 + + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 4 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 4 + gi = OBJECT_SIZE_BUILTIN(&p->a, 0); - // CHECK: store i32 4 gi = OBJECT_SIZE_BUILTIN(&p->a, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(&p->a, 2); - // CHECK: store i32 4 gi = OBJECT_SIZE_BUILTIN(&p->a, 3); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 20 + + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 40) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 20 + gi = OBJECT_SIZE_BUILTIN(&p->t[5], 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 2); - // CHECK: store i32 20 gi = OBJECT_SIZE_BUILTIN(&p->t[5], 3); } // PR24493 -- ICE if OBJECT_SIZE_BUILTIN called with NULL and (Type & 1) != 0 -// CHECK-LABEL: @test24 void test24(void) { - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 + // STATIC-LABEL: @test24 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // Note: Currently fixed at zero because LLVM can't handle type=3 correctly. + // Hopefully will be lowered properly in the future. + // STATIC: store i32 0 + + // DYNAMIC-LABEL: @test24 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true, i1 false, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // Note: Currently fixed at zero because LLVM can't handle type=3 correctly. + // Hopefully will be lowered properly in the future. + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN((void*)0, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN((void*)0, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN((void*)0, 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 = OBJECT_SIZE_BUILTIN((void*)0, 3); } -// CHECK-LABEL: @test25 void test25(void) { - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 + // STATIC-LABEL: @test25 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // Note: Currently fixed at zero because LLVM can't handle type=3 correctly. + // Hopefully will be lowered properly in the future. + // STATIC: store i32 0 + + // DYNAMIC-LABEL: @test25 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true, i1 false, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // Note: Currently fixed at zero because LLVM can't handle type=3 correctly. + // Hopefully will be lowered properly in the future. + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 2); + gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 3); + + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) // 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 = OBJECT_SIZE_BUILTIN((void*)0x1000, 3); + // STATIC: store i32 0 + + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true, i1 false, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // Note: Currently fixed at zero because LLVM can't handle type=3 correctly. + // Hopefully will be lowered properly in the future. + // DYNAMIC: store i32 0 - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN((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. - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 3); } -// CHECK-LABEL: @test26 void test26(void) { struct { int v[10]; } t[10]; - // CHECK: store i32 316 + // STATIC-LABEL: @test26 + // STATIC: store i32 316 + // STATIC: store i32 312 + // STATIC: store i32 308 + // STATIC: store i32 0 + + // DYNAMIC-LABEL: @test26 + // DYNAMIC: store i32 316 + // DYNAMIC: store i32 312 + // DYNAMIC: store i32 308 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(&t[1].v[11], 0); - // CHECK: store i32 312 gi = OBJECT_SIZE_BUILTIN(&t[1].v[12], 1); - // CHECK: store i32 308 gi = OBJECT_SIZE_BUILTIN(&t[1].v[13], 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(&t[1].v[14], 3); } struct Test27IncompleteTy; -// CHECK-LABEL: @test27 void test27(struct Test27IncompleteTy *t) { - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC-LABEL: @test27 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // Note: this is currently fixed at 0 because LLVM doesn't have sufficient + // data to correctly handle type=3 + // STATIC: store i32 0 + + // DYNAMIC-LABEL: @test27 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // Note: this is currently fixed at 0 because LLVM doesn't have sufficient + // data to correctly handle type=3 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(t, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(t, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(t, 2); + gi = OBJECT_SIZE_BUILTIN(t, 3); + + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) // Note: this is currently fixed at 0 because LLVM doesn't have sufficient // data to correctly handle type=3 - // CHECK: store i32 0 - gi = OBJECT_SIZE_BUILTIN(t, 3); + // STATIC: store i32 0 + + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 true, i1 false, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // Note: this is currently fixed at 0 because LLVM doesn't have sufficient + // data to correctly handle type=3 + // DYNAMIC: store i32 0 - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(&test27, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(&test27, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(&test27, 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 = OBJECT_SIZE_BUILTIN(&test27, 3); } // The intent of this test is to ensure that OBJECT_SIZE_BUILTIN treats `&foo` // and `(T*)&foo` identically, when used as the pointer argument. -// CHECK-LABEL: @test28 void test28(void) { struct { int v[10]; } t[10]; #define addCasts(s) ((char*)((short*)(s))) - // CHECK: store i32 360 + // STATIC-LABEL: @test28 + // STATIC: store i32 360 + // STATIC: store i32 360 + // STATIC: store i32 360 + // STATIC: store i32 360 + + // DYNAMIC-LABEL: @test28 + // DYNAMIC: store i32 360 + // DYNAMIC: store i32 360 + // DYNAMIC: store i32 360 + // DYNAMIC: store i32 360 + gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 0); - // CHECK: store i32 360 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 1); - // CHECK: store i32 360 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 2); - // CHECK: store i32 360 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 3); - // CHECK: store i32 356 + // STATIC: store i32 356 + // STATIC: store i32 36 + // STATIC: store i32 356 + // STATIC: store i32 36 + + // DYNAMIC: store i32 356 + // DYNAMIC: store i32 36 + // DYNAMIC: store i32 356 + // DYNAMIC: store i32 36 + gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 0); - // CHECK: store i32 36 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 1); - // CHECK: store i32 356 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 2); - // CHECK: store i32 36 gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 3); #undef addCasts } @@ -419,89 +650,139 @@ struct StaticStruct { char snd[2]; }; -// CHECK-LABEL: @test29 void test29(struct DynStructVar *dv, struct DynStruct0 *d0, struct DynStruct1 *d1, struct StaticStruct *ss) { - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC-LABEL: @test29 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 0 + + // DYNAMIC-LABEL: @test29 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(dv->snd, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(dv->snd, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(dv->snd, 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(dv->snd, 3); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 0 + + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(d0->snd, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(d0->snd, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(d0->snd, 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(d0->snd, 3); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 1 + + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 1) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 1 + gi = OBJECT_SIZE_BUILTIN(d1->snd, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(d1->snd, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(d1->snd, 2); - // CHECK: store i32 1 gi = OBJECT_SIZE_BUILTIN(d1->snd, 3); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 2 + + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 2) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 2 + gi = OBJECT_SIZE_BUILTIN(ss->snd, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(ss->snd, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(ss->snd, 2); - // CHECK: store i32 2 gi = OBJECT_SIZE_BUILTIN(ss->snd, 3); } -// CHECK-LABEL: @test30 void test30(void) { struct { struct DynStruct1 fst, snd; } *nested; - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC-LABEL: @test30 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 1 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 1 + + // DYNAMIC-LABEL: @test30 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 1 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 1 + gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 0); - // CHECK: store i32 1 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 2); - // CHECK: store i32 1 gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 3); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 1 + + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 1) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 1 + gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 2); - // CHECK: store i32 1 gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 3); + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 1 + + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 1) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 1 + union { struct DynStruct1 d1; char c[1]; } *u; - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + gi = OBJECT_SIZE_BUILTIN(u->c, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(u->c, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(u->c, 2); - // CHECK: store i32 1 gi = OBJECT_SIZE_BUILTIN(u->c, 3); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 1 + + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 1) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 1 + gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 2); - // CHECK: store i32 1 gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 3); } -// CHECK-LABEL: @test31 void test31(void) { // Miscellaneous 'writing off the end' detection tests struct DynStructVar *dsv; @@ -509,51 +790,73 @@ void test31(void) { struct DynStruct1 *ds1; struct StaticStruct *ss; - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 - gi = OBJECT_SIZE_BUILTIN(ds1[9].snd, 1); + // STATIC-LABEL: @test31 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 - gi = OBJECT_SIZE_BUILTIN(&ss[9].snd[0], 1); + // DYNAMIC-LABEL: @test31 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 1) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 2) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 1) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 0) - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + gi = OBJECT_SIZE_BUILTIN(ds1[9].snd, 1); + gi = OBJECT_SIZE_BUILTIN(&ss[9].snd[0], 1); gi = OBJECT_SIZE_BUILTIN(&ds1[9].snd[0], 1); - - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(&ds0[9].snd[0], 1); - - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(&dsv[9].snd[0], 1); } -// CHECK-LABEL: @test32 static struct DynStructVar D32 = { .fst = {}, .snd = { 0, 1, 2, }, }; unsigned long test32(void) { - // CHECK: ret i64 19 + // STATIC-LABEL: @test32 + // STATIC: ret i64 19 + + // DYNAMIC-LABEL: @test32 + // DYNAMIC: ret i64 19 + return OBJECT_SIZE_BUILTIN(&D32, 1); } -// CHECK-LABEL: @test33 static struct DynStructVar D33 = { .fst = {}, .snd = {}, }; unsigned long test33(void) { - // CHECK: ret i64 16 + // STATIC-LABEL: @test33 + // STATIC: ret i64 16 + + // DYNAMIC-LABEL: @test33 + // DYNAMIC: ret i64 16 + return OBJECT_SIZE_BUILTIN(&D33, 1); } -// CHECK-LABEL: @test34 + static struct DynStructVar D34 = { .fst = {}, }; unsigned long test34(void) { - // CHECK: ret i64 16 + // STATIC-LABEL: @test34 + // STATIC: ret i64 16 + + // DYNAMIC-LABEL: @test34 + // DYNAMIC: ret i64 16 + return OBJECT_SIZE_BUILTIN(&D34, 1); } -// CHECK-LABEL: @test35 unsigned long test35(void) { - // CHECK: ret i64 16 + // STATIC-LABEL: @test35 + // STATIC: ret i64 16 + + // DYNAMIC-LABEL: @test35 + // DYNAMIC: ret i64 16 + return OBJECT_SIZE_BUILTIN(&(struct DynStructVar){}, 1); } extern void *memset (void *s, int c, unsigned long n); @@ -563,15 +866,18 @@ void test36(void) { // given a struct with a flexible array member that lacks an initializer. memset(&D, 0, sizeof(D)); } -// CHECK-LABEL: @test37 struct Z { struct A { int x, y[]; } z; int a; int b[]; }; static struct Z my_z = { .b = {1,2,3} }; unsigned long test37 (void) { - // CHECK: ret i64 4 + // STATIC-LABEL: @test37 + // STATIC: ret i64 4 + + // DYNAMIC-LABEL: @test37 + // DYNAMIC: ret i64 4 + return OBJECT_SIZE_BUILTIN(&my_z.z, 1); } -// CHECK-LABEL: @PR30346 void PR30346(void) { struct sa_family_t {}; struct sockaddr { @@ -580,26 +886,42 @@ void PR30346(void) { }; struct sockaddr *sa; - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 + + // STATIC-LABEL: @PR30346 + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) + // STATIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) + // STATIC: store i32 14 + + // DYNAMIC-LABEL: @PR30346 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 true, i1 false, i64 14) + // DYNAMIC: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) + // DYNAMIC: store i32 14 + gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 2); - // CHECK: store i32 14 gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 3); } extern char incomplete_char_array[]; -// CHECK-LABEL: @incomplete_and_function_types int incomplete_and_function_types(void) { - // CHECK: call i64 @llvm.objectsize.i64.p0 + // STATIC-LABEL: @incomplete_and_function_types + // STATIC: call i64 @llvm.objectsize.i64.p0 + // STATIC: call i64 @llvm.objectsize.i64.p0 + // STATIC: call i64 @llvm.objectsize.i64.p0 + // STATIC: store i32 0 + + // DYNAMIC-LABEL: @incomplete_and_function_types + // DYNAMIC: call i64 @llvm.objectsize.i64.p0 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0 + // DYNAMIC: call i64 @llvm.objectsize.i64.p0 + // DYNAMIC: store i32 0 + gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 2); - // CHECK: store i32 0 gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 3); } @@ -616,8 +938,14 @@ void deeply_nested(void) { } b[2]; } *a; - // CHECK: store i32 4 + // STATIC-LABEL: @deeply_nested + // STATIC: store i32 4 + // STATIC: store i32 4 + + // DYNAMIC-LABEL: @deeply_nested + // DYNAMIC: store i32 4 + // DYNAMIC: store i32 4 + gi = OBJECT_SIZE_BUILTIN(&a->b[1].c[1].d[1].e[1], 1); - // CHECK: store i32 4 gi = OBJECT_SIZE_BUILTIN(&a->b[1].c[1].d[1].e[1], 3); } diff --git a/clang/test/CodeGen/object-size.cpp b/clang/test/CodeGen/object-size.cpp index e6ae3aefac2f8..7980400360616 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.p0(ptr %{{.*}}, i1 false, i1 true, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) gi = __builtin_object_size(&c->bs[0], 0); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 false, i64 0) gi = __builtin_object_size(&c->bs[0], 1); - // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) 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.p0(ptr %{{.*}}, i1 false, i1 true, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) 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.p0(ptr %{{.*}}, i1 true, i1 true, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) 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.p0(ptr %{{.*}}, i1 false, i1 true, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1 false, i1 true, i64 0) 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.p0(ptr %{{.*}}, i1 true, i1 true, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 true, i1 true, i1 false, i1 true, i64 0) 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/clang/test/CodeGen/pass-object-size.c b/clang/test/CodeGen/pass-object-size.c index c7c505b0fb3e7..20f56eb017b1c 100644 --- a/clang/test/CodeGen/pass-object-size.c +++ b/clang/test/CodeGen/pass-object-size.c @@ -85,16 +85,16 @@ void test1(unsigned long sz) { char *ptr = (char *)malloc(sz); - // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0({{.*}}, i1 false, i1 true, i1 true) + // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0({{.*}}, i1 false, i1 true, i1 true, i1 true, i64 0) // CHECK: call i32 @DynamicObjectSize0(ptr noundef %{{.*}}, i64 noundef [[REG]]) gi = DynamicObjectSize0(ptr); // CHECK: [[WITH_OFFSET:%.*]] = getelementptr - // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[WITH_OFFSET]], i1 false, i1 true, i1 true) + // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[WITH_OFFSET]], i1 false, i1 true, i1 true, i1 true, i64 0) // CHECK: call i32 @DynamicObjectSize0(ptr noundef {{.*}}, i64 noundef [[REG]]) gi = DynamicObjectSize0(ptr+10); - // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0({{.*}}, i1 true, i1 true, i1 true) + // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0({{.*}}, i1 true, i1 true, i1 true, i1 true, i64 0) // CHECK: call i32 @DynamicObjectSize2(ptr noundef {{.*}}, i64 noundef [[REG]]) gi = DynamicObjectSize2(ptr); } diff --git a/clang/test/CodeGen/sanitize-recover.c b/clang/test/CodeGen/sanitize-recover.c index fa53c2e7ca45e..e3806f0fdf16f 100644 --- a/clang/test/CodeGen/sanitize-recover.c +++ b/clang/test/CodeGen/sanitize-recover.c @@ -19,7 +19,7 @@ void test(void) { void foo(void) { union { int i; } u; u.i=1; - // PARTIAL: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 false) + // PARTIAL: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0(ptr {{.*}}, i1 false, i1 false, i1 true, i64 0) // PARTIAL-NEXT: %[[CHECK0:.*]] = icmp uge i64 %[[SIZE]], 4 // PARTIAL: br i1 %[[CHECK0]], {{.*}} !nosanitize diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index ecedd3a32c7b3..229cf386064f8 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -27031,8 +27031,8 @@ Syntax: :: - declare i32 @llvm.objectsize.i32(ptr , i1 , i1 , i1 ) - declare i64 @llvm.objectsize.i64(ptr , i1 , i1 , i1 ) + declare i32 @llvm.objectsize.i32(ptr , i1 , i1 , i1 , i1 , i64 ) + declare i64 @llvm.objectsize.i64(ptr , i1 , i1 , i1 , i1 , i64 ) Overview: """"""""" @@ -27046,18 +27046,35 @@ class, structure, array, or other object. Arguments: """""""""" -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. The fourth -argument to ``llvm.objectsize`` determines if the value should be evaluated at -runtime. +The ``llvm.objectsize`` intrinsic takes six arguments: + +- The first argument is a pointer to or into the ``object``. +- The second argument controls which value to return when the size is unknown: + + - If it's ``false``, ``llvm.objectsize`` returns ``-1``. + - If it's ``true``, ``llvm.objectsize`` returns ``0``. + +- 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``. + - If it's ``true``, or the ``null`` pointer is in a non-zero address space, + the size is assumed to be unknown. + +- The fourth argument to ``llvm.objectsize`` determines if the value should be + evaluated at runtime. +- The fifth argument controls which size ``llvm.objectsize`` returns: + + - If it's ``false``, ``llvm.objectsize`` returns the size of the closest + surrounding subobject. + - If it's ``true``, ``llvm.objectsize`` returns the size of the whole object. + +- If non-zero, the sixth argument encodes the size information, respectively, + of the original subobject's layout and is used when the fifth argument is + ``false``. -The second, third, and fourth arguments only accept constants. +The second, third, fourth, fifth, and sixth arguments accept only constants. Semantics: """""""""" diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h index 37ce1518f00c0..5f69e3b7cc846 100644 --- a/llvm/include/llvm/Analysis/MemoryBuiltins.h +++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h @@ -161,6 +161,14 @@ struct ObjectSizeOpts { /// though they can't be evaluated. Otherwise, null is always considered to /// point to a 0 byte region of memory. bool NullIsUnknownSize = false; + /// If this is true, return the whole size of the object. Otherwise, return + /// the size of the closest surrounding subobject. + /// FIXME: The default before being added was to return the whole size of the + /// object. Review if this is the correct default. + bool WholeObjectSize = true; + /// The layout of the sub-object: Size/Offset pair. Useful if WholeObjectSize + /// is false. + uint64_t SubobjectSize = 0; /// If set, used for more accurate evaluation AAResults *AA = nullptr; }; diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 144298fd7c016..88604c2165ef9 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1076,11 +1076,12 @@ def int_maximum : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], // Internal interface for object size checking def int_objectsize : DefaultAttrsIntrinsic<[llvm_anyint_ty], - [llvm_anyptr_ty, llvm_i1_ty, - llvm_i1_ty, llvm_i1_ty], + [llvm_anyptr_ty, llvm_i1_ty, llvm_i1_ty, + llvm_i1_ty, llvm_i1_ty, llvm_i64_ty], [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg>, ImmArg>, - ImmArg>]>, + ImmArg>, ImmArg>, + ImmArg>]>, ClangBuiltin<"__builtin_object_size">; //===--------------- Access to Floating Point Environment -----------------===// diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp index 46a7a921d86d3..9f58a82d61258 100644 --- a/llvm/lib/Analysis/MemoryBuiltins.cpp +++ b/llvm/lib/Analysis/MemoryBuiltins.cpp @@ -629,12 +629,18 @@ Value *llvm::lowerObjectSizeCall( EvalOptions.NullIsUnknownSize = cast(ObjectSize->getArgOperand(2))->isOne(); + EvalOptions.WholeObjectSize = + cast(ObjectSize->getArgOperand(4))->isOne(); + + EvalOptions.SubobjectSize = + cast(ObjectSize->getArgOperand(5))->getZExtValue(); auto *ResultType = cast(ObjectSize->getType()); - bool StaticOnly = cast(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`? + if (cast(ObjectSize->getArgOperand(3))->isZero()) { + // Static only. + // + // 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)) @@ -655,6 +661,9 @@ Value *llvm::lowerObjectSizeCall( Value *Size = SizeOffsetPair.Size; Value *Offset = SizeOffsetPair.Offset; + if (!EvalOptions.WholeObjectSize && EvalOptions.SubobjectSize) + Size = ConstantInt::get(Size->getType(), EvalOptions.SubobjectSize); + // If we've outside the end of the object, then we can always access // exactly 0 bytes. Value *ResultSize = Builder.CreateSub(Size, Offset); @@ -1193,7 +1202,15 @@ SizeOffsetValue ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) { return ObjectSizeOffsetEvaluator::unknown(); Value *Offset = emitGEPOffset(&Builder, DL, &GEP, /*NoAssumptions=*/true); - Offset = Builder.CreateAdd(PtrData.Offset, Offset); + + if (!EvalOpts.WholeObjectSize) + if (auto *Add = dyn_cast(Offset)) + for (auto I = Add->op_begin(), E = Add->op_end(); I != E; ++I) + if (auto *C = dyn_cast(I)) { + Offset = Builder.CreateSub(Offset, C); + break; + } + return SizeOffsetValue(PtrData.Size, Offset); } diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 25992395e471b..d723e96443423 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -4388,12 +4388,55 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { break; case Intrinsic::objectsize: { - Value *NullIsUnknownSize = - CI->arg_size() == 2 ? Builder.getFalse() : CI->getArgOperand(2); - Value *Dynamic = - CI->arg_size() < 4 ? Builder.getFalse() : CI->getArgOperand(3); - NewCall = Builder.CreateCall( - NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize, Dynamic}); + // The default behavior before the addition of the '' argument + // was to return the size of the whole object. + Value *UnknownVal = nullptr; + Value *NullIsUnknownSize = nullptr; + Value *Dynamic = nullptr; + Value *WholeObj = nullptr; + Value *SubobjectSize = nullptr; + + switch (CI->arg_size()) { + case 2: + UnknownVal = CI->getArgOperand(1); + NullIsUnknownSize = Builder.getFalse(); + Dynamic = Builder.getFalse(); + WholeObj = Builder.getTrue(); + SubobjectSize = Builder.getInt64(0); + break; + case 3: + UnknownVal = CI->getArgOperand(1); + NullIsUnknownSize = CI->getArgOperand(2); + Dynamic = Builder.getFalse(); + WholeObj = Builder.getTrue(); + SubobjectSize = Builder.getInt64(0); + break; + case 4: + UnknownVal = CI->getArgOperand(1); + NullIsUnknownSize = CI->getArgOperand(2); + Dynamic = CI->getArgOperand(3); + WholeObj = Builder.getTrue(); + SubobjectSize = Builder.getInt64(0); + break; + case 5: + UnknownVal = CI->getArgOperand(1); + NullIsUnknownSize = CI->getArgOperand(2); + Dynamic = CI->getArgOperand(3); + WholeObj = CI->getArgOperand(4); + SubobjectSize = Builder.getInt64(0); + break; + case 6: + UnknownVal = CI->getArgOperand(1); + NullIsUnknownSize = CI->getArgOperand(2); + Dynamic = CI->getArgOperand(3); + WholeObj = CI->getArgOperand(4); + SubobjectSize = CI->getArgOperand(5); + break; + } + + NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0), UnknownVal, + NullIsUnknownSize, Dynamic, WholeObj, + SubobjectSize}); break; } diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp index b1b15e9915aea..c47c496b1062f 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -1499,7 +1499,8 @@ bool AMDGPUPromoteAllocaImpl::tryPromoteAllocaToLDS(AllocaInst &I, CallInst *NewCall = Builder.CreateCall( ObjectSize, - {Src, Intr->getOperand(1), Intr->getOperand(2), Intr->getOperand(3)}); + {Src, Intr->getOperand(1), Intr->getOperand(2), Intr->getOperand(3), + Intr->getOperand(4), Intr->getOperand(5)}); Intr->replaceAllUsesWith(NewCall); Intr->eraseFromParent(); continue; diff --git a/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll b/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll index 1e9fd0df78922..954a36b76ddc5 100644 --- a/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll +++ b/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll @@ -21,7 +21,7 @@ define i32 @trivially_free() { ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a4 = call i1 @llvm.is.constant.i32(i32 undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0(i64 1, ptr undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.end.p0(i64 1, ptr undef) -; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true) +; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true, i1 true, i64 0) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a6 = call ptr @llvm.ptr.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.var.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef @@ -41,7 +41,7 @@ define i32 @trivially_free() { ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a4 = call i1 @llvm.is.constant.i32(i32 undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0(i64 1, ptr undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.end.p0(i64 1, ptr undef) -; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true) +; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true, i1 true, i64 0) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a6 = call ptr @llvm.ptr.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.var.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret i32 undef @@ -61,7 +61,7 @@ define i32 @trivially_free() { %a4 = call i1 @llvm.is.constant.i32(i32 undef) call void @llvm.lifetime.start.p0(i64 1, ptr undef) call void @llvm.lifetime.end.p0(i64 1, ptr undef) - %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 1, i1 1, i1 1) + %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 1, i1 1, i1 1, i1 1, i64 0) %a6 = call ptr @llvm.ptr.annotation.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) call void @llvm.var.annotation(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ret i32 undef @@ -82,7 +82,7 @@ declare ptr @llvm.strip.invariant.group.p0(ptr) declare i1 @llvm.is.constant.i32(i32) declare void @llvm.lifetime.start.p0(i64, ptr) declare void @llvm.lifetime.end.p0(i64, ptr) -declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1) +declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1, i1, i64) declare ptr @llvm.ptr.annotation.p0(ptr, ptr, ptr, i32, ptr) declare void @llvm.var.annotation(ptr, ptr, ptr, i32, ptr) diff --git a/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll b/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll index 4ebb1e314ba18..9a86fe665584d 100644 --- a/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll +++ b/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll @@ -23,7 +23,7 @@ define i32 @trivially_free() { ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a4 = call i1 @llvm.is.constant.i32(i32 undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0(i64 1, ptr undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.end.p0(i64 1, ptr undef) -; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true) +; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true, i1 true, i64 0) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a6 = call ptr @llvm.ptr.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.var.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef @@ -43,7 +43,7 @@ define i32 @trivially_free() { ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a4 = call i1 @llvm.is.constant.i32(i32 undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0(i64 1, ptr undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.end.p0(i64 1, ptr undef) -; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true) +; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true, i1 true, i64 0) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a6 = call ptr @llvm.ptr.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.var.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef @@ -63,7 +63,7 @@ define i32 @trivially_free() { %a4 = call i1 @llvm.is.constant.i32(i32 undef) call void @llvm.lifetime.start.p0(i64 1, ptr undef) call void @llvm.lifetime.end.p0(i64 1, ptr undef) - %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 1, i1 1, i1 1) + %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 1, i1 1, i1 1, i1 1, i64 0) %a6 = call ptr @llvm.ptr.annotation.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) call void @llvm.var.annotation(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ret i32 undef @@ -84,7 +84,7 @@ declare ptr @llvm.strip.invariant.group.p0(ptr) declare i1 @llvm.is.constant.i32(i32) declare void @llvm.lifetime.start.p0(i64, ptr) declare void @llvm.lifetime.end.p0(i64, ptr) -declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1) +declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1, i1, i64) declare ptr @llvm.ptr.annotation.p0(ptr, ptr, ptr, i32, ptr) declare void @llvm.var.annotation(ptr, ptr, ptr, i32, ptr) diff --git a/llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll b/llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll index 5d47e48944271..ebd787a5a66dc 100644 --- a/llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll +++ b/llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll @@ -21,7 +21,7 @@ define i32 @trivially_free() { ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a4 = call i1 @llvm.is.constant.i32(i32 undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0(i64 1, ptr undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.end.p0(i64 1, ptr undef) -; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true) +; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true, i1 true, i64 0) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a6 = call ptr @llvm.ptr.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.var.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef @@ -41,7 +41,7 @@ define i32 @trivially_free() { ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a4 = call i1 @llvm.is.constant.i32(i32 undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0(i64 1, ptr undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.end.p0(i64 1, ptr undef) -; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true) +; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true, i1 true, i64 0) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %a6 = call ptr @llvm.ptr.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.var.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ; CHECK-THROUGHPUT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef @@ -61,7 +61,7 @@ define i32 @trivially_free() { %a4 = call i1 @llvm.is.constant.i32(i32 undef) call void @llvm.lifetime.start.p0(i64 1, ptr undef) call void @llvm.lifetime.end.p0(i64 1, ptr undef) - %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 1, i1 1, i1 1) + %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 1, i1 1, i1 1, i1 1, i64 0) %a6 = call ptr @llvm.ptr.annotation.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) call void @llvm.var.annotation(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef) ret i32 undef @@ -82,7 +82,7 @@ declare ptr @llvm.strip.invariant.group.p0(ptr) declare i1 @llvm.is.constant.i32(i32) declare void @llvm.lifetime.start.p0(i64, ptr) declare void @llvm.lifetime.end.p0(i64, ptr) -declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1) +declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1, i1, i64) declare ptr @llvm.ptr.annotation.p0(ptr, ptr, ptr, i32, ptr) declare void @llvm.var.annotation(ptr, ptr, ptr, i32, ptr) diff --git a/llvm/test/Assembler/auto_upgrade_intrinsics.ll b/llvm/test/Assembler/auto_upgrade_intrinsics.ll index e3603846e9e9b..bcf4fb5f0cdaf 100644 --- a/llvm/test/Assembler/auto_upgrade_intrinsics.ll +++ b/llvm/test/Assembler/auto_upgrade_intrinsics.ll @@ -60,7 +60,7 @@ define void @test.coro.end(ptr %ptr) { declare i32 @llvm.objectsize.i32(ptr, i1) nounwind readonly define i32 @test.objectsize() { ; CHECK-LABEL: @test.objectsize( -; CHECK: @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) +; CHECK: @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) %s = call i32 @llvm.objectsize.i32(ptr @a, i1 false) ret i32 %s } @@ -68,7 +68,7 @@ define i32 @test.objectsize() { declare i64 @llvm.objectsize.i64.p0(ptr, i1) nounwind readonly define i64 @test.objectsize.2() { ; CHECK-LABEL: @test.objectsize.2( -; CHECK: @llvm.objectsize.i64.p0(ptr @a, i1 false, i1 false, i1 false) +; CHECK: @llvm.objectsize.i64.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) %s = call i64 @llvm.objectsize.i64.p0(ptr @a, i1 false) ret i64 %s } @@ -78,14 +78,14 @@ define i64 @test.objectsize.2() { declare i32 @llvm.objectsize.i32.unnamed(ptr, i1) nounwind readonly define i32 @test.objectsize.unnamed() { ; CHECK-LABEL: @test.objectsize.unnamed( -; CHECK: @llvm.objectsize.i32.p0(ptr @u, i1 false, i1 false, i1 false) +; CHECK: @llvm.objectsize.i32.p0(ptr @u, i1 false, i1 false, i1 false, i1 true, i64 0) %s = call i32 @llvm.objectsize.i32.unnamed(ptr @u, i1 false) ret i32 %s } define i64 @test.objectsize.unnamed.2() { ; CHECK-LABEL: @test.objectsize.unnamed.2( -; CHECK: @llvm.objectsize.i64.p0(ptr @u, i1 false, i1 false, i1 false) +; CHECK: @llvm.objectsize.i64.p0(ptr @u, i1 false, i1 false, i1 false, i1 true, i64 0) %s = call i64 @llvm.objectsize.i64.p0(ptr @u, i1 false) ret i64 %s } diff --git a/llvm/test/Bitcode/objectsize-upgrade-7.0.ll b/llvm/test/Bitcode/objectsize-upgrade-7.0.ll index 5390fc91f2b26..c36de3707e7e5 100644 --- a/llvm/test/Bitcode/objectsize-upgrade-7.0.ll +++ b/llvm/test/Bitcode/objectsize-upgrade-7.0.ll @@ -4,9 +4,9 @@ define void @callit(i8* %ptr) { %sz = call i64 @llvm.objectsize.i64.p0i8(i8* %ptr, i1 false, i1 true) - ; CHECK: %sz = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false) + ; CHECK: %sz = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false, i1 true, i64 0) ret void } declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1) -; CHECK: declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg) +; CHECK: declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/memcpy_chk_no_tail.ll b/llvm/test/CodeGen/AArch64/GlobalISel/memcpy_chk_no_tail.ll index 263dfbdc139be..cbefd1ebf59ca 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/memcpy_chk_no_tail.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/memcpy_chk_no_tail.ll @@ -11,7 +11,7 @@ target triple = "arm64-apple-ios13.0.0" ; CHECK: bl _memcpy define void @usqrt(i32 %x, ptr %q) local_unnamed_addr #0 { %a = alloca i32, align 4 - %obj = tail call i64 @llvm.objectsize.i64.p0(ptr %q, i1 false, i1 true, i1 false) + %obj = tail call i64 @llvm.objectsize.i64.p0(ptr %q, i1 false, i1 true, i1 false, i1 true, i64 0) %call = call ptr @__memcpy_chk(ptr %q, ptr nonnull %a, i64 1000, i64 %obj) #4 ret void } @@ -20,7 +20,7 @@ define void @usqrt(i32 %x, ptr %q) local_unnamed_addr #0 { declare ptr @__memcpy_chk(ptr, ptr, i64, i64) local_unnamed_addr #2 ; Function Attrs: nounwind readnone speculatable willreturn -declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg) #3 +declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) #3 attributes #0 = { optsize "disable-tail-calls"="false" "frame-pointer"="all" } attributes #2 = { nofree nounwind "disable-tail-calls"="false" "frame-pointer"="all" } attributes #3 = { nounwind readnone speculatable willreturn } diff --git a/llvm/test/CodeGen/AArch64/memsize-remarks.ll b/llvm/test/CodeGen/AArch64/memsize-remarks.ll index 93e3d6fb02607..3e4382551998b 100644 --- a/llvm/test/CodeGen/AArch64/memsize-remarks.ll +++ b/llvm/test/CodeGen/AArch64/memsize-remarks.ll @@ -8,7 +8,7 @@ target triple = "arm64-apple-ios7.0.0" declare ptr @__memmove_chk(ptr, ptr, i64, i64) #1 declare ptr @__memcpy_chk(ptr, ptr, i64, i64) #1 declare ptr @__memset_chk(ptr, i32, i64, i64) #1 -declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg) #2 +declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) #2 declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) argmemonly nounwind willreturn writeonly declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1 immarg) argmemonly nounwind willreturn declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) argmemonly nounwind willreturn @@ -18,7 +18,7 @@ declare ptr @memset(ptr, i32, i64) define void @memcpy_dynamic(ptr %d, ptr %s, i64 %l) #0 !dbg !14 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false), !dbg !16 + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0), !dbg !16 ; GISEL: remark: memsize.c:4:3: Call to memcpy.{{$}} %call = call ptr @__memcpy_chk(ptr %d, ptr %s, i64 %l, i64 %0) #4, !dbg !17 ret void, !dbg !18 @@ -26,7 +26,7 @@ entry: define void @memcpy_single(ptr %d, ptr %s, i64 %l) #0 !dbg !23 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false), !dbg !24 + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0), !dbg !24 ; GISEL: remark: memsize.c:10:3: Call to memcpy. Memory operation size: 1 bytes. %call = call ptr @__memcpy_chk(ptr %d, ptr %s, i64 1, i64 %0) #4, !dbg !25 ret void, !dbg !26 @@ -34,7 +34,7 @@ entry: define void @memcpy_intrinsic(ptr %d, ptr %s, i64 %l) #0 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false) + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0) ; GISEL: remark: :0:0: Call to memcpy. Memory operation size: 1 bytes. call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 1, i1 false) ret void @@ -42,7 +42,7 @@ entry: define void @memcpy_static(ptr %d, ptr %s, i64 %l) #0 !dbg !27 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false), !dbg !28 + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0), !dbg !28 ; GISEL: remark: memsize.c:13:3: Call to memcpy. Memory operation size: 100 bytes. %call = call ptr @__memcpy_chk(ptr %d, ptr %s, i64 100, i64 %0) #4, !dbg !29 ret void, !dbg !30 @@ -50,7 +50,7 @@ entry: define void @memcpy_huge(ptr %d, ptr %s, i64 %l) #0 !dbg !31 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false), !dbg !32 + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0), !dbg !32 ; GISEL: remark: memsize.c:16:3: Call to memcpy. Memory operation size: 100000 bytes. %call = call ptr @__memcpy_chk(ptr %d, ptr %s, i64 100000, i64 %0) #4, !dbg !33 ret void, !dbg !34 @@ -58,7 +58,7 @@ entry: define void @memmove_dynamic(ptr %d, ptr %s, i64 %l) #0 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false) + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0) ; GISEL: remark: :0:0: Call to memmove.{{$}} %call = call ptr @__memmove_chk(ptr %d, ptr %s, i64 %l, i64 %0) #4 ret void @@ -66,7 +66,7 @@ entry: define void @memmove_single(ptr %d, ptr %s, i64 %l) #0 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false) + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0) ; GISEL: remark: :0:0: Call to memmove. Memory operation size: 1 bytes. %call = call ptr @__memmove_chk(ptr %d, ptr %s, i64 1, i64 %0) #4 ret void @@ -74,7 +74,7 @@ entry: define void @memmove_static(ptr %d, ptr %s, i64 %l) #0 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false) + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0) ; GISEL: remark: :0:0: Call to memmove. Memory operation size: 100 bytes. %call = call ptr @__memmove_chk(ptr %d, ptr %s, i64 100, i64 %0) #4 ret void @@ -82,7 +82,7 @@ entry: define void @memmove_huge(ptr %d, ptr %s, i64 %l) #0 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false) + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0) ; GISEL: remark: :0:0: Call to memmove. Memory operation size: 100000 bytes. %call = call ptr @__memmove_chk(ptr %d, ptr %s, i64 100000, i64 %0) #4 ret void @@ -90,7 +90,7 @@ entry: define void @memset_dynamic(ptr %d, i64 %l) #0 !dbg !38 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false), !dbg !39 + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0), !dbg !39 ; GISEL: remark: memsize.c:22:3: Call to memset.{{$}} %call = call ptr @__memset_chk(ptr %d, i32 0, i64 %l, i64 %0) #4, !dbg !40 ret void, !dbg !41 @@ -98,7 +98,7 @@ entry: define void @memset_single(ptr %d, i64 %l) #0 !dbg !46 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false), !dbg !47 + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0), !dbg !47 ; GISEL: remark: memsize.c:28:3: Call to memset. Memory operation size: 1 bytes. %call = call ptr @__memset_chk(ptr %d, i32 0, i64 1, i64 %0) #4, !dbg !48 ret void, !dbg !49 @@ -106,7 +106,7 @@ entry: define void @memset_static(ptr %d, i64 %l) #0 !dbg !50 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false), !dbg !51 + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0), !dbg !51 ; GISEL: remark: memsize.c:31:3: Call to memset. Memory operation size: 100 bytes. %call = call ptr @__memset_chk(ptr %d, i32 0, i64 100, i64 %0) #4, !dbg !52 ret void, !dbg !53 @@ -114,7 +114,7 @@ entry: define void @memset_huge(ptr %d, i64 %l) #0 !dbg !54 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false), !dbg !55 + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0), !dbg !55 ; GISEL: remark: memsize.c:34:3: Call to memset. Memory operation size: 100000 bytes. %call = call ptr @__memset_chk(ptr %d, i32 0, i64 100000, i64 %0) #4, !dbg !56 ret void, !dbg !57 @@ -122,7 +122,7 @@ entry: define void @memset_empty(ptr %d, i64 %l) #0 !dbg !42 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false), !dbg !43 + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0), !dbg !43 ; GISEL: remark: memsize.c:25:3: Call to memset. Memory operation size: 0 bytes. %call = call ptr @__memset_chk(ptr %d, i32 0, i64 0, i64 %0) #4, !dbg !44 ret void, !dbg !45 @@ -131,7 +131,7 @@ entry: ; YAML-LABEL: Function: memcpy_empty define void @memcpy_empty(ptr %d, ptr %s, i64 %l) #0 !dbg !19 { entry: - %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false), !dbg !20 + %0 = call i64 @llvm.objectsize.i64.p0(ptr %d, i1 false, i1 true, i1 false, i1 true, i64 0), !dbg !20 ; GISEL: remark: memsize.c:7:3: Call to memcpy. Memory operation size: 0 bytes. %call = call ptr @__memcpy_chk(ptr %d, ptr %s, i64 0, i64 %0) #4, !dbg !21 ret void, !dbg !22 diff --git a/llvm/test/CodeGen/AMDGPU/promote-alloca-mem-intrinsics.ll b/llvm/test/CodeGen/AMDGPU/promote-alloca-mem-intrinsics.ll index aabd5df956837..f9dfaa9513923 100644 --- a/llvm/test/CodeGen/AMDGPU/promote-alloca-mem-intrinsics.ll +++ b/llvm/test/CodeGen/AMDGPU/promote-alloca-mem-intrinsics.ll @@ -10,7 +10,7 @@ declare void @llvm.memmove.p5.p5.i64(ptr addrspace(5) nocapture, ptr addrspace(5 declare void @llvm.memset.p5.i32(ptr addrspace(5) nocapture, i8, i32, i1) #0 -declare i32 @llvm.objectsize.i32.p5(ptr addrspace(5), i1, i1, i1) #1 +declare i32 @llvm.objectsize.i32.p5(ptr addrspace(5), i1, i1, i1, i1, i64) #1 ; CHECK-LABEL: @promote_with_memcpy( ; CHECK: [[GEP:%[0-9]+]] = getelementptr inbounds [64 x [17 x i32]], ptr addrspace(3) @promote_with_memcpy.alloca, i32 0, i32 %{{[0-9]+}} @@ -45,10 +45,10 @@ define amdgpu_kernel void @promote_with_memset(ptr addrspace(1) %out, ptr addrsp ; CHECK-LABEL: @promote_with_objectsize( ; CHECK: [[PTR:%[0-9]+]] = getelementptr inbounds [64 x [17 x i32]], ptr addrspace(3) @promote_with_objectsize.alloca, i32 0, i32 %{{[0-9]+}} -; CHECK: call i32 @llvm.objectsize.i32.p3(ptr addrspace(3) [[PTR]], i1 false, i1 false, i1 false) +; CHECK: call i32 @llvm.objectsize.i32.p3(ptr addrspace(3) [[PTR]], i1 false, i1 false, i1 false, i1 true, i64 0) define amdgpu_kernel void @promote_with_objectsize(ptr addrspace(1) %out) #0 { %alloca = alloca [17 x i32], align 4, addrspace(5) - %size = call i32 @llvm.objectsize.i32.p5(ptr addrspace(5) %alloca, i1 false, i1 false, i1 false) + %size = call i32 @llvm.objectsize.i32.p5(ptr addrspace(5) %alloca, i1 false, i1 false, i1 false, i1 true, i64 0) store i32 %size, ptr addrspace(1) %out ret void } @@ -57,7 +57,7 @@ define amdgpu_kernel void @promote_with_objectsize(ptr addrspace(1) %out) #0 { ; CHECK: store i32 32, ptr addrspace(1) %out, align 4 define amdgpu_kernel void @promote_with_objectsize_8(ptr addrspace(1) %out) #0 { %alloca = alloca [8 x i32], align 4, addrspace(5) - %size = call i32 @llvm.objectsize.i32.p5(ptr addrspace(5) %alloca, i1 false, i1 false, i1 false) + %size = call i32 @llvm.objectsize.i32.p5(ptr addrspace(5) %alloca, i1 false, i1 false, i1 false, i1 true, i64 0) store i32 %size, ptr addrspace(1) %out ret void } diff --git a/llvm/test/Instrumentation/BoundsChecking/simple.ll b/llvm/test/Instrumentation/BoundsChecking/simple.ll index 60d124f0b8973..fa919d790525d 100644 --- a/llvm/test/Instrumentation/BoundsChecking/simple.ll +++ b/llvm/test/Instrumentation/BoundsChecking/simple.ll @@ -106,15 +106,14 @@ define void @f4(i64 %x) nounwind { define void @f5(i64 %x) nounwind { ; CHECK-LABEL: @f5( -; CHECK-NEXT: [[TMP1:%.*]] = add i64 0, [[X:%.*]] -; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [8 x i8], ptr @.str, i64 0, i64 [[X]] -; CHECK-NEXT: [[TMP2:%.*]] = sub i64 8, [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 8, [[TMP1]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP2]], 1 -; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]] -; CHECK-NEXT: br i1 [[TMP5]], label [[TRAP:%.*]], label [[TMP6:%.*]] -; CHECK: 6: -; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[IDX]], align 4 +; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [8 x i8], ptr @.str, i64 0, i64 [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = sub i64 8, [[X]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 8, [[X]] +; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP1]], 1 +; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP2]], [[TMP3]] +; CHECK-NEXT: br i1 [[TMP4]], label [[TRAP:%.*]], label [[TMP5:%.*]] +; CHECK: 5: +; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[IDX]], align 4 ; CHECK-NEXT: ret void ; CHECK: trap: ; CHECK-NEXT: call void @llvm.trap() #[[ATTR6]] @@ -128,15 +127,14 @@ define void @f5(i64 %x) nounwind { define void @f5_as1(i64 %x) nounwind { ; CHECK-LABEL: @f5_as1( ; CHECK-NEXT: [[X_C:%.*]] = trunc i64 [[X:%.*]] to i16 -; CHECK-NEXT: [[TMP1:%.*]] = add i16 0, [[X_C]] ; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [8 x i8], ptr addrspace(1) @.str_as1, i64 0, i64 [[X]] -; CHECK-NEXT: [[TMP2:%.*]] = sub i16 8, [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i16 8, [[TMP1]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i16 [[TMP2]], 1 -; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]] -; CHECK-NEXT: br i1 [[TMP5]], label [[TRAP:%.*]], label [[TMP6:%.*]] -; CHECK: 6: -; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr addrspace(1) [[IDX]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = sub i16 8, [[X_C]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i16 8, [[X_C]] +; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i16 [[TMP1]], 1 +; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP2]], [[TMP3]] +; CHECK-NEXT: br i1 [[TMP4]], label [[TRAP:%.*]], label [[TMP5:%.*]] +; CHECK: 5: +; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr addrspace(1) [[IDX]], align 4 ; CHECK-NEXT: ret void ; CHECK: trap: ; CHECK-NEXT: call void @llvm.trap() #[[ATTR6]] @@ -150,15 +148,14 @@ define void @f5_as1(i64 %x) nounwind { define void @f5_as2(i32 %x) nounwind {; ; CHECK-LABEL: @f5_as2( ; CHECK-NEXT: [[X_C:%.*]] = sext i32 [[X:%.*]] to i48 -; CHECK-NEXT: [[TMP1:%.*]] = add i48 0, [[X_C]] ; CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [8 x i8], ptr addrspace(2) @.str_as2, i32 0, i32 [[X]] -; CHECK-NEXT: [[TMP2:%.*]] = sub i48 8, [[TMP1]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i48 8, [[TMP1]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i48 [[TMP2]], 1 -; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]] -; CHECK-NEXT: br i1 [[TMP5]], label [[TRAP:%.*]], label [[TMP6:%.*]] -; CHECK: 6: -; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr addrspace(2) [[IDX]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = sub i48 8, [[X_C]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i48 8, [[X_C]] +; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i48 [[TMP1]], 1 +; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP2]], [[TMP3]] +; CHECK-NEXT: br i1 [[TMP4]], label [[TRAP:%.*]], label [[TMP5:%.*]] +; CHECK: 5: +; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr addrspace(2) [[IDX]], align 4 ; CHECK-NEXT: ret void ; CHECK: trap: ; CHECK-NEXT: call void @llvm.trap() #[[ATTR6]] @@ -293,18 +290,17 @@ define i64 @f12(i64 %x, i64 %y) nounwind { ; CHECK-NEXT: [[TMP1:%.*]] = mul i64 1, [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = tail call ptr @calloc(i64 1, i64 [[X]]) ; CHECK-NEXT: [[DOTIDX:%.*]] = mul i64 [[Y:%.*]], 8 -; CHECK-NEXT: [[TMP3:%.*]] = add i64 0, [[DOTIDX]] -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i64 [[Y]] -; CHECK-NEXT: [[TMP5:%.*]] = sub i64 [[TMP1]], [[TMP3]] -; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i64 [[TMP1]], [[TMP3]] -; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i64 [[TMP5]], 8 -; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] -; CHECK-NEXT: [[TMP9:%.*]] = icmp slt i64 [[TMP3]], 0 -; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP9]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP10]], label [[TRAP:%.*]], label [[TMP11:%.*]] -; CHECK: 11: -; CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr [[TMP4]], align 8 -; CHECK-NEXT: ret i64 [[TMP12]] +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i64 [[Y]] +; CHECK-NEXT: [[TMP4:%.*]] = sub i64 [[TMP1]], [[DOTIDX]] +; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i64 [[TMP1]], [[DOTIDX]] +; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i64 [[TMP4]], 8 +; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]] +; CHECK-NEXT: [[TMP8:%.*]] = icmp slt i64 [[DOTIDX]], 0 +; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP8]], [[TMP7]] +; CHECK-NEXT: br i1 [[TMP9]], label [[TRAP:%.*]], label [[TMP10:%.*]] +; CHECK: 10: +; CHECK-NEXT: [[TMP11:%.*]] = load i64, ptr [[TMP3]], align 8 +; CHECK-NEXT: ret i64 [[TMP11]] ; CHECK: trap: ; CHECK-NEXT: call void @llvm.trap() #[[ATTR6]] ; CHECK-NEXT: unreachable @@ -367,14 +363,13 @@ define i8 @f14(i1 %i) { ; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ 32, [[BB1]] ] ; CHECK-NEXT: [[ALLOC:%.*]] = phi ptr [ null, [[ENTRY]] ], [ [[G]], [[BB1]] ] ; CHECK-NEXT: [[IND:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ -4, [[BB1]] ] -; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[IND]] ; CHECK-NEXT: [[P:%.*]] = getelementptr i8, ptr [[ALLOC]], i64 [[IND]] -; CHECK-NEXT: [[TMP3:%.*]] = sub i64 [[TMP0]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP0]], [[TMP2]] -; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i64 [[TMP3]], 1 -; CHECK-NEXT: [[TMP6:%.*]] = or i1 [[TMP4]], [[TMP5]] -; CHECK-NEXT: br i1 [[TMP6]], label [[TRAP:%.*]], label [[TMP7:%.*]] -; CHECK: 7: +; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[TMP0]], [[IND]] +; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP0]], [[IND]] +; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP2]], 1 +; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]] +; CHECK-NEXT: br i1 [[TMP5]], label [[TRAP:%.*]], label [[TMP6:%.*]] +; CHECK: 6: ; CHECK-NEXT: [[RET:%.*]] = load i8, ptr [[P]], align 1 ; CHECK-NEXT: ret i8 [[RET]] ; CHECK: trap: @@ -443,16 +438,15 @@ define <4 x i32> @load_vector(i64 %y) nounwind { ; CHECK-LABEL: @load_vector( ; CHECK-NEXT: [[TMP1:%.*]] = tail call ptr @calloc(i64 1, i64 256) ; CHECK-NEXT: [[DOTIDX:%.*]] = mul i64 [[Y:%.*]], 8 -; CHECK-NEXT: [[TMP2:%.*]] = add i64 0, [[DOTIDX]] -; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i64 [[Y]] -; CHECK-NEXT: [[TMP4:%.*]] = sub i64 256, [[TMP2]] -; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i64 256, [[TMP2]] -; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i64 [[TMP4]], 16 -; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]] -; CHECK-NEXT: br i1 [[TMP7]], label [[TRAP:%.*]], label [[TMP8:%.*]] -; CHECK: 8: -; CHECK-NEXT: [[TMP9:%.*]] = load <4 x i32>, ptr [[TMP3]], align 8 -; CHECK-NEXT: ret <4 x i32> [[TMP9]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i64 [[Y]] +; CHECK-NEXT: [[TMP3:%.*]] = sub i64 256, [[DOTIDX]] +; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i64 256, [[DOTIDX]] +; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i64 [[TMP3]], 16 +; CHECK-NEXT: [[TMP6:%.*]] = or i1 [[TMP4]], [[TMP5]] +; CHECK-NEXT: br i1 [[TMP6]], label [[TRAP:%.*]], label [[TMP7:%.*]] +; CHECK: 7: +; CHECK-NEXT: [[TMP8:%.*]] = load <4 x i32>, ptr [[TMP2]], align 8 +; CHECK-NEXT: ret <4 x i32> [[TMP8]] ; CHECK: trap: ; CHECK-NEXT: call void @llvm.trap() #[[ATTR6]] ; CHECK-NEXT: unreachable @@ -467,18 +461,17 @@ define @load_scalable_vector(i64 %y) nounwind { ; CHECK-LABEL: @load_scalable_vector( ; CHECK-NEXT: [[TMP1:%.*]] = tail call ptr @calloc(i64 1, i64 256) ; CHECK-NEXT: [[DOTIDX:%.*]] = mul i64 [[Y:%.*]], 8 -; CHECK-NEXT: [[TMP2:%.*]] = add i64 0, [[DOTIDX]] -; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i64 [[Y]] -; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.vscale.i64() -; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP4]], 4 -; CHECK-NEXT: [[TMP6:%.*]] = sub i64 256, [[TMP2]] -; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i64 256, [[TMP2]] -; CHECK-NEXT: [[TMP8:%.*]] = icmp ult i64 [[TMP6]], [[TMP5]] -; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]] -; CHECK-NEXT: br i1 [[TMP9]], label [[TRAP:%.*]], label [[TMP10:%.*]] -; CHECK: 10: -; CHECK-NEXT: [[TMP11:%.*]] = load , ptr [[TMP3]], align 8 -; CHECK-NEXT: ret [[TMP11]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i64 [[Y]] +; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[TMP3]], 4 +; CHECK-NEXT: [[TMP5:%.*]] = sub i64 256, [[DOTIDX]] +; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i64 256, [[DOTIDX]] +; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i64 [[TMP5]], [[TMP4]] +; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] +; CHECK-NEXT: br i1 [[TMP8]], label [[TRAP:%.*]], label [[TMP9:%.*]] +; CHECK: 9: +; CHECK-NEXT: [[TMP10:%.*]] = load , ptr [[TMP2]], align 8 +; CHECK-NEXT: ret [[TMP10]] ; CHECK: trap: ; CHECK-NEXT: call void @llvm.trap() #[[ATTR6]] ; CHECK-NEXT: unreachable diff --git a/llvm/test/Other/cgscc-libcall-update.ll b/llvm/test/Other/cgscc-libcall-update.ll index 05dc0cfb60685..263f64ddeb1cd 100644 --- a/llvm/test/Other/cgscc-libcall-update.ll +++ b/llvm/test/Other/cgscc-libcall-update.ll @@ -14,7 +14,7 @@ bb: %tmp = alloca [1024 x i8], align 16 call void @llvm.memcpy.p0.p0.i64(ptr %tmp, ptr %arg1, i64 1024, i1 false) ; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(1024) - %tmp3 = call i64 @llvm.objectsize.i64.p0(ptr %tmp, i1 false, i1 true, i1 false) + %tmp3 = call i64 @llvm.objectsize.i64.p0(ptr %tmp, i1 false, i1 true, i1 false, i1 true, i64 0) %tmp4 = call ptr @__strncpy_chk(ptr %arg2, ptr %tmp, i64 1023, i64 %tmp3) ; CHECK-NOT: call ; CHECK: call ptr @strncpy(ptr noundef nonnull dereferenceable(1) %arg2, ptr noundef nonnull dereferenceable(1) %tmp, i64 1023) @@ -34,7 +34,7 @@ bb: declare ptr @my_special_strncpy(ptr %arg1, ptr %arg2, i64 %size) -declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1) +declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1, i1, i64) declare ptr @__strncpy_chk(ptr, ptr, i64, i64) diff --git a/llvm/test/Transforms/InferAddressSpaces/AMDGPU/debug-info.ll b/llvm/test/Transforms/InferAddressSpaces/AMDGPU/debug-info.ll index f636aa24d87c3..5a5ad236966db 100644 --- a/llvm/test/Transforms/InferAddressSpaces/AMDGPU/debug-info.ll +++ b/llvm/test/Transforms/InferAddressSpaces/AMDGPU/debug-info.ll @@ -25,10 +25,10 @@ define void @simplified_constexpr_gep_addrspacecast(i64 %idx0, i64 %idx1) #0 !db } ; CHECK-LABEL: @objectsize_group_to_flat_i32( -; CHECK: %val = call i32 @llvm.objectsize.i32.p3(ptr addrspace(3) %group.ptr, i1 true, i1 false, i1 false), !dbg ![[DEBUG_LOC_VAL:[0-9]+]] +; CHECK: %val = call i32 @llvm.objectsize.i32.p3(ptr addrspace(3) %group.ptr, i1 true, i1 false, i1 false, i1 true, i64 0), !dbg ![[DEBUG_LOC_VAL:[0-9]+]] define i32 @objectsize_group_to_flat_i32(ptr addrspace(3) %group.ptr) #0 !dbg !16 { %cast = addrspacecast ptr addrspace(3) %group.ptr to ptr, !dbg !17 - %val = call i32 @llvm.objectsize.i32.p0(ptr %cast, i1 true, i1 false, i1 false), !dbg !18 + %val = call i32 @llvm.objectsize.i32.p0(ptr %cast, i1 true, i1 false, i1 false, i1 true, i64 0), !dbg !18 ret i32 %val, !dbg !19 } @@ -66,7 +66,7 @@ entry: ret float %arrayidx.load, !dbg !45 } -declare i32 @llvm.objectsize.i32.p0(ptr, i1 immarg, i1 immarg, i1 immarg) #1 +declare i32 @llvm.objectsize.i32.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) #1 declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #2 declare ptr @llvm.ptrmask.p0.i64(ptr, i64) #3 declare i1 @llvm.amdgcn.is.shared(ptr nocapture) #4 @@ -140,4 +140,4 @@ attributes #4 = { nounwind readnone speculatable } !42 = !DILocation(line: 22, column: 1, scope: !37) !43 = !DILocation(line: 23, column: 1, scope: !37) !44 = !DILocation(line: 24, column: 1, scope: !37) -!45 = !DILocation(line: 25, column: 1, scope: !37) \ No newline at end of file +!45 = !DILocation(line: 25, column: 1, scope: !37) diff --git a/llvm/test/Transforms/InferAddressSpaces/AMDGPU/intrinsics.ll b/llvm/test/Transforms/InferAddressSpaces/AMDGPU/intrinsics.ll index 2743f1749adc0..b0610f184f369 100644 --- a/llvm/test/Transforms/InferAddressSpaces/AMDGPU/intrinsics.ll +++ b/llvm/test/Transforms/InferAddressSpaces/AMDGPU/intrinsics.ll @@ -1,23 +1,23 @@ ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=infer-address-spaces %s | FileCheck %s ; CHECK-LABEL: @objectsize_group_to_flat_i32( -; CHECK: %val = call i32 @llvm.objectsize.i32.p3(ptr addrspace(3) %group.ptr, i1 true, i1 false, i1 false) +; CHECK: %val = call i32 @llvm.objectsize.i32.p3(ptr addrspace(3) %group.ptr, i1 true, i1 false, i1 false, i1 true, i64 0) define i32 @objectsize_group_to_flat_i32(ptr addrspace(3) %group.ptr) #0 { %cast = addrspacecast ptr addrspace(3) %group.ptr to ptr - %val = call i32 @llvm.objectsize.i32.p0(ptr %cast, i1 true, i1 false, i1 false) + %val = call i32 @llvm.objectsize.i32.p0(ptr %cast, i1 true, i1 false, i1 false, i1 true, i64 0) ret i32 %val } ; CHECK-LABEL: @objectsize_global_to_flat_i64( -; CHECK: %val = call i64 @llvm.objectsize.i64.p3(ptr addrspace(3) %global.ptr, i1 true, i1 false, i1 false) +; CHECK: %val = call i64 @llvm.objectsize.i64.p3(ptr addrspace(3) %global.ptr, i1 true, i1 false, i1 false, i1 true, i64 0) define i64 @objectsize_global_to_flat_i64(ptr addrspace(3) %global.ptr) #0 { %cast = addrspacecast ptr addrspace(3) %global.ptr to ptr - %val = call i64 @llvm.objectsize.i64.p0(ptr %cast, i1 true, i1 false, i1 false) + %val = call i64 @llvm.objectsize.i64.p0(ptr %cast, i1 true, i1 false, i1 false, i1 true, i64 0) ret i64 %val } -declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1) #1 -declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1) #1 +declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1, i1, i64) #1 +declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1, i1, i64) #1 attributes #0 = { nounwind } attributes #1 = { nounwind readnone } diff --git a/llvm/test/Transforms/InferAlignment/propagate-assume.ll b/llvm/test/Transforms/InferAlignment/propagate-assume.ll index 8cf0cb35035ed..e0abb1b1b05c1 100644 --- a/llvm/test/Transforms/InferAlignment/propagate-assume.ll +++ b/llvm/test/Transforms/InferAlignment/propagate-assume.ll @@ -193,7 +193,7 @@ define void @complex_backpropagate(ptr %a, ptr %b, ptr %c) { ; CHECK-NEXT: [[LOAD_A:%.*]] = load i32, ptr [[A]], align 32 ; CHECK-NEXT: [[LOAD_B:%.*]] = load i32, ptr [[B]], align 4 ; CHECK-NEXT: store i32 [[LOAD_B]], ptr [[A]], align 32 -; CHECK-NEXT: [[OBJ_SIZE:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[C]], i1 false, i1 false, i1 false) +; CHECK-NEXT: [[OBJ_SIZE:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[C]], i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: store i64 [[OBJ_SIZE]], ptr [[ALLOCA]], align 8 ; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A]] to i64 ; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 @@ -225,7 +225,7 @@ define void @complex_backpropagate_bundle(ptr %a, ptr %b, ptr %c) { ; CHECK-NEXT: [[LOAD_A:%.*]] = load i32, ptr [[A]], align 32 ; CHECK-NEXT: [[LOAD_B:%.*]] = load i32, ptr [[B]], align 4 ; CHECK-NEXT: store i32 [[LOAD_B]], ptr [[A]], align 32 -; CHECK-NEXT: [[OBJ_SIZE:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[C]], i1 false, i1 false, i1 false) +; CHECK-NEXT: [[OBJ_SIZE:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[C]], i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: store i64 [[OBJ_SIZE]], ptr [[ALLOCA]], align 8 ; CHECK-NEXT: tail call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i32 32) ] ; CHECK-NEXT: ret void diff --git a/llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll b/llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll index 18f37aba82957..90c7872cd51d4 100644 --- a/llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll +++ b/llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll @@ -4,12 +4,12 @@ @numa_nodes_parsed = external constant %struct.nodemask_t, align 8 declare void @foo() -declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg) +declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) ; Test that we inline @callee into @caller. define i64 @caller() { ; CHECK-LABEL: @caller( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.objectsize.i64.p0(ptr @numa_nodes_parsed, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.objectsize.i64.p0(ptr @numa_nodes_parsed, i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 128 ; CHECK-NEXT: br i1 [[TMP2]], label %[[CALLEE_EXIT:.*]], label %[[HANDLER_TYPE_MISMATCH94_I:.*]] ; CHECK: [[HANDLER_TYPE_MISMATCH94_I]]: @@ -31,7 +31,7 @@ define i64 @caller() { ; Do not change the linkage of @callee; that will give it a severe discount in ; cost (LastCallToStaticBonus). define i64 @callee() { - %1 = tail call i64 @llvm.objectsize.i64.p0(ptr @numa_nodes_parsed, i1 false, i1 false, i1 false) + %1 = tail call i64 @llvm.objectsize.i64.p0(ptr @numa_nodes_parsed, i1 false, i1 false, i1 false, i1 true, i64 0) %2 = icmp uge i64 %1, 128 br i1 %2, label %cont95, label %handler.type_mismatch94 diff --git a/llvm/test/Transforms/InstCombine/allocsize.ll b/llvm/test/Transforms/InstCombine/allocsize.ll index 031053c395316..21b7b30f960d1 100644 --- a/llvm/test/Transforms/InstCombine/allocsize.ll +++ b/llvm/test/Transforms/InstCombine/allocsize.ll @@ -47,7 +47,7 @@ define void @test_malloc_fails(ptr %p, ptr %r, i32 %n) { ; CHECK-SAME: ptr [[P:%.*]], ptr [[R:%.*]], i32 [[N:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call ptr @my_malloc(ptr null, i32 [[N]]) ; CHECK-NEXT: store ptr [[TMP1]], ptr [[P]], align 8 -; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP1]], i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP1]], i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: store i64 [[TMP2]], ptr [[R]], align 8 ; CHECK-NEXT: ret void ; @@ -64,11 +64,11 @@ define void @test_calloc_fails(ptr %p, ptr %r, i32 %n) { ; CHECK-SAME: ptr [[P:%.*]], ptr [[R:%.*]], i32 [[N:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = call ptr @my_calloc(ptr null, ptr null, i32 [[N]], i32 5) ; CHECK-NEXT: store ptr [[TMP1]], ptr [[P]], align 8 -; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP1]], i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP1]], i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: store i64 [[TMP2]], ptr [[R]], align 8 ; CHECK-NEXT: [[TMP3:%.*]] = call ptr @my_calloc(ptr null, ptr null, i32 100, i32 [[N]]) ; CHECK-NEXT: store ptr [[TMP3]], ptr [[P]], align 8 -; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP3]], i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP3]], i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: store i64 [[TMP4]], ptr [[R]], align 8 ; CHECK-NEXT: ret void ; @@ -127,14 +127,14 @@ define void @test_overflow(ptr %p, ptr %r) { ; CHECK-SAME: ptr [[P:%.*]], ptr [[R:%.*]]) { ; CHECK-NEXT: [[BIG_MALLOC:%.*]] = call dereferenceable_or_null(4294967298) ptr @my_calloc(ptr null, ptr null, i32 -2147483647, i32 2) ; CHECK-NEXT: store ptr [[BIG_MALLOC]], ptr [[P]], align 8 -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr [[BIG_MALLOC]], i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr [[BIG_MALLOC]], i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: store i32 [[TMP1]], ptr [[R]], align 4 ; CHECK-NEXT: [[BIG_LITTLE_MALLOC:%.*]] = call dereferenceable_or_null(508) ptr @my_tiny_calloc(ptr null, ptr null, i8 127, i8 4) ; CHECK-NEXT: store ptr [[BIG_LITTLE_MALLOC]], ptr [[P]], align 8 ; CHECK-NEXT: store i32 508, ptr [[R]], align 4 ; CHECK-NEXT: [[BIG_MALLOC_I64:%.*]] = call dereferenceable_or_null(8589934592) ptr @my_malloc_i64(ptr null, i64 8589934592) ; CHECK-NEXT: store ptr [[BIG_MALLOC_I64]], ptr [[P]], align 8 -; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr [[BIG_MALLOC_I64]], i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr [[BIG_MALLOC_I64]], i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: store i32 [[TMP2]], ptr [[R]], align 4 ; CHECK-NEXT: store i64 8589934592, ptr [[R]], align 8 ; CHECK-NEXT: [[VARIED_CALLOC:%.*]] = call dereferenceable_or_null(5000) ptr @my_varied_calloc(ptr null, ptr null, i32 1000, i8 5) diff --git a/llvm/test/Transforms/InstCombine/assume_inevitable.ll b/llvm/test/Transforms/InstCombine/assume_inevitable.ll index 2643c9b525cb5..43a871479d224 100644 --- a/llvm/test/Transforms/InstCombine/assume_inevitable.ll +++ b/llvm/test/Transforms/InstCombine/assume_inevitable.ll @@ -14,7 +14,7 @@ define i32 @assume_inevitable(ptr %a, ptr %b, ptr %c) { ; CHECK-NEXT: [[DUMMY_EQ:%.*]] = icmp ugt i32 [[LOADRES]], 42 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[DUMMY_EQ]]) ; CHECK-NEXT: [[M_A:%.*]] = call ptr @llvm.ptr.annotation.p0.p0(ptr nonnull [[M]], ptr nonnull @.str, ptr nonnull @.str1, i32 2, ptr null) -; CHECK-NEXT: [[OBJSZ:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[C:%.*]], i1 false, i1 false, i1 false) +; CHECK-NEXT: [[OBJSZ:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[C:%.*]], i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: store i64 [[OBJSZ]], ptr [[M_A]], align 4 ; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A]] to i64 ; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 diff --git a/llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll b/llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll index 7a53ca996dc5a..599f2261c57ed 100644 --- a/llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll +++ b/llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll @@ -15,7 +15,7 @@ define i64 @weird_identity_but_ok(i64 %sz) { ; entry: %call = tail call ptr @malloc(i64 %sz) - %calc_size = tail call i64 @llvm.objectsize.i64.p0(ptr %call, i1 false, i1 true, i1 true) + %calc_size = tail call i64 @llvm.objectsize.i64.p0(ptr %call, i1 false, i1 true, i1 true, i1 true, i64 0) tail call void @free(ptr %call) ret i64 %calc_size } @@ -46,7 +46,7 @@ second_label: join_label: %joined = phi ptr [ %first_call, %first_label ], [ %second_call, %second_label ] - %calc_size = tail call i64 @llvm.objectsize.i64.p0(ptr %joined, i1 false, i1 true, i1 true) + %calc_size = tail call i64 @llvm.objectsize.i64.p0(ptr %joined, i1 false, i1 true, i1 true, i1 true, i64 0) ret i64 %calc_size } @@ -60,18 +60,18 @@ define i64 @internal_pointer(i64 %sz) { entry: %ptr = call ptr @malloc(i64 %sz) %ptr2 = getelementptr inbounds i8, ptr %ptr, i32 2 - %calc_size = call i64 @llvm.objectsize.i64.p0(ptr %ptr2, i1 false, i1 true, i1 true) + %calc_size = call i64 @llvm.objectsize.i64.p0(ptr %ptr2, i1 false, i1 true, i1 true, i1 true, i64 0) ret i64 %calc_size } define i64 @uses_nullptr_no_fold() { ; CHECK-LABEL: define i64 @uses_nullptr_no_fold() { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RES:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr null, i1 false, i1 true, i1 true) +; CHECK-NEXT: [[RES:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr null, i1 false, i1 true, i1 true, i1 true, i64 0) ; CHECK-NEXT: ret i64 [[RES]] ; entry: - %res = call i64 @llvm.objectsize.i64.p0(ptr null, i1 false, i1 true, i1 true) + %res = call i64 @llvm.objectsize.i64.p0(ptr null, i1 false, i1 true, i1 true, i1 true, i64 0) ret i64 %res } @@ -82,7 +82,7 @@ define i64 @uses_nullptr_fold() { ; entry: ; NOTE: the third parameter to this call is false, unlike above. - %res = call i64 @llvm.objectsize.i64.p0(ptr null, i1 false, i1 false, i1 true) + %res = call i64 @llvm.objectsize.i64.p0(ptr null, i1 false, i1 false, i1 true, i1 true, i64 0) ret i64 %res } @@ -98,7 +98,7 @@ define void @f() { ; CHECK-NEXT: br i1 [[TOBOOL4]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]] ; CHECK: for.body: ; CHECK-NEXT: [[DP_05:%.*]] = phi ptr [ [[ADD_PTR:%.*]], [[FOR_BODY]] ], [ @d, [[ENTRY:%.*]] ] -; CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.objectsize.i64.p0(ptr [[DP_05]], i1 false, i1 true, i1 true) +; CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.objectsize.i64.p0(ptr [[DP_05]], i1 false, i1 true, i1 true, i1 true, i64 0) ; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 ; CHECK-NEXT: tail call void @bury(i32 [[CONV]]) ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @c, align 4 @@ -118,7 +118,7 @@ entry: for.body: ; preds = %entry, %for.body %dp.05 = phi ptr [ %add.ptr, %for.body ], [ @d, %entry ] - %0 = tail call i64 @llvm.objectsize.i64.p0(ptr %dp.05, i1 false, i1 true, i1 true) + %0 = tail call i64 @llvm.objectsize.i64.p0(ptr %dp.05, i1 false, i1 true, i1 true, i1 true, i64 0) %conv = trunc i64 %0 to i32 tail call void @bury(i32 %conv) #3 %1 = load i32, ptr @c, align 4 @@ -153,7 +153,7 @@ define void @bdos_cmpm1(i64 %alloc) { ; entry: %obj = call ptr @malloc(i64 %alloc) - %objsize = call i64 @llvm.objectsize.i64.p0(ptr %obj, i1 0, i1 0, i1 1) + %objsize = call i64 @llvm.objectsize.i64.p0(ptr %obj, i1 0, i1 0, i1 1, i1 1, i64 0) %cmp.not = icmp eq i64 %objsize, -1 br i1 %cmp.not, label %if.else, label %if.then @@ -189,7 +189,7 @@ define void @bdos_cmpm1_expr(i64 %alloc, i64 %part) { entry: %sz = udiv i64 %alloc, %part %obj = call ptr @malloc(i64 %sz) - %objsize = call i64 @llvm.objectsize.i64.p0(ptr %obj, i1 0, i1 0, i1 1) + %objsize = call i64 @llvm.objectsize.i64.p0(ptr %obj, i1 0, i1 0, i1 1, i1 1, i64 0) %cmp.not = icmp eq i64 %objsize, -1 br i1 %cmp.not, label %if.else, label %if.then @@ -220,7 +220,7 @@ entry: %gep = getelementptr i8, ptr addrspace(7) @p7, i32 1 %as = addrspacecast ptr addrspace(7) %gep to ptr %select = select i1 %c, ptr %p0, ptr %as - %calc_size = tail call i64 @llvm.objectsize.i64.p0(ptr %select, i1 false, i1 true, i1 true) + %calc_size = tail call i64 @llvm.objectsize.i64.p0(ptr %select, i1 false, i1 true, i1 true, i1 true, i64 0) ret i64 %calc_size } @@ -234,7 +234,7 @@ define i64 @constexpr_as_cast(i1 %c) { entry: %p0 = tail call ptr @malloc(i64 64) %select = select i1 %c, ptr %p0, ptr addrspacecast (ptr addrspace(7) getelementptr (i8, ptr addrspace(7) @p7, i32 1) to ptr) - %calc_size = tail call i64 @llvm.objectsize.i64.p0(ptr %select, i1 false, i1 true, i1 true) + %calc_size = tail call i64 @llvm.objectsize.i64.p0(ptr %select, i1 false, i1 true, i1 true, i1 true, i64 0) ret i64 %calc_size } @@ -249,7 +249,7 @@ declare ptr @get_unknown_buffer() declare void @free(ptr nocapture) nounwind allockind("free") "alloc-family"="malloc" ; Function Attrs: nounwind readnone speculatable -declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1) +declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1, i1, i64) declare void @fortified_chk(ptr, i64) diff --git a/llvm/test/Transforms/InstCombine/builtin-object-size-custom-dl.ll b/llvm/test/Transforms/InstCombine/builtin-object-size-custom-dl.ll index fe8b321114e47..415d06f862f5a 100644 --- a/llvm/test/Transforms/InstCombine/builtin-object-size-custom-dl.ll +++ b/llvm/test/Transforms/InstCombine/builtin-object-size-custom-dl.ll @@ -6,7 +6,7 @@ define i64 @objsize1_custom_idx(i64 %sz) { entry: %ptr = call ptr @malloc(i64 %sz) %ptr2 = getelementptr inbounds i8, ptr %ptr, i32 2 - %calc_size = call i64 @llvm.objectsize.i64.p0(ptr %ptr2, i1 false, i1 true, i1 true) + %calc_size = call i64 @llvm.objectsize.i64.p0(ptr %ptr2, i1 false, i1 true, i1 true, i1 true, i64 0) ret i64 %calc_size } @@ -17,7 +17,7 @@ entry: %var = alloca %struct.V, align 4 call void @llvm.lifetime.start.p0(i64 28, ptr %var) #3 %arrayidx = getelementptr inbounds [10 x i8], ptr %var, i64 0, i64 1 - %0 = call i64 @llvm.objectsize.i64.p0(ptr %arrayidx, i1 false, i1 false, i1 false) + %0 = call i64 @llvm.objectsize.i64.p0(ptr %arrayidx, i1 false, i1 false, i1 false, i1 true, i64 0) %conv = trunc i64 %0 to i32 call void @llvm.lifetime.end.p0(i64 28, ptr %var) #3 ret i32 %conv @@ -27,4 +27,4 @@ entry: declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #1 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #1 declare ptr @malloc(i64) -declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1) +declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1, i1, i64) diff --git a/llvm/test/Transforms/InstCombine/builtin-object-size-strdup-family.ll b/llvm/test/Transforms/InstCombine/builtin-object-size-strdup-family.ll index 63f3edc20c0f3..c9fb16142fbad 100644 --- a/llvm/test/Transforms/InstCombine/builtin-object-size-strdup-family.ll +++ b/llvm/test/Transforms/InstCombine/builtin-object-size-strdup-family.ll @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s @@ -6,7 +6,7 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16 target triple = "x86_64-unknown-linux-gnu" declare dso_local noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr -declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg) +declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) declare noalias ptr @strdup(ptr); declare noalias ptr @__strdup(ptr); declare noalias ptr @strndup(ptr, i64); @@ -15,37 +15,41 @@ declare noalias ptr @__strndup(ptr, i64); @str = dso_local constant [11 x i8] c"toulbroc'h\00" define dso_local i64 @check_strdup(i32 noundef %n) local_unnamed_addr { -; CHECK-LABEL: @check_strdup( +; CHECK-LABEL: define dso_local i64 @check_strdup +; CHECK-SAME: (i32 noundef [[N:%.*]]) local_unnamed_addr { ; CHECK-NEXT: ret i64 11 ; %ptr = call noalias ptr @strdup(ptr noundef @str) - %size = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false) + %size = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false, i1 true, i64 0) ret i64 %size } define dso_local i64 @check_dunder_strdup(i32 noundef %n) local_unnamed_addr { -; CHECK-LABEL: @check_dunder_strdup( +; CHECK-LABEL: define dso_local i64 @check_dunder_strdup +; CHECK-SAME: (i32 noundef [[N:%.*]]) local_unnamed_addr { ; CHECK-NEXT: ret i64 11 ; %ptr = call noalias ptr @__strdup(ptr noundef @str) - %size = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false) + %size = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false, i1 true, i64 0) ret i64 %size } define dso_local i64 @check_strndup(i32 noundef %n) local_unnamed_addr { -; CHECK-LABEL: @check_strndup( +; CHECK-LABEL: define dso_local i64 @check_strndup +; CHECK-SAME: (i32 noundef [[N:%.*]]) local_unnamed_addr { ; CHECK-NEXT: ret i64 5 ; %ptr = call noalias ptr @strndup(ptr noundef @str, i64 4) - %size = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false) + %size = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false, i1 true, i64 0) ret i64 %size } define dso_local i64 @check_dunder_strndup(i32 noundef %n) local_unnamed_addr { -; CHECK-LABEL: @check_dunder_strndup( +; CHECK-LABEL: define dso_local i64 @check_dunder_strndup +; CHECK-SAME: (i32 noundef [[N:%.*]]) local_unnamed_addr { ; CHECK-NEXT: ret i64 5 ; %ptr = call noalias ptr @__strndup(ptr noundef @str, i64 4) - %size = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false) + %size = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false, i1 true, i64 0) ret i64 %size } diff --git a/llvm/test/Transforms/InstCombine/invoke.ll b/llvm/test/Transforms/InstCombine/invoke.ll index 7e64d9ed60157..ea9f7c0ad24e9 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.p0(ptr %call, i1 false, i1 false, i1 false) +; CHECK: call i64 @llvm.objectsize.i64.p0(ptr %call, i1 false, i1 false, i1 false, i1 true, i64 0) %0 = tail call i64 @llvm.objectsize.i64(ptr %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 44b549e400dd8..c490de0d08437 100644 --- a/llvm/test/Transforms/InstCombine/memset_chk-1.ll +++ b/llvm/test/Transforms/InstCombine/memset_chk-1.ll @@ -91,7 +91,7 @@ define i32 @test_rauw(ptr %a, ptr %b, ptr %c) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CALL49:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[A:%.*]]) ; CHECK-NEXT: [[ADD180:%.*]] = add i64 [[CALL49]], 1 -; CHECK-NEXT: [[YO107:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[B:%.*]], i1 false, i1 false, i1 false) +; CHECK-NEXT: [[YO107:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[B:%.*]], i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: [[CALL50:%.*]] = call ptr @__memmove_chk(ptr [[B]], ptr [[A]], i64 [[ADD180]], i64 [[YO107]]) ; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[B]]) ; CHECK-NEXT: [[STRCHR1:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[STRLEN]] @@ -106,7 +106,7 @@ define i32 @test_rauw(ptr %a, ptr %b, ptr %c) { entry: %call49 = call i64 @strlen(ptr %a) %add180 = add i64 %call49, 1 - %yo107 = call i64 @llvm.objectsize.i64.p0(ptr %b, i1 false, i1 false, i1 false) + %yo107 = call i64 @llvm.objectsize.i64.p0(ptr %b, i1 false, i1 false, i1 false, i1 true, i64 0) %call50 = call ptr @__memmove_chk(ptr %b, ptr %a, i64 %add180, i64 %yo107) %call51i = call ptr @strrchr(ptr %b, i32 0) %d = load ptr, ptr %c, align 8 @@ -121,7 +121,7 @@ entry: declare ptr @__memmove_chk(ptr, ptr, i64, i64) declare ptr @strrchr(ptr, i32) declare i64 @strlen(ptr nocapture) -declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1) +declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1, i1, i64) declare ptr @__memset_chk(ptr, i32, i64, i64) @@ -134,7 +134,7 @@ define ptr @pr25892(i64 %size) #0 { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[CALL]], null ; CHECK-NEXT: br i1 [[CMP]], label [[CLEANUP:%.*]], label [[IF_END:%.*]] ; CHECK: if.end: -; CHECK-NEXT: [[CALL2:%.*]] = tail call i64 @llvm.objectsize.i64.p0(ptr nonnull [[CALL]], i1 false, i1 false, i1 false) +; CHECK-NEXT: [[CALL2:%.*]] = tail call i64 @llvm.objectsize.i64.p0(ptr nonnull [[CALL]], i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: [[CALL3:%.*]] = tail call ptr @__memset_chk(ptr nonnull [[CALL]], i32 0, i64 [[SIZE]], i64 [[CALL2]]) #[[ATTR3]] ; CHECK-NEXT: br label [[CLEANUP]] ; CHECK: cleanup: @@ -146,7 +146,7 @@ entry: %cmp = icmp eq ptr %call, null br i1 %cmp, label %cleanup, label %if.end if.end: - %call2 = tail call i64 @llvm.objectsize.i64.p0(ptr nonnull %call, i1 false, i1 false, i1 false) + %call2 = tail call i64 @llvm.objectsize.i64.p0(ptr nonnull %call, i1 false, i1 false, i1 false, i1 true, i64 0) %call3 = tail call ptr @__memset_chk(ptr nonnull %call, i32 0, i64 %size, i64 %call2) #1 br label %cleanup cleanup: diff --git a/llvm/test/Transforms/InstCombine/objsize.ll b/llvm/test/Transforms/InstCombine/objsize.ll index 33c14f44fc5fb..5a5f4430b866a 100644 --- a/llvm/test/Transforms/InstCombine/objsize.ll +++ b/llvm/test/Transforms/InstCombine/objsize.ll @@ -10,7 +10,7 @@ define i32 @foo() nounwind { ; CHECK-LABEL: @foo( ; CHECK-NEXT: ret i32 60 ; - %1 = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) + %1 = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -27,7 +27,7 @@ define ptr @bar() nounwind { ; entry: %retval = alloca ptr - %0 = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) + %0 = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) %cmp = icmp ne i32 %0, -1 br i1 %cmp, label %cond.true, label %cond.false @@ -44,7 +44,7 @@ define i32 @f() nounwind { ; CHECK-LABEL: @f( ; CHECK-NEXT: ret i32 0 ; - %1 = call i32 @llvm.objectsize.i32.p0(ptr getelementptr ([60 x i8], ptr @a, i32 1, i32 0), i1 false, i1 false, i1 false) + %1 = call i32 @llvm.objectsize.i32.p0(ptr getelementptr ([60 x i8], ptr @a, i32 1, i32 0), i1 false, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -52,11 +52,11 @@ define i32 @f() nounwind { define i1 @baz() nounwind { ; CHECK-LABEL: @baz( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.objectsize.i32.p0(ptr @window, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.objectsize.i32.p0(ptr @window, i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -1 ; CHECK-NEXT: ret i1 [[TMP2]] ; - %1 = tail call i32 @llvm.objectsize.i32.p0(ptr @window, i1 false, i1 false, i1 false) + %1 = tail call i32 @llvm.objectsize.i32.p0(ptr @window, i1 false, i1 false, i1 false, i1 true, i64 0) %2 = icmp eq i32 %1, -1 ret i1 %2 } @@ -64,7 +64,7 @@ define i1 @baz() nounwind { define void @test1(ptr %q, i32 %x) nounwind noinline { ; CHECK-LABEL: @test1( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr getelementptr inbounds ([0 x i8], ptr @window, i32 0, i32 10), i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr getelementptr inbounds ([0 x i8], ptr @window, i32 0, i32 10), i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], -1 ; CHECK-NEXT: br i1 [[TMP1]], label %"47", label %"46" ; CHECK: "46": @@ -73,7 +73,7 @@ define void @test1(ptr %q, i32 %x) nounwind noinline { ; CHECK-NEXT: unreachable ; entry: - %0 = call i32 @llvm.objectsize.i32.p0(ptr getelementptr inbounds ([0 x i8], ptr @window, i32 0, i32 10), i1 false, i1 false, i1 false) ; [#uses=1] + %0 = call i32 @llvm.objectsize.i32.p0(ptr getelementptr inbounds ([0 x i8], ptr @window, i32 0, i32 10), i1 false, i1 false, i1 false, i1 true, i64 0) ; [#uses=1] %1 = icmp eq i32 %0, -1 ; [#uses=1] br i1 %1, label %"47", label %"46" @@ -90,7 +90,7 @@ define i32 @test2() nounwind { ; CHECK-LABEL: @test2( ; CHECK-NEXT: ret i32 34 ; - %1 = call i32 @llvm.objectsize.i32.p0(ptr getelementptr (i8, ptr @.str5, i32 2), i1 false, i1 false, i1 false) + %1 = call i32 @llvm.objectsize.i32.p0(ptr getelementptr (i8, ptr @.str5, i32 2), i1 false, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -99,9 +99,9 @@ define i32 @test2() nounwind { declare ptr @__memcpy_chk(ptr, ptr, i32, i32) nounwind -declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1) nounwind readonly +declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1, i1, i64) nounwind readonly -declare i32 @llvm.objectsize.i32.p1(ptr addrspace(1), i1, i1, i1) nounwind readonly +declare i32 @llvm.objectsize.i32.p1(ptr addrspace(1), i1, i1, i1, i1, i64) nounwind readonly declare ptr @__inline_memcpy_chk(ptr, ptr, i32) nounwind inlinehint @@ -120,7 +120,7 @@ entry: bb11: %0 = getelementptr inbounds float, ptr getelementptr inbounds ([480 x float], ptr @array, i32 0, i32 128), i32 -127 ; [#uses=1] - %1 = call i32 @llvm.objectsize.i32.p0(ptr %0, i1 false, i1 false, i1 false) ; [#uses=1] + %1 = call i32 @llvm.objectsize.i32.p0(ptr %0, i1 false, i1 false, i1 false, i1 true, i64 0) ; [#uses=1] %2 = call ptr @__memcpy_chk(ptr %ptr1, ptr %ptr2, i32 512, i32 %1) nounwind ; [#uses=0] unreachable @@ -144,7 +144,7 @@ define i32 @test4(ptr %esc) nounwind ssp { ; entry: %0 = alloca %struct.data, align 8 - %1 = call i32 @llvm.objectsize.i32.p0(ptr %0, i1 false, i1 false, i1 false) nounwind + %1 = call i32 @llvm.objectsize.i32.p0(ptr %0, i1 false, i1 false, i1 false, i1 true, i64 0) nounwind %2 = call ptr @__memset_chk(ptr %0, i32 0, i32 1824, i32 %1) nounwind store ptr %0, ptr %esc ret i32 0 @@ -163,7 +163,7 @@ define ptr @test5(i32 %n) nounwind ssp { ; entry: %0 = tail call noalias ptr @malloc(i32 20) nounwind - %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %0, i1 false, i1 false, i1 false) + %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %0, i1 false, i1 false, i1 false, i1 true, i64 0) %2 = load ptr, ptr @s, align 8 %3 = tail call ptr @__memcpy_chk(ptr %0, ptr %2, i32 10, i32 %1) nounwind ret ptr %0 @@ -179,7 +179,7 @@ define void @test6(i32 %n) nounwind ssp { ; entry: %0 = tail call noalias ptr @malloc(i32 20) nounwind - %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %0, i1 false, i1 false, i1 false) + %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %0, i1 false, i1 false, i1 false, i1 true, i64 0) %2 = load ptr, ptr @s, align 8 %3 = tail call ptr @__memcpy_chk(ptr %0, ptr %2, i32 30, i32 %1) nounwind ret void @@ -198,7 +198,7 @@ define i32 @test7(ptr %esc) { %alloc = call noalias ptr @malloc(i32 48) nounwind store ptr %alloc, ptr %esc %gep = getelementptr inbounds i8, ptr %alloc, i32 16 - %objsize = call i32 @llvm.objectsize.i32.p0(ptr %gep, i1 false, i1 false, i1 false) nounwind readonly + %objsize = call i32 @llvm.objectsize.i32.p0(ptr %gep, i1 false, i1 false, i1 false, i1 true, i64 0) nounwind readonly ret i32 %objsize } @@ -213,7 +213,7 @@ define i32 @test8(ptr %esc) { %alloc = call noalias ptr @calloc(i32 5, i32 7) nounwind store ptr %alloc, ptr %esc %gep = getelementptr inbounds i8, ptr %alloc, i32 5 - %objsize = call i32 @llvm.objectsize.i32.p0(ptr %gep, i1 false, i1 false, i1 false) nounwind readonly + %objsize = call i32 @llvm.objectsize.i32.p0(ptr %gep, i1 false, i1 false, i1 false, i1 true, i64 0) nounwind readonly ret i32 %objsize } @@ -228,7 +228,7 @@ define i32 @test9(ptr %esc) { ; %call = tail call ptr @strdup(ptr @.str) nounwind store ptr %call, ptr %esc, align 8 - %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %call, i1 true, i1 false, i1 false) + %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %call, i1 true, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -240,7 +240,7 @@ define i32 @test10(ptr %esc) { ; %call = tail call ptr @strndup(ptr @.str, i32 3) nounwind store ptr %call, ptr %esc, align 8 - %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %call, i1 true, i1 false, i1 false) + %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %call, i1 true, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -252,7 +252,7 @@ define i32 @test11(ptr %esc) { ; %call = tail call ptr @strndup(ptr @.str, i32 7) nounwind store ptr %call, ptr %esc, align 8 - %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %call, i1 true, i1 false, i1 false) + %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %call, i1 true, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -264,7 +264,7 @@ define i32 @test12(ptr %esc) { ; %call = tail call ptr @strndup(ptr @.str, i32 8) nounwind store ptr %call, ptr %esc, align 8 - %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %call, i1 true, i1 false, i1 false) + %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %call, i1 true, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -276,7 +276,7 @@ define i32 @test13(ptr %esc) { ; %call = tail call ptr @strndup(ptr @.str, i32 57) nounwind store ptr %call, ptr %esc, align 8 - %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %call, i1 true, i1 false, i1 false) + %1 = tail call i32 @llvm.objectsize.i32.p0(ptr %call, i1 true, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -286,7 +286,7 @@ define i32 @test18() { ; CHECK-LABEL: @test18( ; CHECK-NEXT: ret i32 60 ; - %1 = call i32 @llvm.objectsize.i32.p0(ptr @globalalias, i1 false, i1 false, i1 false) + %1 = call i32 @llvm.objectsize.i32.p0(ptr @globalalias, i1 false, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -294,10 +294,10 @@ define i32 @test18() { define i32 @test19() { ; CHECK-LABEL: @test19( -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @globalalias2, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @globalalias2, i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: ret i32 [[TMP1]] ; - %1 = call i32 @llvm.objectsize.i32.p0(ptr @globalalias2, i1 false, i1 false, i1 false) + %1 = call i32 @llvm.objectsize.i32.p0(ptr @globalalias2, i1 false, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -305,7 +305,7 @@ define i32 @test20() { ; CHECK-LABEL: @test20( ; CHECK-NEXT: ret i32 0 ; - %1 = call i32 @llvm.objectsize.i32.p0(ptr null, i1 false, i1 false, i1 false) + %1 = call i32 @llvm.objectsize.i32.p0(ptr null, i1 false, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } @@ -313,65 +313,65 @@ define i32 @test21() { ; CHECK-LABEL: @test21( ; CHECK-NEXT: ret i32 0 ; - %1 = call i32 @llvm.objectsize.i32.p0(ptr null, i1 true, i1 false, i1 false) + %1 = call i32 @llvm.objectsize.i32.p0(ptr null, i1 true, i1 false, i1 false, i1 true, i64 0) ret i32 %1 } define i32 @test22() { ; CHECK-LABEL: @test22( -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr null, i1 false, i1 true, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr null, i1 false, i1 true, i1 false, i1 true, i64 0) ; CHECK-NEXT: ret i32 [[TMP1]] ; - %1 = call i32 @llvm.objectsize.i32.p0(ptr null, i1 false, i1 true, i1 false) + %1 = call i32 @llvm.objectsize.i32.p0(ptr null, i1 false, i1 true, i1 false, i1 true, i64 0) ret i32 %1 } define i32 @test23() { ; CHECK-LABEL: @test23( -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr null, i1 true, i1 true, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr null, i1 true, i1 true, i1 false, i1 true, i64 0) ; CHECK-NEXT: ret i32 [[TMP1]] ; - %1 = call i32 @llvm.objectsize.i32.p0(ptr null, i1 true, i1 true, i1 false) + %1 = call i32 @llvm.objectsize.i32.p0(ptr null, i1 true, i1 true, i1 false, i1 true, i64 0) ret i32 %1 } ; 1 is an arbitrary non-zero address space. define i32 @test24() { ; CHECK-LABEL: @test24( -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: ret i32 [[TMP1]] ; %1 = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 false, - i1 false, i1 false) + i1 false, i1 false, i1 true, i64 0) ret i32 %1 } define i32 @test25() { ; CHECK-LABEL: @test25( -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 true, i1 false, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 true, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: ret i32 [[TMP1]] ; %1 = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 true, - i1 false, i1 false) + i1 false, i1 false, i1 true, i64 0) ret i32 %1 } define i32 @test26() { ; CHECK-LABEL: @test26( -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 false, i1 true, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 false, i1 true, i1 false, i1 true, i64 0) ; CHECK-NEXT: ret i32 [[TMP1]] ; %1 = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 false, - i1 true, i1 false) + i1 true, i1 false, i1 true, i64 0) ret i32 %1 } define i32 @test27() { ; CHECK-LABEL: @test27( -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 true, i1 true, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 true, i1 true, i1 false, i1 true, i64 0) ; CHECK-NEXT: ret i32 [[TMP1]] ; %1 = call i32 @llvm.objectsize.i32.p1(ptr addrspace(1) null, i1 true, - i1 true, i1 false) + i1 true, i1 false, i1 true, i64 0) ret i32 %1 } diff --git a/llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll b/llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll index 5ebd9fae76201..8a965123de4ae 100644 --- a/llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll +++ b/llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll @@ -78,12 +78,12 @@ define ptr @test_simplify4_tail() { define ptr @test_simplify5() { ; CHECK-LABEL: @test_simplify5( -; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: [[TMP1:%.*]] = call ptr @__memcpy_chk(ptr nonnull @a, ptr nonnull @.str, i32 12, i32 [[LEN]]) ; CHECK-NEXT: ret ptr getelementptr inbounds ([60 x i8], ptr @a, i32 0, i32 11) ; - %len = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) + %len = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) %ret = call ptr @__stpcpy_chk(ptr @a, ptr @.str, i32 %len) ret ptr %ret } @@ -97,7 +97,7 @@ define ptr @test_simplify6() { ; CHECK-NEXT: ret ptr [[RET]] ; - %len = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) + %len = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) %ret = call ptr @__stpcpy_chk(ptr @a, ptr @a, i32 %len) ret ptr %ret } @@ -127,4 +127,4 @@ define ptr @test_no_simplify1() { } declare ptr @__stpcpy_chk(ptr, ptr, i32) nounwind -declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1) nounwind readonly +declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1, i1, i64) nounwind readonly diff --git a/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll b/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll index 7fdfa35e0d138..5ec34acb9ff71 100644 --- a/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll +++ b/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll @@ -78,12 +78,12 @@ define ptr @test_simplify4_tail() { define ptr @test_simplify5() { ; CHECK-LABEL: @test_simplify5( -; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: [[RET:%.*]] = call ptr @__memcpy_chk(ptr nonnull @a, ptr nonnull @.str, i32 12, i32 [[LEN]]) ; CHECK-NEXT: ret ptr [[RET]] ; - %len = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) + %len = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) %ret = call ptr @__strcpy_chk(ptr @a, ptr @.str, i32 %len) ret ptr %ret } @@ -92,12 +92,12 @@ define ptr @test_simplify5() { define ptr @test_simplify6() { ; CHECK-LABEL: @test_simplify6( -; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: [[RET:%.*]] = call ptr @__strcpy_chk(ptr nonnull @a, ptr nonnull @a, i32 [[LEN]]) ; CHECK-NEXT: ret ptr [[RET]] ; - %len = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) + %len = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false, i1 true, i64 0) %ret = call ptr @__strcpy_chk(ptr @a, ptr @a, i32 %len) ret ptr %ret } @@ -136,4 +136,4 @@ define ptr @test_no_simplify2(ptr %dst, ptr %src, i32 %a) { } declare ptr @__strcpy_chk(ptr, ptr, i32) nounwind -declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1) nounwind readonly +declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1, i1, i64) nounwind readonly diff --git a/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-load.ll b/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-load.ll index ee01e328b8983..9a32aacb56a86 100644 --- a/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-load.ll +++ b/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-load.ll @@ -4,7 +4,7 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" -declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg) +declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) define dso_local i64 @check_store_load(i1 %cond) local_unnamed_addr { @@ -37,7 +37,7 @@ if.end: return: %held = load ptr, ptr %holder - %objsize = call i64 @llvm.objectsize.i64.p0(ptr %held, i1 false, i1 true, i1 false) + %objsize = call i64 @llvm.objectsize.i64.p0(ptr %held, i1 false, i1 true, i1 false, i1 true, i64 0) ret i64 %objsize } diff --git a/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-phi.ll b/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-phi.ll index 4f4d6a88e1693..ec0588c3abd54 100644 --- a/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-phi.ll +++ b/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-phi.ll @@ -6,7 +6,7 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16 target triple = "x86_64-unknown-linux-gnu" declare dso_local noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr allocsize(0) -declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg) +declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) @buffer = dso_local global [4 x i8] zeroinitializer, align 1 @@ -32,7 +32,7 @@ if.else: if.end: %p = phi ptr [ %malloced, %if.else ], [ @buffer, %entry ] - %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 false, i1 true, i1 false) + %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 false, i1 true, i1 false, i1 true, i64 0) ret i64 %size } @@ -58,7 +58,7 @@ if.else: if.end: %p = phi ptr [ %malloced, %if.else ], [ @buffer, %entry ] - %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 true, i1 true, i1 false) + %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 true, i1 true, i1 false, i1 true, i64 0) ret i64 %size } @@ -86,7 +86,7 @@ if.else: if.end: %p = phi ptr [ %offseted, %if.else ], [ %buffer, %entry ] - %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 false, i1 true, i1 false) + %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 false, i1 true, i1 false, i1 true, i64 0) ret i64 %size } @@ -114,6 +114,6 @@ if.else: if.end: %p = phi ptr [ %offseted, %if.else ], [ %buffer, %entry ] - %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 true, i1 true, i1 false) + %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 true, i1 true, i1 false, i1 true, i64 0) ret i64 %size } diff --git a/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-posix-memalign.ll b/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-posix-memalign.ll index 240e319a178b4..6447f15e82d4a 100644 --- a/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-posix-memalign.ll +++ b/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-posix-memalign.ll @@ -5,7 +5,7 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16 target triple = "x86_64-unknown-linux-gnu" declare dso_local i32 @posix_memalign(ptr noundef, i64 noundef, i64 noundef) -declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg) +declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) ; Check posix_memalign call with proper handlig of return value define dso_local i64 @check_posix_memalign(i32 noundef %n) local_unnamed_addr { @@ -29,7 +29,7 @@ entry: cond.false: %val = load ptr, ptr %obj - %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false) + %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false, i1 true, i64 0) br label %exit exit: @@ -63,7 +63,7 @@ entry: cond.false: %val = load ptr, ptr %obj - %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false) + %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false, i1 true, i64 0) br label %exit exit: @@ -91,7 +91,7 @@ entry: cond.false: %val = load ptr, ptr %obj - %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false) + %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false, i1 true, i64 0) br label %exit exit: @@ -113,7 +113,7 @@ entry: %obj = alloca ptr %call = call i32 @posix_memalign(ptr noundef %obj, i64 noundef 8, i64 noundef 10) %val = load ptr, ptr %obj - %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false) + %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false, i1 true, i64 0) ret i64 %objsize } @@ -142,7 +142,7 @@ entry: cond.false: %val = load ptr, ptr %obj - %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false) + %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false, i1 true, i64 0) br label %exit exit: @@ -173,7 +173,7 @@ entry: cond.false: %val = load ptr, ptr %obj - %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false) + %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false, i1 true, i64 0) br label %exit exit: @@ -209,7 +209,7 @@ cond.true: cond.false: %val = load ptr, ptr %obj - %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false) + %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false, i1 true, i64 0) br label %exit exit: diff --git a/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll b/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll index 32bd2fff2732e..ff5de7a8c2a5f 100644 --- a/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll +++ b/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll @@ -19,7 +19,7 @@ declare i1 @llvm.is.constant.sl_i32i32s({i32, i32} %a) nounwind readnone declare i1 @llvm.is.constant.a2i64([2 x i64] %a) nounwind readnone declare i1 @llvm.is.constant.p0(ptr %a) nounwind readnone -declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1) nounwind readnone +declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1, i1, i64) nounwind readnone declare i32 @subfun_1() declare i32 @subfun_2() @@ -45,7 +45,7 @@ define i1 @test_objectsize(ptr %obj) nounwind { ;; CHECK-NOT: llvm.objectsize ;; CHECK-NOT: llvm.is.constant ;; CHECK: ret i1 true - %os = call i64 @llvm.objectsize.i64.p0(ptr %obj, i1 false, i1 false, i1 false) + %os = call i64 @llvm.objectsize.i64.p0(ptr %obj, i1 false, i1 false, i1 false, i1 true, i64 0) %os1 = add i64 %os, 1 %v = call i1 @llvm.is.constant.i64(i64 %os1) ret i1 %v diff --git a/llvm/test/Transforms/LowerConstantIntrinsics/crash-on-large-allocas.ll b/llvm/test/Transforms/LowerConstantIntrinsics/crash-on-large-allocas.ll index 171eb3e925d49..945a51702b0f8 100644 --- a/llvm/test/Transforms/LowerConstantIntrinsics/crash-on-large-allocas.ll +++ b/llvm/test/Transforms/LowerConstantIntrinsics/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.p0(ptr %i, i1 false, i1 false, i1 false) + %j = call i16 @llvm.objectsize.i16.p0(ptr %i, i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK: ret i16 -1 ret i16 %j } -declare i16 @llvm.objectsize.i16.p0(ptr, i1, i1, i1) +declare i16 @llvm.objectsize.i16.p0(ptr, i1, i1, i1, i1, i64) diff --git a/llvm/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll b/llvm/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll index c90d5152e1a09..26c0a6347b668 100644 --- a/llvm/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll +++ b/llvm/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll @@ -4,8 +4,8 @@ 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(ptr, i1, i1, i1) nounwind readonly -declare i64 @llvm.objectsize.i64.p1(ptr addrspace(1), i1, i1, i1) nounwind readonly +declare i64 @llvm.objectsize.i64(ptr, i1, i1, i1, i1, i64) nounwind readonly +declare i64 @llvm.objectsize.i64.p1(ptr addrspace(1), i1, i1, i1, i1, i64) nounwind readonly declare void @llvm.trap() nounwind ; objectsize should fold to a constant, which causes the branch to fold to an @@ -18,7 +18,7 @@ define i32 @test1(ptr %ptr) nounwind ssp noredzone align 2 { ; CHECK-NEXT: ret i32 4 ; entry: - %0 = tail call i64 @llvm.objectsize.i64(ptr %ptr, i1 false, i1 false, i1 false) + %0 = tail call i64 @llvm.objectsize.i64(ptr %ptr, i1 false, i1 false, i1 false, i1 true, i64 0) %1 = icmp ugt i64 %0, 3 br i1 %1, label %T, label %trap @@ -37,7 +37,7 @@ define i64 @test_objectsize_null_flag(ptr %ptr) { ; CHECK-NEXT: ret i64 -1 ; entry: - %0 = tail call i64 @llvm.objectsize.i64(ptr null, i1 false, i1 true, i1 false) + %0 = tail call i64 @llvm.objectsize.i64(ptr null, i1 false, i1 true, i1 false, i1 true, i64 0) ret i64 %0 } @@ -47,7 +47,7 @@ define i64 @test_objectsize_null_flag_min(ptr %ptr) { ; CHECK-NEXT: ret i64 0 ; entry: - %0 = tail call i64 @llvm.objectsize.i64(ptr null, i1 true, i1 true, i1 false) + %0 = tail call i64 @llvm.objectsize.i64(ptr null, i1 true, i1 true, i1 false, i1 true, i64 0) ret i64 %0 } @@ -60,7 +60,7 @@ define i64 @test_objectsize_null_flag_noas0() { ; entry: %0 = tail call i64 @llvm.objectsize.i64.p1(ptr addrspace(1) null, i1 false, - i1 true, i1 false) + i1 true, i1 false, i1 true, i64 0) ret i64 %0 } @@ -71,7 +71,7 @@ define i64 @test_objectsize_null_flag_min_noas0() { ; entry: %0 = tail call i64 @llvm.objectsize.i64.p1(ptr addrspace(1) null, i1 true, - i1 true, i1 false) + i1 true, i1 false, i1 true, i64 0) ret i64 %0 } @@ -82,7 +82,7 @@ define i64 @test_objectsize_null_known_flag_noas0() { ; entry: %0 = tail call i64 @llvm.objectsize.i64.p1(ptr addrspace(1) null, i1 false, - i1 false, i1 false) + i1 false, i1 false, i1 true, i64 0) ret i64 %0 } @@ -93,7 +93,7 @@ define i64 @test_objectsize_null_known_flag_min_noas0() { ; entry: %0 = tail call i64 @llvm.objectsize.i64.p1(ptr addrspace(1) null, i1 true, - i1 false, i1 false) + i1 false, i1 false, i1 true, i64 0) ret i64 %0 } @@ -101,7 +101,7 @@ define i64 @test_objectsize_byval_arg(ptr byval([42 x i8]) %ptr) { ; CHECK-LABEL: @test_objectsize_byval_arg( ; CHECK-NEXT: ret i64 42 ; - %size = tail call i64 @llvm.objectsize.i64(ptr %ptr, i1 true, i1 false, i1 false) + %size = tail call i64 @llvm.objectsize.i64(ptr %ptr, i1 true, i1 false, i1 false, i1 true, i64 0) ret i64 %size } @@ -109,7 +109,7 @@ define i64 @test_objectsize_byref_arg(ptr byref([42 x i8]) %ptr) { ; CHECK-LABEL: @test_objectsize_byref_arg( ; CHECK-NEXT: ret i64 42 ; - %size = tail call i64 @llvm.objectsize.i64(ptr %ptr, i1 true, i1 false, i1 false) + %size = tail call i64 @llvm.objectsize.i64(ptr %ptr, i1 true, i1 false, i1 false, i1 true, i64 0) ret i64 %size } @@ -131,7 +131,7 @@ define i64 @vla_pointer_size_mismatch(i42 %x) { ; %A = alloca i8, i42 %x, align 1 %G1 = getelementptr i8, ptr %A, i8 17 - %objsize = call i64 @llvm.objectsize.i64(ptr %G1, i1 false, i1 true, i1 true) + %objsize = call i64 @llvm.objectsize.i64(ptr %G1, i1 false, i1 true, i1 true, i1 true, i64 0) ret i64 %objsize } @@ -143,7 +143,7 @@ define i64 @test_objectsize_malloc() { ; CHECK-NEXT: ret i64 16 ; %ptr = call ptr @malloc(i64 16) - %objsize = call i64 @llvm.objectsize.i64(ptr %ptr, i1 false, i1 true, i1 true) + %objsize = call i64 @llvm.objectsize.i64(ptr %ptr, i1 false, i1 true, i1 true, i1 true, i64 0) ret i64 %objsize } @@ -153,7 +153,7 @@ define i32 @promote_with_objectsize_min_false() { ; CHECK-LABEL: @promote_with_objectsize_min_false( ; CHECK-NEXT: ret i32 -1 ; - %size = call i32 @llvm.objectsize.i32.p0(ptr @gv_weak, i1 false, i1 false, i1 false) + %size = call i32 @llvm.objectsize.i32.p0(ptr @gv_weak, i1 false, i1 false, i1 false, i1 true, i64 0) ret i32 %size } @@ -161,7 +161,7 @@ define i32 @promote_with_objectsize_min_true() { ; CHECK-LABEL: @promote_with_objectsize_min_true( ; CHECK-NEXT: ret i32 8 ; - %size = call i32 @llvm.objectsize.i32.p0(ptr @gv_weak, i1 true, i1 false, i1 false) + %size = call i32 @llvm.objectsize.i32.p0(ptr @gv_weak, i1 true, i1 false, i1 false, i1 true, i64 0) ret i32 %size } @@ -171,7 +171,7 @@ define i32 @promote_with_objectsize_nullunknown_false() { ; CHECK-LABEL: @promote_with_objectsize_nullunknown_false( ; CHECK-NEXT: ret i32 0 ; - %size = call i32 @llvm.objectsize.i32.p0(ptr @gv_extern, i1 true, i1 false, i1 false) + %size = call i32 @llvm.objectsize.i32.p0(ptr @gv_extern, i1 true, i1 false, i1 false, i1 true, i64 0) ret i32 %size } @@ -179,8 +179,8 @@ define i32 @promote_with_objectsize_nullunknown_true() { ; CHECK-LABEL: @promote_with_objectsize_nullunknown_true( ; CHECK-NEXT: ret i32 0 ; - %size = call i32 @llvm.objectsize.i32.p0(ptr @gv_extern, i1 true, i1 true, i1 false) + %size = call i32 @llvm.objectsize.i32.p0(ptr @gv_extern, i1 true, i1 true, i1 false, i1 true, i64 0) ret i32 %size } -declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1) +declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1, i1, i64) diff --git a/llvm/test/Transforms/LowerConstantIntrinsics/stale-worklist-phi.ll b/llvm/test/Transforms/LowerConstantIntrinsics/stale-worklist-phi.ll index 0b0258bf36630..b52ee81b341bd 100644 --- a/llvm/test/Transforms/LowerConstantIntrinsics/stale-worklist-phi.ll +++ b/llvm/test/Transforms/LowerConstantIntrinsics/stale-worklist-phi.ll @@ -15,7 +15,7 @@ define fastcc void @foo(ptr %p) unnamed_addr { entry: - %0 = tail call i32 @llvm.objectsize.i32.p0(ptr %p, i1 false, i1 false, i1 false) #2 + %0 = tail call i32 @llvm.objectsize.i32.p0(ptr %p, i1 false, i1 false, i1 false, i1 true, i64 0) #2 %1 = icmp ne i32 %0, 0 %.not1.i = icmp eq i32 %0, 0 br label %for.cond @@ -41,7 +41,7 @@ cont4.i: ; preds = %cont2.i } ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare i32 @llvm.objectsize.i32.p0(ptr, i1 immarg, i1 immarg, i1 immarg) #1 +declare i32 @llvm.objectsize.i32.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) #1 attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } attributes #2 = { nounwind } diff --git a/llvm/test/Transforms/SCCP/issue59602-assume-like-call-users.ll b/llvm/test/Transforms/SCCP/issue59602-assume-like-call-users.ll index 352eb21095c23..32dc36a378cd7 100644 --- a/llvm/test/Transforms/SCCP/issue59602-assume-like-call-users.ll +++ b/llvm/test/Transforms/SCCP/issue59602-assume-like-call-users.ll @@ -18,11 +18,11 @@ define i32 @call_assume_self_user() { ; users have a concrete value" define internal i32 @assume_self_user() { ; CHECK-LABEL: define {{[^@]+}}@assume_self_user() { -; CHECK-NEXT: [[OBJSIZE:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @assume_self_user, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[OBJSIZE:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @assume_self_user, i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: store i32 [[OBJSIZE]], ptr @extern, align 4 ; CHECK-NEXT: ret i32 undef ; - %objsize = call i32 @llvm.objectsize.i32.p0(ptr @assume_self_user, i1 false, i1 false, i1 false) + %objsize = call i32 @llvm.objectsize.i32.p0(ptr @assume_self_user, i1 false, i1 false, i1 false, i1 true, i64 0) store i32 %objsize, ptr @extern ret i32 0 } @@ -48,15 +48,15 @@ define i32 @callsite_with_returned() { define internal i32 @constexpr_self_user(i32 %arg0) addrspace(1) { ; CHECK-LABEL: define {{[^@]+}}@constexpr_self_user ; CHECK-SAME: (i32 [[ARG0:%.*]]) addrspace(1) { -; CHECK-NEXT: [[OBJSIZE:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr addrspacecast (ptr addrspace(1) @constexpr_self_user to ptr), i1 false, i1 false, i1 false) +; CHECK-NEXT: [[OBJSIZE:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr addrspacecast (ptr addrspace(1) @constexpr_self_user to ptr), i1 false, i1 false, i1 false, i1 true, i64 0) ; CHECK-NEXT: store i32 [[OBJSIZE]], ptr @extern, align 4 ; CHECK-NEXT: ret i32 undef ; - %objsize = call i32 @llvm.objectsize.i32.p0(ptr addrspacecast (ptr addrspace(1) @constexpr_self_user to ptr), i1 false, i1 false, i1 false) + %objsize = call i32 @llvm.objectsize.i32.p0(ptr addrspacecast (ptr addrspace(1) @constexpr_self_user to ptr), i1 false, i1 false, i1 false, i1 true, i64 0) store i32 %objsize, ptr @extern ret i32 %arg0 } -declare i32 @llvm.objectsize.i32.p0(ptr, i1 immarg, i1 immarg, i1 immarg) #0 +declare i32 @llvm.objectsize.i32.p0(ptr, i1 immarg, i1 immarg, i1 immarg, i1 immarg, i64 immarg) #0 attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }