diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 10232ff41da15a..de6dcc0298b8c9 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -3774,6 +3774,74 @@ type-generic alternative to the ``__builtin_clz{,l,ll}`` (respectively ``__builtin_ctz{,l,ll}``) builtins, with support for other integer types, such as ``unsigned __int128`` and C23 ``unsigned _BitInt(N)``. +``__builtin_counted_by_ref`` +---------------------------- + +``__builtin_counted_by_ref`` returns a pointer to the count field from the +``counted_by`` attribute. + +The argument must be a flexible array member. If the argument isn't a flexible +array member or doesn't have the ``counted_by`` attribute, the builtin returns +``(void *)0``. + +**Syntax**: + +.. code-block:: c + + T *__builtin_counted_by_ref(void *array) + +**Examples**: + +.. code-block:: c + + #define alloc(P, FAM, COUNT) ({ \ + size_t __ignored_assignment; \ + typeof(P) __p = NULL; \ + __p = malloc(MAX(sizeof(*__p), \ + sizeof(*__p) + sizeof(*__p->FAM) * COUNT)); \ + \ + *_Generic( \ + __builtin_counted_by_ref(__p->FAM), \ + void *: &__ignored_assignment, \ + default: __builtin_counted_by_ref(__p->FAM)) = COUNT; \ + \ + __p; \ + }) + +**Description**: + +The ``__builtin_counted_by_ref`` builtin allows the programmer to prevent a +common error associated with the ``counted_by`` attribute. When using the +``counted_by`` attribute, the ``count`` field **must** be set before the +flexible array member can be accessed. Otherwise, the sanitizers may view such +accesses as false positives. For instance, it's not uncommon for programmers to +initialize the flexible array before setting the ``count`` field: + +.. code-block:: c + + struct s { + int dummy; + short count; + long array[] __attribute__((counted_by(count))); + }; + + struct s *ptr = malloc(sizeof(struct s) + sizeof(long) * COUNT); + + for (int i = 0; i < COUNT; ++i) + ptr->array[i] = i; + + ptr->count = COUNT; + +Enforcing the rule that ``ptr->count = COUNT;`` must occur after every +allocation of a struct with a flexible array member with the ``counted_by`` +attribute is prone to failure in large code bases. This builtin mitigates this +for allocators (like in Linux) that are implemented in a way where the counter +assignment can happen automatically. + +**Note: The value returned by ``__builtin_counted_by_ref`` cannot be assigned +to a variable, have its address taken, or passed into or returned from a +function, because doing so violates bounds safety conventions.** + Multiprecision Arithmetic Builtins ---------------------------------- diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4e542ee91a8b36..7ce8647e7b7cfd 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -289,6 +289,29 @@ Non-comprehensive list of changes in this release as well as declarations. - ``__builtin_abs`` function can now be used in constant expressions. +- The new builtin ``__builtin_counted_by_ref`` was added. In contexts where the + programmer needs access to the ``counted_by`` attribute's field, but it's not + available --- e.g. in macros. For instace, it can be used to automatically + set the counter during allocation in the Linux kernel: + + .. code-block:: c + + /* A simplified version of Linux allocation macros */ + #define alloc(PTR, FAM, COUNT) ({ \ + sizeof_t __ignored_assignment; \ + typeof(P) __p; \ + size_t __size = sizeof(*P) + sizeof(*P->FAM) * COUNT; \ + __p = malloc(__size); \ + *_Generic( \ + __builtin_counted_by_ref(__p->FAM), \ + void *: &__ignored_assignment, \ + default: __builtin_counted_by_ref(__p->FAM)) = COUNT; \ + __p; \ + }) + + The flexible array member (FAM) can now be accessed immediately without causing + issues with the sanitizer because the counter is automatically set. + New Compiler Flags ------------------ diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 9bd67e0cefebc3..3ae6f190dc56f0 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4914,3 +4914,9 @@ def ArithmeticFence : LangBuiltin<"ALL_LANGUAGES"> { let Attributes = [CustomTypeChecking, Constexpr]; let Prototype = "void(...)"; } + +def CountedByRef : Builtin { + let Spellings = ["__builtin_counted_by_ref"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "int(...)"; +} diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 34ff49d7238a7f..2c9de7984f962a 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6652,6 +6652,18 @@ def warn_counted_by_attr_elt_type_unknown_size : Warning, InGroup; +// __builtin_counted_by_ref diagnostics: +def err_builtin_counted_by_ref_must_be_flex_array_member : Error< + "'__builtin_counted_by_ref' argument must reference a flexible array member">; +def err_builtin_counted_by_ref_cannot_leak_reference : Error< + "value returned by '__builtin_counted_by_ref' cannot be assigned to a " + "variable, have its address taken, or passed into or returned from a function">; +def err_builtin_counted_by_ref_invalid_lhs_use : Error< + "value returned by '__builtin_counted_by_ref' cannot be used in " + "%select{an array subscript|a binary}0 expression">; +def err_builtin_counted_by_ref_has_side_effects : Error< + "'__builtin_counted_by_ref' argument cannot have side-effects">; + let CategoryName = "ARC Semantic Issue" in { // ARC-mode diagnostics. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 93d98e1cbb9c81..742e0565e50887 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2510,6 +2510,8 @@ class Sema final : public SemaBase { bool BuiltinNonDeterministicValue(CallExpr *TheCall); + bool BuiltinCountedByRef(CallExpr *TheCall); + // Matrix builtin handling. ExprResult BuiltinMatrixTranspose(CallExpr *TheCall, ExprResult CallResult); ExprResult BuiltinMatrixColumnMajorLoad(CallExpr *TheCall, diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 86913763ef9ff5..29c10d9be3b585 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3656,6 +3656,10 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const { (!hasAttr() && !hasAttr())) return 0; + if (getASTContext().getLangOpts().CPlusPlus && + BuiltinID == Builtin::BI__builtin_counted_by_ref) + return 0; + const ASTContext &Context = getASTContext(); if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) return BuiltinID; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 038057d2164ced..e382f8b3d3d2cf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3691,6 +3691,35 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType, /*EmittedE=*/nullptr, IsDynamic)); } + case Builtin::BI__builtin_counted_by_ref: { + // Default to returning '(void *) 0'. + llvm::Value *Result = llvm::ConstantPointerNull::get( + llvm::PointerType::getUnqual(getLLVMContext())); + + const Expr *Arg = E->getArg(0)->IgnoreParenImpCasts(); + + if (auto *UO = dyn_cast(Arg); + UO && UO->getOpcode() == UO_AddrOf) { + Arg = UO->getSubExpr()->IgnoreParenImpCasts(); + + if (auto *ASE = dyn_cast(Arg)) + Arg = ASE->getBase()->IgnoreParenImpCasts(); + } + + if (const MemberExpr *ME = dyn_cast_if_present(Arg)) { + if (auto *CATy = + ME->getMemberDecl()->getType()->getAs(); + CATy && CATy->getKind() == CountAttributedType::CountedBy) { + const auto *FAMDecl = cast(ME->getMemberDecl()); + if (const FieldDecl *CountFD = FAMDecl->findCountedByField()) + Result = GetCountedByFieldExprGEP(Arg, FAMDecl, CountFD); + else + llvm::report_fatal_error("Cannot find the counted_by 'count' field"); + } + } + + return RValue::get(Result); + } case Builtin::BI__builtin_prefetch: { Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); // FIXME: Technically these constants should of type 'int', yes? diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index e90e8da3e9f1ea..3364a00c6e9ff7 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1145,15 +1145,7 @@ static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD, return false; } -/// This method is typically called in contexts where we can't generate -/// side-effects, like in __builtin_dynamic_object_size. When finding -/// expressions, only choose those that have either already been emitted or can -/// be loaded without side-effects. -/// -/// - \p FAMDecl: the \p Decl for the flexible array member. It may not be -/// within the top-level struct. -/// - \p CountDecl: must be within the same non-anonymous struct as \p FAMDecl. -llvm::Value *CodeGenFunction::EmitLoadOfCountedByField( +llvm::Value *CodeGenFunction::GetCountedByFieldExprGEP( const Expr *Base, const FieldDecl *FAMDecl, const FieldDecl *CountDecl) { const RecordDecl *RD = CountDecl->getParent()->getOuterLexicalRecordContext(); @@ -1182,12 +1174,25 @@ llvm::Value *CodeGenFunction::EmitLoadOfCountedByField( return nullptr; Indices.push_back(Builder.getInt32(0)); - Res = Builder.CreateInBoundsGEP( + return Builder.CreateInBoundsGEP( ConvertType(QualType(RD->getTypeForDecl(), 0)), Res, RecIndicesTy(llvm::reverse(Indices)), "..counted_by.gep"); +} - return Builder.CreateAlignedLoad(ConvertType(CountDecl->getType()), Res, - getIntAlign(), "..counted_by.load"); +/// This method is typically called in contexts where we can't generate +/// side-effects, like in __builtin_dynamic_object_size. When finding +/// expressions, only choose those that have either already been emitted or can +/// be loaded without side-effects. +/// +/// - \p FAMDecl: the \p Decl for the flexible array member. It may not be +/// within the top-level struct. +/// - \p CountDecl: must be within the same non-anonymous struct as \p FAMDecl. +llvm::Value *CodeGenFunction::EmitLoadOfCountedByField( + const Expr *Base, const FieldDecl *FAMDecl, const FieldDecl *CountDecl) { + if (llvm::Value *GEP = GetCountedByFieldExprGEP(Base, FAMDecl, CountDecl)) + return Builder.CreateAlignedLoad(ConvertType(CountDecl->getType()), GEP, + getIntAlign(), "..counted_by.load"); + return nullptr; } void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base, diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 3ff4458fb32024..90dc399f1341f3 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3305,6 +3305,10 @@ class CodeGenFunction : public CodeGenTypeCache { const FieldDecl *FAMDecl, uint64_t &Offset); + llvm::Value *GetCountedByFieldExprGEP(const Expr *Base, + const FieldDecl *FAMDecl, + const FieldDecl *CountDecl); + /// Build an expression accessing the "counted_by" field. llvm::Value *EmitLoadOfCountedByField(const Expr *Base, const FieldDecl *FAMDecl, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index dae271c1ff5001..cf77e8393ce35f 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2971,6 +2971,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, } break; } + case Builtin::BI__builtin_counted_by_ref: + if (BuiltinCountedByRef(TheCall)) + return ExprError(); + break; } if (getLangOpts().HLSL && HLSL().CheckBuiltinFunctionCall(BuiltinID, TheCall)) @@ -5573,6 +5577,55 @@ bool Sema::BuiltinSetjmp(CallExpr *TheCall) { return false; } +bool Sema::BuiltinCountedByRef(CallExpr *TheCall) { + if (checkArgCount(TheCall, 1)) + return true; + + ExprResult ArgRes = UsualUnaryConversions(TheCall->getArg(0)); + if (ArgRes.isInvalid()) + return true; + + // For simplicity, we support only limited expressions for the argument. + // Specifically a pointer to a flexible array member:'ptr->array'. This + // allows us to reject arguments with complex casting, which really shouldn't + // be a huge problem. + const Expr *Arg = ArgRes.get()->IgnoreParenImpCasts(); + if (!isa(Arg->getType()) && !Arg->getType()->isArrayType()) + return Diag(Arg->getBeginLoc(), + diag::err_builtin_counted_by_ref_must_be_flex_array_member) + << Arg->getSourceRange(); + + if (Arg->HasSideEffects(Context)) + return Diag(Arg->getBeginLoc(), + diag::err_builtin_counted_by_ref_has_side_effects) + << Arg->getSourceRange(); + + if (const auto *ME = dyn_cast(Arg)) { + if (!ME->isFlexibleArrayMemberLike( + Context, getLangOpts().getStrictFlexArraysLevel())) + return Diag(Arg->getBeginLoc(), + diag::err_builtin_counted_by_ref_must_be_flex_array_member) + << Arg->getSourceRange(); + + if (auto *CATy = + ME->getMemberDecl()->getType()->getAs(); + CATy && CATy->getKind() == CountAttributedType::CountedBy) { + const auto *FAMDecl = cast(ME->getMemberDecl()); + if (const FieldDecl *CountFD = FAMDecl->findCountedByField()) { + TheCall->setType(Context.getPointerType(CountFD->getType())); + return false; + } + } + } else { + return Diag(Arg->getBeginLoc(), + diag::err_builtin_counted_by_ref_must_be_flex_array_member) + << Arg->getSourceRange(); + } + + TheCall->setType(Context.getPointerType(Context.VoidTy)); + return false; +} + namespace { class UncoveredArgHandler { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 7f3cff1054aeed..fc3438bc1207b6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -9187,6 +9187,38 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, LHSType = Context.getCanonicalType(LHSType).getUnqualifiedType(); RHSType = Context.getCanonicalType(RHSType).getUnqualifiedType(); + // __builtin_counted_by_ref cannot be assigned to a variable, used in + // function call, or in a return. + auto FindBuiltinCountedByRefExpr = [&](Expr *E) -> CallExpr * { + struct BuiltinCountedByRefVisitor + : public RecursiveASTVisitor { + CallExpr *TheCall = nullptr; + bool VisitCallExpr(CallExpr *CE) { + if (CE->getBuiltinCallee() == Builtin::BI__builtin_counted_by_ref) { + TheCall = CE; + return false; + } + return true; + } + bool VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE) { + // A UnaryExprOrTypeTraitExpr---e.g. sizeof, __alignof, etc.---isn't + // the same as a CallExpr, so if we find a __builtin_counted_by_ref() + // call in one, ignore it. + return false; + } + } V; + V.TraverseStmt(E); + return V.TheCall; + }; + static llvm::SmallPtrSet Diagnosed; + if (auto *CE = FindBuiltinCountedByRefExpr(RHS.get()); + CE && !Diagnosed.count(CE)) { + Diagnosed.insert(CE); + Diag(CE->getExprLoc(), + diag::err_builtin_counted_by_ref_cannot_leak_reference) + << CE->getSourceRange(); + } + // Common case: no conversion required. if (LHSType == RHSType) { Kind = CK_NoOp; @@ -13735,6 +13767,43 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, ConvTy = CheckAssignmentConstraints(Loc, LHSType, RHSType); } + // __builtin_counted_by_ref can't be used in a binary expression or array + // subscript on the LHS. + int DiagOption = -1; + auto FindInvalidUseOfBoundsSafetyCounter = [&](Expr *E) -> CallExpr * { + struct BuiltinCountedByRefVisitor + : public RecursiveASTVisitor { + CallExpr *CE = nullptr; + bool InvalidUse = false; + int Option = -1; + + bool VisitCallExpr(CallExpr *E) { + if (E->getBuiltinCallee() == Builtin::BI__builtin_counted_by_ref) { + CE = E; + return false; + } + return true; + } + + bool VisitArraySubscriptExpr(ArraySubscriptExpr *E) { + InvalidUse = true; + Option = 0; // report 'array expression' in diagnostic. + return true; + } + bool VisitBinaryOperator(BinaryOperator *E) { + InvalidUse = true; + Option = 1; // report 'binary expression' in diagnostic. + return true; + } + } V; + V.TraverseStmt(E); + DiagOption = V.Option; + return V.InvalidUse ? V.CE : nullptr; + }; + if (auto *CE = FindInvalidUseOfBoundsSafetyCounter(LHSExpr)) + Diag(CE->getExprLoc(), diag::err_builtin_counted_by_ref_invalid_lhs_use) + << DiagOption << CE->getSourceRange(); + if (DiagnoseAssignmentResult(ConvTy, Loc, LHSType, RHSType, RHS.get(), AssignmentAction::Assigning)) return QualType(); diff --git a/clang/test/AST/ast-print-builtin-counted-by-ref.c b/clang/test/AST/ast-print-builtin-counted-by-ref.c new file mode 100644 index 00000000000000..c0ff7515fc8208 --- /dev/null +++ b/clang/test/AST/ast-print-builtin-counted-by-ref.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -ast-print %s -o - | FileCheck %s + +typedef unsigned long int size_t; + +int global_array[42]; +int global_int; + +struct fam_struct { + int x; + char count; + int array[] __attribute__((counted_by(count))); +}; + +// CHECK-LABEL: void test1(struct fam_struct *ptr, int size) { +// CHECK-NEXT: size_t __ignored_assignment; +// CHECK-NEXT: *_Generic(__builtin_counted_by_ref(ptr->array), void *: &__ignored_assignment, default: __builtin_counted_by_ref(ptr->array)) = 42; +void test1(struct fam_struct *ptr, int size) { + size_t __ignored_assignment; + + *_Generic(__builtin_counted_by_ref(ptr->array), + void *: &__ignored_assignment, + default: __builtin_counted_by_ref(ptr->array)) = 42; // ok +} diff --git a/clang/test/CodeGen/attr-counted-by-pr110385.c b/clang/test/CodeGen/attr-counted-by-pr110385.c index e120dcc583578d..86cbdfd1be41dc 100644 --- a/clang/test/CodeGen/attr-counted-by-pr110385.c +++ b/clang/test/CodeGen/attr-counted-by-pr110385.c @@ -1,5 +1,5 @@ // 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 -O2 -Wno-missing-declarations -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-missing-declarations -emit-llvm -o - %s | FileCheck %s // See #110385 // Based on reproducer from Kees Cook: @@ -26,18 +26,25 @@ struct bucket2 { void init(void * __attribute__((pass_dynamic_object_size(0)))); // CHECK-LABEL: define dso_local void @test1( -// CHECK-SAME: ptr nocapture noundef readonly [[FOO:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-SAME: ptr noundef [[FOO:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[GROWABLE:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 -// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[GROWABLE]], align 8, !tbaa [[TBAA2:![0-9]+]] -// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 12 -// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 +// CHECK-NEXT: [[FOO_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[FOO]], ptr [[FOO_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FOO_ADDR]], align 8 +// CHECK-NEXT: [[GROWABLE:%.*]] = getelementptr inbounds nuw [[STRUCT_BUCKET:%.*]], ptr [[TMP0]], i32 0, i32 1 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[GROWABLE]], align 8 +// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_VARIABLE:%.*]], ptr [[TMP1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i16], ptr [[ARRAY]], i64 0, i64 0 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[FOO_ADDR]], align 8 +// CHECK-NEXT: [[GROWABLE1:%.*]] = getelementptr inbounds nuw [[STRUCT_BUCKET]], ptr [[TMP2]], i32 0, i32 1 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[GROWABLE1]], align 8 +// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_VARIABLE]], ptr [[TMP3]], i32 0, i32 2 // CHECK-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 -// CHECK-NEXT: [[TMP2:%.*]] = shl nsw i64 [[TMP1]], 1 -// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 -// CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 -// CHECK-NEXT: tail call void @init(ptr noundef nonnull [[ARRAY]], i64 noundef [[TMP4]]) #[[ATTR2:[0-9]+]] +// CHECK-NEXT: [[TMP4:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// CHECK-NEXT: [[TMP5:%.*]] = mul nsw i64 [[TMP4]], 2 +// CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i64 [[TMP4]], -1 +// CHECK-NEXT: [[TMP7:%.*]] = select i1 [[TMP6]], i64 [[TMP5]], i64 0 +// CHECK-NEXT: call void @init(ptr noundef [[ARRAYDECAY]], i64 noundef [[TMP7]]) // CHECK-NEXT: ret void // void test1(struct bucket *foo) { @@ -45,16 +52,23 @@ void test1(struct bucket *foo) { } // CHECK-LABEL: define dso_local void @test2( -// CHECK-SAME: ptr noundef [[FOO:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: ptr noundef [[FOO:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 16 -// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 12 +// CHECK-NEXT: [[FOO_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[FOO]], ptr [[FOO_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FOO_ADDR]], align 8 +// CHECK-NEXT: [[GROWABLE:%.*]] = getelementptr inbounds nuw [[STRUCT_BUCKET2:%.*]], ptr [[TMP0]], i32 0, i32 1 +// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_VARIABLE:%.*]], ptr [[GROWABLE]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i16], ptr [[ARRAY]], i64 0, i64 0 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[FOO_ADDR]], align 8 +// CHECK-NEXT: [[GROWABLE1:%.*]] = getelementptr inbounds nuw [[STRUCT_BUCKET2]], ptr [[TMP1]], i32 0, i32 1 +// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_VARIABLE]], ptr [[GROWABLE1]], i32 0, i32 2 // CHECK-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 -// CHECK-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 1 -// CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 -// CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 -// CHECK-NEXT: tail call void @init(ptr noundef nonnull [[ARRAY]], i64 noundef [[TMP3]]) #[[ATTR2]] +// CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// CHECK-NEXT: [[TMP3:%.*]] = mul nsw i64 [[TMP2]], 2 +// CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i64 [[TMP2]], -1 +// CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP4]], i64 [[TMP3]], i64 0 +// CHECK-NEXT: call void @init(ptr noundef [[ARRAYDECAY]], i64 noundef [[TMP5]]) // CHECK-NEXT: ret void // void test2(struct bucket2 *foo) { diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c index f70e552bca26ab..87785c8545161c 100644 --- a/clang/test/CodeGen/attr-counted-by.c +++ b/clang/test/CodeGen/attr-counted-by.c @@ -1,8 +1,8 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 3 -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -DCOUNTED_BY -O2 -Wall -fsanitize=array-bounds,object-size,local-bounds -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=SANITIZE-WITH-ATTR %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -DCOUNTED_BY -O2 -Wall -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=NO-SANITIZE-WITH-ATTR %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wall -fsanitize=array-bounds,object-size,local-bounds -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=SANITIZE-WITHOUT-ATTR %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wall -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=NO-SANITIZE-WITHOUT-ATTR %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -DCOUNTED_BY -Wall -fsanitize=array-bounds,object-size,local-bounds -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=SANITIZE-WITH-ATTR %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -DCOUNTED_BY -Wall -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=NO-SANITIZE-WITH-ATTR %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wall -fsanitize=array-bounds,object-size,local-bounds -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=SANITIZE-WITHOUT-ATTR %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wall -fstrict-flex-arrays=3 -emit-llvm -o - %s | FileCheck --check-prefix=NO-SANITIZE-WITHOUT-ATTR %s #if !__has_attribute(counted_by) #error "has attribute broken" @@ -57,48 +57,116 @@ struct anon_struct { }; // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test1( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP1]], i1 false, i1 false, i1 false), !nosanitize [[META2:![0-9]+]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp uge i64 [[TMP2]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB1:[0-9]+]], i64 [[TMP4]]) #[[ATTR5:[0-9]+]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP1]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP5]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i32 -4 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2:![0-9]+]] -// 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-NEXT: [[TMP6:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP6]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP7]], 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 @[[GLOB1:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9:[0-9]+]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB4:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont3: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 +// SANITIZE-WITH-ATTR: cont1: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[VAL]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4:![0-9]+]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP9]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB5:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX]], align 4 // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test1( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP1]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP2]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[VAL]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test1( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP1]], i1 false, i1 false, i1 false), !nosanitize [[META2:![0-9]+]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = icmp uge i64 [[TMP2]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP3]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[TMP1]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB1:[0-9]+]], i64 [[TMP4]]) #[[ATTR5:[0-9]+]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP1]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP5]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[VAL]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = icmp uge i64 [[TMP6]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP7]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB3:[0-9]+]], i64 [[TMP8]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX]], align 4 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test1( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP1]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP2]] to i64 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[VAL]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX]], align 4 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test1(struct annotated *p, int index, int val) { @@ -106,133 +174,309 @@ void test1(struct annotated *p, int index, int val) { } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 1 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[INDEX]], [[TMP0]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nsw i64 [[TMP1]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP4]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP5]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp uge i64 [[TMP6]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP7]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP5]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB6:[0-9]+]], i64 [[TMP8]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP5]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i32 -4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp ult i64 [[TMP9]], [[TMP10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], 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 @[[GLOB3:[0-9]+]], i64 [[INDEX]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB8:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[TMP9]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = icmp uge i64 [[TMP12]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP13]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB9:[0-9]+]], i64 [[TMP14]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP2]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 1 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP0]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nsw i64 [[TMP1]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP4]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP5]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[TMP6]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test2( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB4:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP4]] to i32 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP5]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = icmp uge i64 [[TMP6]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP7]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP5]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB5:[0-9]+]], i64 [[TMP8]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY3:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP5]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY3]], i64 0, i64 [[TMP9]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP11]], label [[CONT5:%.*]], label [[HANDLER_TYPE_MISMATCH4:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB6:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont5: +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test2( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP2]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY1]], i64 0, i64 [[TMP3]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test2(struct annotated *p, size_t index) { p->array[index] = __builtin_dynamic_object_size(p->array, 1); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test2_bdos( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 1 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 -// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]] -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nsw i64 [[TMP1]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]] +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test2_bdos( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 1 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nsw i64 [[TMP1]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test2_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB7:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP4]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test2_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP1]] // size_t test2_bdos(struct annotated *p) { return __builtin_dynamic_object_size(p->array, 1); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test3( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB10:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP2]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i32 -4 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[INDEX]], [[TMP0]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp ult i64 [[TMP6]], [[TMP7]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP8]], 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 @[[GLOB4:[0-9]+]], i64 [[INDEX]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB11:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[TMP6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = icmp uge i64 [[TMP9]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP10]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB12:[0-9]+]], i64 [[TMP11]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] -// SANITIZE-WITH-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test3( -// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP2]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[TMP3]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test3( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB8:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP2]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[TMP6]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = icmp uge i64 [[TMP7]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP8]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB9:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test3( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP2]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[TMP3]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test3(struct annotated *p, size_t index) { @@ -242,164 +486,426 @@ void test3(struct annotated *p, size_t index) { } // SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test3_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test3_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test3_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test3_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP1]] // size_t test3_bdos(struct annotated *p) { return __builtin_dynamic_object_size(p, 0); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: [[FAM_IDX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[FAM_IDX]], ptr [[FAM_IDX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 1 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// 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-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sub nsw i64 [[TMP1]], 3 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = mul nsw i64 [[TMP2]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i64 [[TMP2]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 true, [[TMP4]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = select i1 [[TMP5]], i64 [[TMP3]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP6]] to i8 +// SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = zext i8 [[CONV]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP7]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP9]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP7]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB13:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP7]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP11]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i32 -4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP12]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP13]], label [[CONT2:%.*]], 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 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB14:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !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 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], 244 -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = select i1 [[TMP2]], i32 [[TMP5]], i32 0 +// SANITIZE-WITH-ATTR: cont2: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD6:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = icmp uge i64 [[TMP14]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP15]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch3: +// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB15:[0-9]+]], i64 [[TMP16]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont4: +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP5:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[TMP17]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD6:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP5]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD6]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = sub nsw i64 [[TMP18]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP20:%.*]] = mul nsw i64 [[TMP19]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = icmp sgt i64 [[TMP19]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP22:%.*]] = and i1 true, [[TMP21]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP23:%.*]] = select i1 [[TMP22]], i64 [[TMP20]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: [[CONV7:%.*]] = trunc i64 [[TMP23]] to i8 +// SANITIZE-WITH-ATTR-NEXT: [[CONV8:%.*]] = zext i8 [[CONV7]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP24:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP25:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP24]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP26:%.*]] = icmp uge i64 [[TMP25]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP26]], label [[CONT10:%.*]], label [[HANDLER_TYPE_MISMATCH9:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch9: +// SANITIZE-WITH-ATTR-NEXT: [[TMP27:%.*]] = ptrtoint ptr [[TMP24]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB16:[0-9]+]], i64 [[TMP27]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont10: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY11:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP24]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP28:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP28]], 1 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM12:%.*]] = sext i32 [[ADD]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD6]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp ult i64 [[IDXPROM12]], [[TMP6]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP7]], label [[CONT19:%.*]], label [[HANDLER_OUT_OF_BOUNDS15:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP13:%.*]] = getelementptr inbounds i8, ptr [[ARRAY11]], i32 -4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD14:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP13]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP29:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD14]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP30:%.*]] = icmp ult i64 [[IDXPROM12]], [[TMP29]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP30]], label [[CONT16:%.*]], label [[HANDLER_OUT_OF_BOUNDS15:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds15: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM12]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB17:[0-9]+]], i64 [[IDXPROM12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont16: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY11]], i64 0, i64 [[IDXPROM12]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP31:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX17]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP32:%.*]] = icmp uge i64 [[TMP31]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP32]], label [[CONT19:%.*]], label [[HANDLER_TYPE_MISMATCH18:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch18: +// SANITIZE-WITH-ATTR-NEXT: [[TMP33:%.*]] = ptrtoint ptr [[ARRAYIDX17]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB18:[0-9]+]], i64 [[TMP33]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont19: -// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD6]], 3 -// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD6]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = add i32 [[TMP9]], 240 -// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = and i32 [[TMP10]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV8:%.*]] = select i1 [[TMP8]], i32 [[TMP11]], i32 0 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM12]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV8]], ptr [[ARRAYIDX17]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD21:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[ADD27:%.*]] = add nsw i32 [[INDEX]], 2 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV8]], ptr [[ARRAYIDX17]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP34:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP20:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[TMP34]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD21:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP20]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP35:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD21]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP36:%.*]] = load i32, ptr [[FAM_IDX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP38:%.*]] = sub nsw i64 [[TMP35]], [[TMP37]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP39:%.*]] = mul nsw i64 [[TMP38]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP40:%.*]] = icmp sgt i64 [[TMP38]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP41:%.*]] = icmp sgt i64 [[TMP37]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP42:%.*]] = and i1 [[TMP41]], [[TMP40]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP43:%.*]] = select i1 [[TMP42]], i64 [[TMP39]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: [[CONV22:%.*]] = trunc i64 [[TMP43]] to i8 +// SANITIZE-WITH-ATTR-NEXT: [[CONV23:%.*]] = zext i8 [[CONV22]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP44:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP45:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP44]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP46:%.*]] = icmp uge i64 [[TMP45]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP46]], label [[CONT25:%.*]], label [[HANDLER_TYPE_MISMATCH24:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch24: +// SANITIZE-WITH-ATTR-NEXT: [[TMP47:%.*]] = ptrtoint ptr [[TMP44]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB19:[0-9]+]], i64 [[TMP47]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont25: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY26:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP44]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP48:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP48]], 2 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM28:%.*]] = sext i32 [[ADD27]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD21]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = icmp ult i64 [[IDXPROM28]], [[TMP12]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP13]], label [[CONT35:%.*]], label [[HANDLER_OUT_OF_BOUNDS31:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP29:%.*]] = getelementptr inbounds i8, ptr [[ARRAY26]], i32 -4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD30:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP29]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP49:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD30]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP50:%.*]] = icmp ult i64 [[IDXPROM28]], [[TMP49]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP50]], label [[CONT32:%.*]], label [[HANDLER_OUT_OF_BOUNDS31:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds31: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[IDXPROM28]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB20:[0-9]+]], i64 [[IDXPROM28]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont32: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY26]], i64 0, i64 [[IDXPROM28]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP51:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX33]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP52:%.*]] = icmp uge i64 [[TMP51]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP52]], label [[CONT35:%.*]], label [[HANDLER_TYPE_MISMATCH34:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch34: +// SANITIZE-WITH-ATTR-NEXT: [[TMP53:%.*]] = ptrtoint ptr [[ARRAYIDX33]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB21:[0-9]+]], i64 [[TMP53]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont35: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM28]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = icmp sgt i32 [[FAM_IDX]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD21]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = sext i32 [[FAM_IDX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = sub nsw i64 [[TMP15]], [[TMP16]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = icmp sgt i64 [[TMP17]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = and i1 [[TMP14]], [[TMP18]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP17]] to i32 -// SANITIZE-WITH-ATTR-NEXT: [[TMP20:%.*]] = shl i32 [[DOTTR]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = and i32 [[TMP20]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV23:%.*]] = select i1 [[TMP19]], i32 [[TMP21]], i32 0 -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV23]], ptr [[ARRAYIDX33]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV23]], ptr [[ARRAYIDX33]], align 4 // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[FAM_IDX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[FAM_IDX]], ptr [[FAM_IDX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 1 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 244 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i32 [[TMP1]], 252 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sub nsw i64 [[TMP1]], 3 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = mul nsw i64 [[TMP2]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i64 [[TMP2]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 true, [[TMP4]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = select i1 [[TMP5]], i64 [[TMP3]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP6]] to i8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = zext i8 [[CONV]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP7]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP8]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD3:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD3]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], 240 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD3]], 3 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = and i32 [[TMP5]], 252 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV5:%.*]] = select i1 [[TMP6]], i32 [[TMP7]], i32 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP2:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[TMP9]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD3:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP2]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD3]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = sub nsw i64 [[TMP10]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = mul nsw i64 [[TMP11]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = icmp sgt i64 [[TMP11]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = and i1 true, [[TMP13]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = select i1 [[TMP14]], i64 [[TMP12]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV4:%.*]] = trunc i64 [[TMP15]] to i8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV5:%.*]] = zext i8 [[CONV4]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY6:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP16]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP17]], 1 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM7:%.*]] = sext i32 [[ADD]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM7]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV5]], ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD10:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD10]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = sext i32 [[FAM_IDX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = sub nsw i64 [[TMP8]], [[TMP9]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp sgt i64 [[TMP10]], -1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[FAM_IDX]], -1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = and i1 [[TMP12]], [[TMP11]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP10]] to i32 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = shl i32 [[DOTTR]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = and i32 [[TMP14]], 252 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV12:%.*]] = select i1 [[TMP13]], i32 [[TMP15]], i32 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ADD14:%.*]] = add nsw i32 [[INDEX]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY6]], i64 0, i64 [[IDXPROM7]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV5]], ptr [[ARRAYIDX8]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP9:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED]], ptr [[TMP18]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD10:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP9]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD10]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP20:%.*]] = load i32, ptr [[FAM_IDX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = sext i32 [[TMP20]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP22:%.*]] = sub nsw i64 [[TMP19]], [[TMP21]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP23:%.*]] = mul nsw i64 [[TMP22]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP24:%.*]] = icmp sgt i64 [[TMP22]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP25:%.*]] = icmp sgt i64 [[TMP21]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP26:%.*]] = and i1 [[TMP25]], [[TMP24]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP27:%.*]] = select i1 [[TMP26]], i64 [[TMP23]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV11:%.*]] = trunc i64 [[TMP27]] to i8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV12:%.*]] = zext i8 [[CONV11]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP28:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY13:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP28]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP29:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP29]], 2 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM15:%.*]] = sext i32 [[ADD14]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM15]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV12]], ptr [[ARRAYIDX16]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY13]], i64 0, i64 [[IDXPROM15]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV12]], ptr [[ARRAYIDX16]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test4( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX5]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[FAM_IDX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[FAM_IDX]], ptr [[FAM_IDX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB10:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 3 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP4]] to i8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV1:%.*]] = zext i8 [[CONV]] to i32 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP5]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = icmp uge i64 [[TMP6]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP7]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP5]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB11:[0-9]+]], i64 [[TMP8]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY4:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP5]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP9]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY4]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX5]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP11]], label [[CONT7:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch6: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[ARRAYIDX5]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB12:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont7: +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX5]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP13:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP14:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP13]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP15:%.*]] = icmp uge i64 [[TMP14]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP15]], label [[CONT9:%.*]], label [[HANDLER_TYPE_MISMATCH8:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch8: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP16:%.*]] = ptrtoint ptr [[TMP13]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB13:[0-9]+]], i64 [[TMP16]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont9: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY10:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP13]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY10]], i64 0, i64 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP17:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX11]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV12:%.*]] = trunc i64 [[TMP17]] to i8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV13:%.*]] = zext i8 [[CONV12]] to i32 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP18:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP19:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP18]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP20:%.*]] = icmp uge i64 [[TMP19]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP20]], label [[CONT15:%.*]], label [[HANDLER_TYPE_MISMATCH14:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch14: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP21:%.*]] = ptrtoint ptr [[TMP18]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB14:[0-9]+]], i64 [[TMP21]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont15: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY16:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP18]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP22:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP22]], 1 // SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM17:%.*]] = sext i32 [[ADD]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM17]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX18]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[ADD31:%.*]] = add nsw i32 [[INDEX]], 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY16]], i64 0, i64 [[IDXPROM17]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP23:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX18]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP24:%.*]] = icmp uge i64 [[TMP23]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP24]], label [[CONT20:%.*]], label [[HANDLER_TYPE_MISMATCH19:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch19: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP25:%.*]] = ptrtoint ptr [[ARRAYIDX18]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB15:[0-9]+]], i64 [[TMP25]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont20: +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV13]], ptr [[ARRAYIDX18]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP26:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP27:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP26]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP28:%.*]] = icmp uge i64 [[TMP27]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP28]], label [[CONT22:%.*]], label [[HANDLER_TYPE_MISMATCH21:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch21: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP29:%.*]] = ptrtoint ptr [[TMP26]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB16:[0-9]+]], i64 [[TMP29]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont22: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY23:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP26]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP30:%.*]] = load i32, ptr [[FAM_IDX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM24:%.*]] = sext i32 [[TMP30]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY23]], i64 0, i64 [[IDXPROM24]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP31:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX25]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV26:%.*]] = trunc i64 [[TMP31]] to i8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV27:%.*]] = zext i8 [[CONV26]] to i32 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP32:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP33:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP32]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP34:%.*]] = icmp uge i64 [[TMP33]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP34]], label [[CONT29:%.*]], label [[HANDLER_TYPE_MISMATCH28:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch28: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP35:%.*]] = ptrtoint ptr [[TMP32]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB17:[0-9]+]], i64 [[TMP35]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont29: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY30:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP32]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP36:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ADD31:%.*]] = add nsw i32 [[TMP36]], 2 // SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM32:%.*]] = sext i32 [[ADD31]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM32]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX33]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY30]], i64 0, i64 [[IDXPROM32]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP37:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX33]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP38:%.*]] = icmp uge i64 [[TMP37]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP38]], label [[CONT35:%.*]], label [[HANDLER_TYPE_MISMATCH34:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch34: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP39:%.*]] = ptrtoint ptr [[ARRAYIDX33]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB18:[0-9]+]], i64 [[TMP39]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont35: +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV27]], ptr [[ARRAYIDX33]], align 4 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test4( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX3]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[FAM_IDX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[FAM_IDX]], ptr [[FAM_IDX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 3 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV1:%.*]] = zext i8 [[CONV]] to i32 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY2:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP2]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP3]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY2]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX3]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY4:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP4]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY4]], i64 0, i64 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX5]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV6:%.*]] = trunc i64 [[TMP5]] to i8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV7:%.*]] = zext i8 [[CONV6]] to i32 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY8:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP6]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP7]], 1 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM9:%.*]] = sext i32 [[ADD]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM9]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX10]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ADD17:%.*]] = add nsw i32 [[INDEX]], 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY8]], i64 0, i64 [[IDXPROM9]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV7]], ptr [[ARRAYIDX10]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY11:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP8]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = load i32, ptr [[FAM_IDX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM12:%.*]] = sext i32 [[TMP9]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY11]], i64 0, i64 [[IDXPROM12]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX13]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV14:%.*]] = trunc i64 [[TMP10]] to i8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV15:%.*]] = zext i8 [[CONV14]] to i32 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY16:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP11]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ADD17:%.*]] = add nsw i32 [[TMP12]], 2 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM18:%.*]] = sext i32 [[ADD17]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM18]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 255, ptr [[ARRAYIDX19]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY16]], i64 0, i64 [[IDXPROM18]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV15]], ptr [[ARRAYIDX19]], align 4 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test4(struct annotated *p, int index, int fam_idx) { @@ -409,92 +915,204 @@ void test4(struct annotated *p, int index, int fam_idx) { p->array[index + 2] = (unsigned char)__builtin_dynamic_object_size(&(p->array[fam_idx]), 1); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869180, 17179869181) i64 @test4_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test4_bdos( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 1 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sub nsw i64 [[TMP0]], [[TMP1]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nsw i64 [[TMP2]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i64 [[TMP2]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[INDEX]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = select i1 [[TMP6]], i64 [[TMP3]], i64 0 -// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP7]] -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869180, 17179869181) i64 @test4_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = sext i32 [[TMP2]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = sub nsw i64 [[TMP1]], [[TMP3]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = mul nsw i64 [[TMP4]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i64 [[TMP4]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp sgt i64 [[TMP3]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = select i1 [[TMP8]], i64 [[TMP5]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP9]] +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test4_bdos( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 1 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sub nsw i64 [[TMP0]], [[TMP1]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nsw i64 [[TMP2]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i64 [[TMP2]], -1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[INDEX]], -1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = select i1 [[TMP6]], i64 [[TMP3]], i64 0 -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP7]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = sext i32 [[TMP2]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = sub nsw i64 [[TMP1]], [[TMP3]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = mul nsw i64 [[TMP4]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i64 [[TMP4]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp sgt i64 [[TMP3]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = select i1 [[TMP8]], i64 [[TMP5]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP9]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test4_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB19:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP5]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test4_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP2]] // size_t test4_bdos(struct annotated *p, int index) { return __builtin_dynamic_object_size(&p->array[index], 1); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test5( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB23:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP2]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP6]], i32 0, i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP7]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i32 -8 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOTCOUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[DOTCOUNTED_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-NEXT: [[TMP8:%.*]] = icmp ult i64 [[IDXPROM]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP8]], 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 @[[GLOB8:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB25:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = icmp uge i64 [[TMP9]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP10]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB26:[0-9]+]], i64 [[TMP11]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP1]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test5( -// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP0]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP2]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP3]], i32 0, i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test5( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP0]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB21:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP2]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP6]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP7]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP9]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB22:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test5( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP0]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP2]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP3]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test5(struct anon_struct *p, int index) { @@ -502,164 +1120,396 @@ void test5(struct anon_struct *p, int index) { } // SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test5_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test5_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test5_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test5_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP1]] // size_t test5_bdos(struct anon_struct *p) { return __builtin_dynamic_object_size(p, 1); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test6( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 1 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// 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-NEXT: [[TMP1:%.*]] = mul nuw i64 [[DOT_COUNTED_BY_LOAD]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i64 [[DOT_COUNTED_BY_LOAD]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP3]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp uge i64 [[TMP5]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB27:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT]], ptr [[TMP4]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP8]], i32 0, i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP9]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i32 -8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = icmp ult i64 [[IDXPROM]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP10]], 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 @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB28:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = icmp uge i64 [[TMP11]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP12]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB29:[0-9]+]], i64 [[TMP13]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP1]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i64 [[DOT_COUNTED_BY_LOAD]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD_TR:%.*]] = trunc i64 [[DOT_COUNTED_BY_LOAD]] to i32 -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD_TR]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP2]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test6( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 1 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i64 [[DOT_COUNTED_BY_LOAD]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD_TR:%.*]] = trunc i64 [[DOT_COUNTED_BY_LOAD]] to i32 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD_TR]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP0]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP1]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = mul nuw i64 [[DOT_COUNTED_BY_LOAD]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i64 [[DOT_COUNTED_BY_LOAD]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP3]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT]], ptr [[TMP4]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP5]], i32 0, i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test6( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP0]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB23:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP4]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP5]] to i32 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP6]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = icmp uge i64 [[TMP7]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP8]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB24:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT]], ptr [[TMP6]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY3:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP10]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP11]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY3]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP13:%.*]] = icmp uge i64 [[TMP12]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP13]], label [[CONT5:%.*]], label [[HANDLER_TYPE_MISMATCH4:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP14:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB25:[0-9]+]], i64 [[TMP14]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont5: +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test6( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP0]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP1]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP2]] to i32 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT]], ptr [[TMP3]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[TMP4]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP5]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY1]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test6(struct anon_struct *p, int index) { p->array[index] = __builtin_dynamic_object_size(p->array, 1); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, -3) i64 @test6_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test6_bdos( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 1 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl nuw i64 [[DOT_COUNTED_BY_LOAD]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i64 [[DOT_COUNTED_BY_LOAD]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[DOTINV]], i64 0, i64 [[TMP0]] -// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = mul nuw i64 [[DOT_COUNTED_BY_LOAD]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i64 [[DOT_COUNTED_BY_LOAD]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]] // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, -3) i64 @test6_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test6_bdos( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 1 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl nuw i64 [[DOT_COUNTED_BY_LOAD]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i64 [[DOT_COUNTED_BY_LOAD]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[DOTINV]], i64 0, i64 [[TMP0]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = mul nuw i64 [[DOT_COUNTED_BY_LOAD]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i64 [[DOT_COUNTED_BY_LOAD]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test6_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB26:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP4]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP5]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test6_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_STRUCT:%.*]], ptr [[TMP0]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON:%.*]], ptr [[TMP1]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP2]] // size_t test6_bdos(struct anon_struct *p) { return __builtin_dynamic_object_size(p->array, 1); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test7( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i8, ptr [[TMP0]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i8 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// 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-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB31:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP2]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP6]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp uge i64 [[TMP7]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP8]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB33:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP6]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 1, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch3: +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB35:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont4: +// SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1:%.*]], ptr [[TMP6]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP13]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[INTS]], i32 -1 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = zext i8 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP14]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP15]], 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 @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB37:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont7: -// SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 +// SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8:![0-9]+]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = icmp uge i64 [[TMP16]], 1, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP17]], label [[CONT7:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch6: +// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB39:[0-9]+]], i64 [[TMP18]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont7: +// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test7( -// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP2]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1:%.*]], ptr [[TMP3]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6:![0-9]+]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test7( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB28:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP2]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP6]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = icmp uge i64 [[TMP7]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP8]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB30:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP6]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 1, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP11]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB32:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1:%.*]], ptr [[TMP6]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP13:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP13]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6:![0-9]+]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP14:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP15:%.*]] = icmp uge i64 [[TMP14]], 1, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP15]], label [[CONT6:%.*]], label [[HANDLER_TYPE_MISMATCH5:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch5: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP16:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB34:[0-9]+]], i64 [[TMP16]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont6: +// SANITIZE-WITHOUT-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test7( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP2]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1:%.*]], ptr [[TMP3]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6:![0-9]+]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test7(struct union_of_fams *p, int index) { @@ -667,153 +1517,465 @@ void test7(struct union_of_fams *p, int index) { } // SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test7_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test7_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test7_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test7_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP1]] // size_t test7_bdos(struct union_of_fams *p) { return __builtin_dynamic_object_size(p, 1); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test8( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1, i32 0, i32 0 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP1]], 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP4]] to i8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP5]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp uge i64 [[TMP6]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP7]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP5]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB40:[0-9]+]], i64 [[TMP8]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS]], ptr [[TMP5]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP9]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[TMP9]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB41:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP9]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = icmp uge i64 [[TMP13]], 1, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP14]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch3: +// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = ptrtoint ptr [[TMP9]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB42:[0-9]+]], i64 [[TMP15]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont4: +// SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1:%.*]], ptr [[TMP9]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP16]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[INTS]], i32 -1 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = zext i8 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP17]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP18]], 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 @[[GLOB12:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB43:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !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 +// SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i8 [[DOT_COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP20:%.*]] = icmp uge i64 [[TMP19]], 1, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP20]], label [[CONT7:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch6: +// SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB44:[0-9]+]], i64 [[TMP21]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont7: +// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test8( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1, i32 0, i32 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP1]], 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP4]] to i8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS]], ptr [[TMP5]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1:%.*]], ptr [[TMP6]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP7]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[DOT_COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test8( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB35:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = icmp uge i64 [[TMP5]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP6]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB36:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 1, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP9]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB37:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1:%.*]], ptr [[TMP4]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP11]] to i8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP13:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP12]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP14:%.*]] = icmp uge i64 [[TMP13]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP14]], label [[CONT6:%.*]], label [[HANDLER_TYPE_MISMATCH5:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch5: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP15:%.*]] = ptrtoint ptr [[TMP12]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB38:[0-9]+]], i64 [[TMP15]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont6: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS]], ptr [[TMP12]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP17:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP16]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP18:%.*]] = icmp uge i64 [[TMP17]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP18]], label [[CONT8:%.*]], label [[HANDLER_TYPE_MISMATCH7:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch7: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP19:%.*]] = ptrtoint ptr [[TMP16]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB39:[0-9]+]], i64 [[TMP19]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont8: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP20:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP16]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP21:%.*]] = icmp uge i64 [[TMP20]], 1, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP21]], label [[CONT10:%.*]], label [[HANDLER_TYPE_MISMATCH9:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch9: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP22:%.*]] = ptrtoint ptr [[TMP16]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB40:[0-9]+]], i64 [[TMP22]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont10: +// SANITIZE-WITHOUT-ATTR-NEXT: [[INTS11:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1]], ptr [[TMP16]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP23:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP23]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS11]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP24:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP25:%.*]] = icmp uge i64 [[TMP24]], 1, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP25]], label [[CONT13:%.*]], label [[HANDLER_TYPE_MISMATCH12:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch12: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB41:[0-9]+]], i64 [[TMP26]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont13: +// SANITIZE-WITHOUT-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test8( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1:%.*]], ptr [[TMP1]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP2]] to i8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS]], ptr [[TMP3]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INTS1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1]], ptr [[TMP4]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP5]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS1]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test8(struct union_of_fams *p, int index) { p->ints[index] = __builtin_dynamic_object_size(p->ints, 1); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 256) i64 @test8_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test8_bdos( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1, i32 0, i32 0 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64 -// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 256) i64 @test8_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP1]], 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]] +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test8_bdos( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1, i32 0, i32 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP1]], 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test8_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB42:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = icmp uge i64 [[TMP5]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP6]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB43:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 1, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP9]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB44:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1:%.*]], ptr [[TMP4]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP11]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test8_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_1:%.*]], ptr [[TMP1]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP2]] // size_t test8_bdos(struct union_of_fams *p) { return __builtin_dynamic_object_size(p->ints, 1); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test9( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// 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-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB45:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP2]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP6]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp uge i64 [[TMP7]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP8]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB46:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP6]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch3: +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB48:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont4: +// SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP6]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP13]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i32 -4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP14]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP15]], 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 @[[GLOB14:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB50:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont7: -// SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 +// SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = icmp uge i64 [[TMP16]], 1, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP17]], label [[CONT7:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch6: +// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB51:[0-9]+]], i64 [[TMP18]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont7: +// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test9( -// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP2]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP3]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test9( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB45:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP2]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP6]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = icmp uge i64 [[TMP7]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP8]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB46:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP6]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP11]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB48:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP6]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP13:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP13]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP14:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP15:%.*]] = icmp uge i64 [[TMP14]], 1, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP15]], label [[CONT6:%.*]], label [[HANDLER_TYPE_MISMATCH5:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch5: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP16:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB49:[0-9]+]], i64 [[TMP16]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont6: +// SANITIZE-WITHOUT-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test9( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP2]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP3]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test9(struct union_of_fams *p, int index) { @@ -821,189 +1983,318 @@ void test9(struct union_of_fams *p, int index) { } // SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test9_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test9_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test9_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test9_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP1]] // size_t test9_bdos(struct union_of_fams *p) { return __builtin_dynamic_object_size(p, 1); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test10( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1, i32 0, i32 0 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nsw i64 [[TMP1]], 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP4]] to i8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP5]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp uge i64 [[TMP6]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP7]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP5]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB52:[0-9]+]], i64 [[TMP8]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS]], ptr [[TMP5]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP9]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[TMP9]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB53:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP9]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = icmp uge i64 [[TMP13]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP14]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch3: +// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = ptrtoint ptr [[TMP9]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB54:[0-9]+]], i64 [[TMP15]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont4: +// SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP9]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP16]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i32 -4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP17]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP18]], 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 @[[GLOB15:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB55:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !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 +// SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8 -// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP20:%.*]] = icmp uge i64 [[TMP19]], 1, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP20]], label [[CONT7:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch6: +// SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB56:[0-9]+]], i64 [[TMP21]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont7: +// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test10( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1, i32 0, i32 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nsw i64 [[TMP1]], 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP4]] to i8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS]], ptr [[TMP5]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP6]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP7]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test10( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB50:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = icmp uge i64 [[TMP5]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP6]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB51:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP9]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB52:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP4]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP11]] to i8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP13:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP12]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP14:%.*]] = icmp uge i64 [[TMP13]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP14]], label [[CONT6:%.*]], label [[HANDLER_TYPE_MISMATCH5:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch5: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP15:%.*]] = ptrtoint ptr [[TMP12]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB53:[0-9]+]], i64 [[TMP15]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont6: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS]], ptr [[TMP12]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP17:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP16]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP18:%.*]] = icmp uge i64 [[TMP17]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP18]], label [[CONT8:%.*]], label [[HANDLER_TYPE_MISMATCH7:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch7: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP19:%.*]] = ptrtoint ptr [[TMP16]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB54:[0-9]+]], i64 [[TMP19]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont8: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP20:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP16]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP21:%.*]] = icmp uge i64 [[TMP20]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP21]], label [[CONT10:%.*]], label [[HANDLER_TYPE_MISMATCH9:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch9: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP22:%.*]] = ptrtoint ptr [[TMP16]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB55:[0-9]+]], i64 [[TMP22]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont10: +// SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES11:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0]], ptr [[TMP16]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP23:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP23]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES11]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP24:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP25:%.*]] = icmp uge i64 [[TMP24]], 1, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP25]], label [[CONT13:%.*]], label [[HANDLER_TYPE_MISMATCH12:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch12: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB56:[0-9]+]], i64 [[TMP26]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont13: +// SANITIZE-WITHOUT-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test10( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP1]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP2]] to i8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS]], ptr [[TMP3]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0]], ptr [[TMP4]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP5]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES1]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test10(struct union_of_fams *p, int index) { p->bytes[index] = (unsigned char)__builtin_dynamic_object_size(p->bytes, 1); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test10_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test10_bdos( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1, i32 0, i32 0 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext nneg i32 [[NARROW]] to i64 -// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test10_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nsw i64 [[TMP1]], 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]] +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test10_bdos( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1, i32 0, i32 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext nneg i32 [[NARROW]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = mul nsw i64 [[TMP1]], 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i64 [[TMP1]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test10_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB57:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = icmp uge i64 [[TMP5]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP6]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB58:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP9]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB59:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP4]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP11]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test10_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_UNION_OF_FAMS:%.*]], ptr [[TMP0]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP1]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP2]] // size_t test10_bdos(struct union_of_fams *p) { return __builtin_dynamic_object_size(p->bytes, 1); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test11( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// 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]]) #[[ATTR9]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont3: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test11( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret void -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test11( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test11( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void -// -void test11(struct annotated *p, int index) { - p->array[index] = __builtin_dynamic_object_size(&p->count, 1); -} - -// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test11_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { -// SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: ret i64 4 -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test11_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { -// NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 4 -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test11_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { -// SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 4 -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test11_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { -// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 4 -// -size_t test11_bdos(struct annotated *p) { - return __builtin_dynamic_object_size(&p->count, 1); -} - struct { struct { struct { @@ -1011,280 +2302,604 @@ struct { }; }; int entries[] __attribute__((__counted_by__(num_entries))); -} test12_foo; +} test11_foo; struct hang { int entries[6]; -} test12_bar; +} test11_bar; -int test12_a, test12_b; +int test11_a, test11_b; -// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test12( -// SANITIZE-WITH-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test11( +// SANITIZE-WITH-ATTR-SAME: i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 // 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]]) #[[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-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[BAZ]], ptr align 4 @test11_bar, i64 24, i1 false) +// SANITIZE-WITH-ATTR-NEXT: br label [[FOR_COND:%.*]] +// SANITIZE-WITH-ATTR: for.cond: +// SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw [[STRUCT_HANG]], ptr [[BAZ]], i32 0, i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 6, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], 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]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB58:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !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]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP2]], ptr @test12_b, align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr @test12_foo, align 4 -// 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-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX_IDX:%.*]] = mul i64 [[IDXPROM]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i64 0, [[ARRAYIDX_IDX]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp uge i64 [[TMP5]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label [[CONT1:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB59:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = sub i64 24, [[TMP4]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp ult i64 24, [[TMP4]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = icmp ult i64 [[TMP8]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = or i1 [[TMP9]], [[TMP10]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[TRAP:%.*]], label [[TMP12:%.*]] +// SANITIZE-WITH-ATTR: 12: +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP13]], ptr @test11_b, align 4 +// SANITIZE-WITH-ATTR-NEXT: br label [[FOR_INC:%.*]] +// SANITIZE-WITH-ATTR: for.inc: +// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr @test11_foo, i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = icmp uge i64 [[TMP14]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP15]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch2: +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB61:[0-9]+]], i64 ptrtoint (ptr @test11_foo to i64)) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr getelementptr inbounds nuw ([[STRUCT_ANON_3:%.*]], ptr @test11_foo, i32 0, i32 1), i32 -4), align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = icmp ult i64 0, [[TMP16]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP17]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds4: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 0) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB63:[0-9]+]], i64 0) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont5: +// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr getelementptr inbounds nuw ([[STRUCT_ANON_3]], ptr @test11_foo, i32 0, i32 1), i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = icmp uge i64 [[TMP18]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP19]], label [[CONT7:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.type_mismatch6: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB21:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB64:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw ([[STRUCT_ANON_3]], ptr @test11_foo, i32 0, i32 1) to i64)) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont7: +// SANITIZE-WITH-ATTR-NEXT: br label [[TRAP8:%.*]] +// SANITIZE-WITH-ATTR: 20: +// SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = load i32, ptr getelementptr inbounds nuw ([[STRUCT_ANON_3]], ptr @test11_foo, i32 0, i32 1), align 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP21]], ptr @test11_a, align 4 +// SANITIZE-WITH-ATTR-NEXT: br label [[FOR_COND]] +// SANITIZE-WITH-ATTR: trap: +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.trap() #[[ATTR5]] +// SANITIZE-WITH-ATTR-NEXT: unreachable +// SANITIZE-WITH-ATTR: trap8: +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.trap() #[[ATTR5]] +// SANITIZE-WITH-ATTR-NEXT: unreachable // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test12( -// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test11( +// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[BAZ:%.*]] = alloca [[STRUCT_HANG:%.*]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR11:[0-9]+]] -// NO-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_STRUCT7:![0-9]+]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP0]], ptr @test12_b, align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4), align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP1]], ptr @test12_a, align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[BAZ]], ptr align 4 @test11_bar, i64 24, i1 false) // NO-SANITIZE-WITH-ATTR-NEXT: br label [[FOR_COND:%.*]] // NO-SANITIZE-WITH-ATTR: for.cond: +// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw [[STRUCT_HANG]], ptr [[BAZ]], i32 0, i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP1]], ptr @test11_b, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: br label [[FOR_INC:%.*]] +// NO-SANITIZE-WITH-ATTR: for.inc: +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr getelementptr inbounds nuw ([[STRUCT_ANON_3:%.*]], ptr @test11_foo, i32 0, i32 1), align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP2]], ptr @test11_a, align 4 // NO-SANITIZE-WITH-ATTR-NEXT: br label [[FOR_COND]] // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i32 @test12( -// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test11( +// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 // 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.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-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[BAZ]], ptr align 4 @test11_bar, i64 24, i1 false) +// SANITIZE-WITHOUT-ATTR-NEXT: br label [[FOR_COND:%.*]] +// SANITIZE-WITHOUT-ATTR: for.cond: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw [[STRUCT_HANG]], ptr [[BAZ]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 6, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // 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: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB61:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITHOUT-ATTR: cont: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[TMP1]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP2]], ptr @test12_b, align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr @test12_foo, align 4 -// 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-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX_IDX:%.*]] = mul i64 [[IDXPROM]], 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = add i64 0, [[ARRAYIDX_IDX]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = icmp uge i64 [[TMP5]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP6]], label [[CONT1:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB62:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = sub i64 24, [[TMP4]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp ult i64 24, [[TMP4]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = icmp ult i64 [[TMP8]], 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = or i1 [[TMP9]], [[TMP10]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP11]], label [[TRAP:%.*]], label [[TMP12:%.*]] +// SANITIZE-WITHOUT-ATTR: 12: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP13]], ptr @test11_b, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: br label [[FOR_INC:%.*]] +// SANITIZE-WITHOUT-ATTR: for.inc: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP14:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr @test11_foo, i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP15:%.*]] = icmp uge i64 [[TMP14]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP15]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch2: +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB64:[0-9]+]], i64 ptrtoint (ptr @test11_foo to i64)) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr getelementptr inbounds nuw ([[STRUCT_ANON_3:%.*]], ptr @test11_foo, i32 0, i32 1), i32 -4), align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP16:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP17:%.*]] = icmp ult i64 0, [[TMP16]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP17]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // 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: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB66:[0-9]+]], i64 0) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont5: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP18:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr getelementptr inbounds nuw ([[STRUCT_ANON_3]], ptr @test11_foo, i32 0, i32 1), i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP19:%.*]] = icmp uge i64 [[TMP18]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP19]], label [[CONT7:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // 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 nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB67:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw ([[STRUCT_ANON_3]], ptr @test11_foo, i32 0, i32 1) to i64)) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont7: +// SANITIZE-WITHOUT-ATTR-NEXT: br label [[TRAP8:%.*]] +// SANITIZE-WITHOUT-ATTR: 20: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP21:%.*]] = load i32, ptr getelementptr inbounds nuw ([[STRUCT_ANON_3]], ptr @test11_foo, i32 0, i32 1), align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP21]], ptr @test11_a, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: br label [[FOR_COND]] +// SANITIZE-WITHOUT-ATTR: trap: +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.trap() #[[ATTR5]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable +// SANITIZE-WITHOUT-ATTR: trap8: +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.trap() #[[ATTR5]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i32 @test12( -// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test11( +// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i32, align 4 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BAZ:%.*]] = alloca [[STRUCT_HANG:%.*]], align 4 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR9:[0-9]+]] -// NO-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]+]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP0]], ptr @test12_b, align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4), align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP1]], ptr @test12_a, align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[BAZ]], ptr align 4 @test11_bar, i64 24, i1 false) // NO-SANITIZE-WITHOUT-ATTR-NEXT: br label [[FOR_COND:%.*]] // NO-SANITIZE-WITHOUT-ATTR: for.cond: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw [[STRUCT_HANG]], ptr [[BAZ]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP1]], ptr @test11_b, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: br label [[FOR_INC:%.*]] +// NO-SANITIZE-WITHOUT-ATTR: for.inc: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr getelementptr inbounds nuw ([[STRUCT_ANON_3:%.*]], ptr @test11_foo, i32 0, i32 1), align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP2]], ptr @test11_a, align 4 // NO-SANITIZE-WITHOUT-ATTR-NEXT: br label [[FOR_COND]] // -int test12(int index) { - struct hang baz = test12_bar; +int test11(int index) { + struct hang baz = test11_bar; - for (;; test12_a = (&test12_foo)->entries[0]) - test12_b = baz.entries[index]; + for (;; test11_a = (&test11_foo)->entries[0]) + test11_b = baz.entries[index]; - return test12_b; + return test11_b; } -struct test13_foo { - struct test13_bar *domain; -} test13_f; +struct test12_foo { + struct test12_bar *domain; +} test12_f; -struct test13_bar { - struct test13_bar *parent; +struct test12_bar { + struct test12_bar *parent; int revmap_size; - struct test13_foo *revmap[] __attribute__((__counted_by__(revmap_size))); + struct test12_foo *revmap[] __attribute__((__counted_by__(revmap_size))); }; -// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test13( -// SANITIZE-WITH-ATTR-SAME: i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test12( +// SANITIZE-WITH-ATTR-SAME: i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr @test13_f, align 8, !tbaa [[TBAA11:![0-9]+]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// SANITIZE-WITH-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr @test12_f, i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp uge i64 [[TMP0]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB66:[0-9]+]], i64 ptrtoint (ptr @test12_f to i64)) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr @test12_f, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB68:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont2: +// SANITIZE-WITH-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST12_BAR:%.*]], ptr [[TMP2]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[REVMAP]], i32 -8 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[INDEX]], [[TMP1]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp ult i64 [[TMP6]], [[TMP7]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP8]], 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 @[[GLOB24:[0-9]+]], i64 [[INDEX]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB71:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[TMP6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = icmp uge i64 [[TMP9]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP10]], label [[CONT5:%.*]], label [[HANDLER_TYPE_MISMATCH4:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch4: +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB73:[0-9]+]], i64 [[TMP11]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont5: -// SANITIZE-WITH-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]] -// SANITIZE-WITH-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA14:![0-9]+]] +// SANITIZE-WITH-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8 // SANITIZE-WITH-ATTR-NEXT: ret i32 0 // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test13( -// NO-SANITIZE-WITH-ATTR-SAME: i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test12( +// NO-SANITIZE-WITH-ATTR-SAME: i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr @test13_f, align 8, !tbaa [[TBAA8:![0-9]+]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]] -// NO-SANITIZE-WITH-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11:![0-9]+]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr @test12_f, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST12_BAR:%.*]], ptr [[TMP0]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[TMP1]] +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8 // NO-SANITIZE-WITH-ATTR-NEXT: ret i32 0 // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i32 @test13( -// SANITIZE-WITHOUT-ATTR-SAME: i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test12( +// SANITIZE-WITHOUT-ATTR-SAME: i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr @test13_f, align 8, !tbaa [[TBAA11:![0-9]+]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr @test12_f, i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = icmp uge i64 [[TMP0]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB69:[0-9]+]], i64 ptrtoint (ptr @test12_f to i64)) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr @test12_f, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP4]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB71:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST12_BAR:%.*]], ptr [[TMP2]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[REVMAP]], i32 -8 // SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[INDEX]], [[TMP1]], !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = icmp ult i64 [[TMP6]], [[TMP7]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP8]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // 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: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB74:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[TMP6]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = icmp uge i64 [[TMP9]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP10]], label [[CONT5:%.*]], label [[HANDLER_TYPE_MISMATCH4:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB76:[0-9]+]], i64 [[TMP11]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITHOUT-ATTR: cont5: -// SANITIZE-WITHOUT-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]] -// SANITIZE-WITHOUT-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA14:![0-9]+]] +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8 // SANITIZE-WITHOUT-ATTR-NEXT: ret i32 0 // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i32 @test13( -// NO-SANITIZE-WITHOUT-ATTR-SAME: i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test12( +// NO-SANITIZE-WITHOUT-ATTR-SAME: i64 noundef [[INDEX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr @test13_f, align 8, !tbaa [[TBAA8:![0-9]+]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11:![0-9]+]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[INDEX_ADDR:%.*]] = alloca i64, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i64 [[INDEX]], ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr @test12_f, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST12_BAR:%.*]], ptr [[TMP0]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i64, ptr [[INDEX_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[TMP1]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 0 // -int test13(long index) { - test13_f.domain->revmap[index] = 0; +int test12(long index) { + test12_f.domain->revmap[index] = 0; return 0; } -struct test14_foo { +struct test13_foo { int x, y; int blah[] __attribute__((counted_by(x))); }; -// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test14( -// SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test13( +// SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) #[[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-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOMPOUNDLITERAL:%.*]] = alloca [[STRUCT_TEST13_FOO:%.*]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 0 +// SANITIZE-WITH-ATTR-NEXT: store i32 1, ptr [[X]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: store i32 2, ptr [[Y]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[DOTCOMPOUNDLITERAL]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp uge i64 [[TMP0]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[DOTCOMPOUNDLITERAL]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB75:[0-9]+]], i64 [[TMP2]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP3]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[BLAH]], i32 -8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP4]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label [[CONT1:%.*]], 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 @[[GLOB25:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB77:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX_IDX:%.*]] = mul i64 [[IDXPROM]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = add i64 8, [[ARRAYIDX_IDX]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp uge i64 [[TMP7]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP8]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB78:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = sub i64 8, [[TMP6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp ult i64 8, [[TMP6]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = icmp ult i64 [[TMP10]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = or i1 [[TMP11]], [[TMP12]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP13]], label [[TRAP:%.*]], label [[TMP14:%.*]] +// SANITIZE-WITH-ATTR: 14: +// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP15]] // SANITIZE-WITH-ATTR: trap: -// SANITIZE-WITH-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR9]] +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.trap() #[[ATTR5]] // SANITIZE-WITH-ATTR-NEXT: unreachable // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test14( -// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test13( +// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTCOMPOUNDLITERAL:%.*]] = alloca [[STRUCT_TEST14_FOO:%.*]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 1, ptr [[DOTCOMPOUNDLITERAL]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTCOMPOUNDLITERAL]], i64 4 -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 2, ptr [[Y]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTCOMPOUNDLITERAL]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTCOMPOUNDLITERAL:%.*]] = alloca [[STRUCT_TEST13_FOO:%.*]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 1, ptr [[X]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 2, ptr [[Y]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP0]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP1]] // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test14( -// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test13( +// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) #[[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-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOMPOUNDLITERAL:%.*]] = alloca [[STRUCT_TEST13_FOO:%.*]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 1, ptr [[X]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 2, ptr [[Y]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[DOTCOMPOUNDLITERAL]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = icmp uge i64 [[TMP0]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[DOTCOMPOUNDLITERAL]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB78:[0-9]+]], i64 [[TMP2]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP3]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[BLAH]], i32 -8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP4]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP5]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // 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: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB80:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX_IDX:%.*]] = mul i64 [[IDXPROM]], 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = add i64 8, [[ARRAYIDX_IDX]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = icmp uge i64 [[TMP7]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP8]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB81:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = sub i64 8, [[TMP6]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = icmp ult i64 8, [[TMP6]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = icmp ult i64 [[TMP10]], 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP13:%.*]] = or i1 [[TMP11]], [[TMP12]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP13]], label [[TRAP:%.*]], label [[TMP14:%.*]] +// SANITIZE-WITHOUT-ATTR: 14: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP15]] // SANITIZE-WITHOUT-ATTR: trap: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR8]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.trap() #[[ATTR5]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test14( -// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test13( +// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOMPOUNDLITERAL:%.*]] = alloca [[STRUCT_TEST14_FOO:%.*]], align 4 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 1, ptr [[DOTCOMPOUNDLITERAL]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTCOMPOUNDLITERAL]], i64 4 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 2, ptr [[Y]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds nuw i8, ptr [[DOTCOMPOUNDLITERAL]], i64 8 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOMPOUNDLITERAL:%.*]] = alloca [[STRUCT_TEST13_FOO:%.*]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 1, ptr [[X]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 2, ptr [[Y]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST13_FOO]], ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i64 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP1]] // -int test14(int idx) { - return (struct test14_foo){ 1, 2 }.blah[idx]; +int test13(int idx) { + return (struct test13_foo){ 1, 2 }.blah[idx]; } -// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test15( -// SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test14( +// SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) #[[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-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: [[FOO:%.*]] = alloca [[STRUCT_ANON_6:%.*]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[FOO]], ptr align 4 @__const.test14.foo, i64 8, i1 false) +// SANITIZE-WITH-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_6]], ptr [[FOO]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[BLAH]], i32 -8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], 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 @[[GLOB27:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB80:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX_IDX:%.*]] = mul i64 [[IDXPROM]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = add i64 8, [[ARRAYIDX_IDX]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp uge i64 [[TMP4]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label [[CONT1:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB81:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = sub i64 8, [[TMP3]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp ult i64 8, [[TMP3]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp ult i64 [[TMP7]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP10]], label [[TRAP:%.*]], label [[TMP11:%.*]] +// SANITIZE-WITH-ATTR: 11: +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP12]] // SANITIZE-WITH-ATTR: trap: -// SANITIZE-WITH-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR9]] +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.trap() #[[ATTR5]] // SANITIZE-WITH-ATTR-NEXT: unreachable // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test15( -// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test14( +// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr getelementptr inbounds nuw (i8, ptr @__const.test15.foo, i64 8), i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP0]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[FOO:%.*]] = alloca [[STRUCT_ANON_6:%.*]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[FOO]], ptr align 4 @__const.test14.foo, i64 8, i1 false) +// NO-SANITIZE-WITH-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_6]], ptr [[FOO]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP1]] // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test15( -// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test14( +// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) #[[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-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[FOO:%.*]] = alloca [[STRUCT_ANON_6:%.*]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[FOO]], ptr align 4 @__const.test14.foo, i64 8, i1 false) +// SANITIZE-WITHOUT-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_6]], ptr [[FOO]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[BLAH]], i32 -8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // 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 @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB83:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX_IDX:%.*]] = mul i64 [[IDXPROM]], 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = add i64 8, [[ARRAYIDX_IDX]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = icmp uge i64 [[TMP4]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP5]], label [[CONT1:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB84:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = sub i64 8, [[TMP3]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = icmp ult i64 8, [[TMP3]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp ult i64 [[TMP7]], 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP10]], label [[TRAP:%.*]], label [[TMP11:%.*]] +// SANITIZE-WITHOUT-ATTR: 11: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP12]] // SANITIZE-WITHOUT-ATTR: trap: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR8]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.trap() #[[ATTR5]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test15( -// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test14( +// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr getelementptr inbounds nuw (i8, ptr @__const.test15.foo, i64 8), i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[FOO:%.*]] = alloca [[STRUCT_ANON_6:%.*]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[FOO]], ptr align 4 @__const.test14.foo, i64 8, i1 false) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BLAH:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_6]], ptr [[FOO]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP0]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[BLAH]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP1]] // -int test15(int idx) { +int test14(int idx) { struct { int x, y; int blah[] __attribute__((counted_by(x))); @@ -1293,127 +2908,185 @@ int test15(int idx) { return foo.blah[idx]; } -// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test19( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test15( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test19( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test15( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test19( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test15( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i64 42 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ADD_PTR]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[ADD_PTR]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB85:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[ADD_PTR]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP4]] // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test19( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test15( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 -// -size_t test19(struct annotated *p) { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP0]], i64 42 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[ADD_PTR]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 [[TMP1]] +// +size_t test15(struct annotated *p) { // Avoid pointer arithmetic. It could lead to security issues. return __builtin_dynamic_object_size(&(p + 42)->array[2], 1); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test20( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test16( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test20( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test16( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test20( -// SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test16( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test20( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test16( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // -size_t test20(struct annotated *p) { +size_t test16(struct annotated *p) { // Avoid side-effects. return __builtin_dynamic_object_size(&(++p)->array[2], 1); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test21( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test17( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test21( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test17( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test21( -// SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test17( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test21( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test17( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // -size_t test21(struct annotated *p) { +size_t test17(struct annotated *p) { // Avoid side-effects. return __builtin_dynamic_object_size(&(p++)->array[2], 1); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test22( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test18( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test22( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test18( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test22( -// SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test18( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test22( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test18( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // -size_t test22(struct annotated *p) { +size_t test18(struct annotated *p) { // Avoid side-effects. return __builtin_dynamic_object_size(&(--p)->array[2], 1); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test23( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test19( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test23( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test19( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test23( -// SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test19( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test23( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test19( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // -size_t test23(struct annotated *p) { +size_t test19(struct annotated *p) { // Avoid side-effects. return __builtin_dynamic_object_size(&(p--)->array[2], 1); } @@ -1423,158 +3096,369 @@ struct tests_foo { int arr[] __counted_by(count); }; -// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test24( -// SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test20( +// SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[VAR]], i64 40 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -// 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-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: [[VAR_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[VAR]], ptr [[VAR_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_TESTS_FOO:%.*]], ptr [[TMP0]], i64 10 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB83:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO]], ptr [[ARRAYIDX]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARR]], i32 -4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp ult i64 10, [[TMP4]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], 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 @[[GLOB28:[0-9]+]], i64 10) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB85:[0-9]+]], i64 10) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 10 +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp uge i64 [[TMP6]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP7]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch3: +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARRAYIDX2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB86:[0-9]+]], i64 [[TMP8]]) #[[ATTR5]], !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 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP1]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP9]] // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test24( -// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test20( +// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[VAR]], i64 84 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP0]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[VAR_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VAR]], ptr [[VAR_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_TESTS_FOO:%.*]], ptr [[TMP0]], i64 10 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO]], ptr [[ARRAYIDX]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 10 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP1]] // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test24( -// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test20( +// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[VAR]], i64 84 -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]] -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test24( -// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR6:[0-9]+]] { +// SANITIZE-WITHOUT-ATTR-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[VAR_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VAR]], ptr [[VAR_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_TESTS_FOO:%.*]], ptr [[TMP0]], i64 10 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB87:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO]], ptr [[ARRAYIDX]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 10 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX1]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = icmp uge i64 [[TMP4]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP5]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[ARRAYIDX1]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB88:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP7]] +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test20( +// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[VAR]], i64 84 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[VAR_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VAR]], ptr [[VAR_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_TESTS_FOO:%.*]], ptr [[TMP0]], i64 10 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO]], ptr [[ARRAYIDX]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 10 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP1]] // -int test24(int c, struct tests_foo *var) { +int test20(int c, struct tests_foo *var) { // Invalid: there can't be an array of flexible arrays. return var[10].arr[10]; } -// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test25( -// SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test21( +// SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4 -// 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-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: [[VAR_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[VAR]], ptr [[VAR_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB88:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP0]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp uge i64 [[TMP5]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB89:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont2: +// SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO:%.*]], ptr [[TMP4]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARR]], i32 -4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp ult i64 10, [[TMP8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP9]], 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 @[[GLOB29:[0-9]+]], i64 10) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB90:[0-9]+]], i64 10) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 10 +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT5:%.*]], label [[HANDLER_TYPE_MISMATCH4:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch4: +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB91:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !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 -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP13]] // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test25( -// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR8:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test21( +// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 44 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP1]] -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test25( -// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITH-ATTR-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[VAR_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VAR]], ptr [[VAR_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO:%.*]], ptr [[TMP1]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 10 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP2]] +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test21( +// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 44 -// 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 @test25( -// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { +// SANITIZE-WITHOUT-ATTR-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[VAR_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VAR]], ptr [[VAR_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB90:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP0]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP4]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = icmp uge i64 [[TMP5]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP6]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB91:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO:%.*]], ptr [[TMP4]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 10 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP9]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB92:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP11]] +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test21( +// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 44 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP1]] -// -int test25(int c, struct tests_foo **var) { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[VAR_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VAR]], ptr [[VAR_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO:%.*]], ptr [[TMP1]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 10 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP2]] +// +int test21(int c, struct tests_foo **var) { // Double dereferenced variable. return (**var).arr[10]; } // Outer struct -struct test26_foo { +struct test22_foo { int a; struct tests_foo s; }; -// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test26( -// SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[FOO:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test22( +// SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[FOO:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 4 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[C]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[S]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// 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-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: [[FOO_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[FOO]], ptr [[FOO_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FOO_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB93:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST22_FOO:%.*]], ptr [[TMP0]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[S]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp uge i64 [[TMP4]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[S]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB94:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont2: +// SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO:%.*]], ptr [[S]], i32 0, i32 1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = load i32, ptr [[C_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP7]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARR]], i32 -4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP9]], 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]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB95:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont5: -// SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 +// SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT5:%.*]], label [[HANDLER_TYPE_MISMATCH4:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch4: +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB96:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont5: +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP13]] // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test26( -// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[FOO:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test22( +// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[FOO:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[C]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[FOO_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[FOO]], ptr [[FOO_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FOO_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST22_FOO:%.*]], ptr [[TMP0]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO:%.*]], ptr [[S]], i32 0, i32 1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[C_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP0]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP2]] // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test26( -// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[FOO:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test22( +// SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[FOO:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[C]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[FOO_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[FOO]], ptr [[FOO_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FOO_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB94:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST22_FOO:%.*]], ptr [[TMP0]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[S]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = icmp uge i64 [[TMP4]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP5]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[S]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB95:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO:%.*]], ptr [[S]], i32 0, i32 1 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = load i32, ptr [[C_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP7]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]] -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test26( -// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[FOO:%.*]]) local_unnamed_addr #[[ATTR6]] { +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP9]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB96:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP11]] +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test22( +// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[FOO:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[C]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[FOO_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[FOO]], ptr [[FOO_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FOO_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST22_FOO:%.*]], ptr [[TMP0]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TESTS_FOO:%.*]], ptr [[S]], i32 0, i32 1 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[C_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP2]] // -int test26(int c, struct test26_foo *foo) { +int test22(int c, struct test22_foo *foo) { // Invalid: A structure with a flexible array must be a pointer. return foo->s.arr[c]; } -struct test27_baz; +struct test23_baz; -struct test27_bar { +struct test23_bar { unsigned char type; unsigned char flags; unsigned short use_cnt; unsigned char hw_priv; }; -struct test27_foo { - struct test27_baz *a; +struct test23_foo { + struct test23_baz *a; unsigned char bit1 : 1; unsigned char bit2 : 1; @@ -1582,130 +3466,362 @@ struct test27_foo { unsigned int n_tables; unsigned long missed; - struct test27_bar *entries[] __counted_by(n_tables); + struct test23_bar *entries[] __counted_by(n_tables); }; -// SANITIZE-WITH-ATTR-LABEL: define dso_local ptr @test27( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local ptr @test23( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: [[J_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[J]], ptr [[J_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 24, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB98:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST23_FOO:%.*]], ptr [[TMP0]], i32 0, i32 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ENTRIES]], i32 -12 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// 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-NEXT: [[TMP5:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], 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 @[[GLOB32:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB100:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont3: -// SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 24 +// SANITIZE-WITH-ATTR: cont1: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM4:%.*]] = sext i32 [[J]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [[STRUCT_TEST27_BAR:%.*]], ptr [[TMP2]], i64 [[IDXPROM4]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp uge i64 [[TMP7]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP8]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB102:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = load i32, ptr [[J_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM4:%.*]] = sext i32 [[TMP11]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [[STRUCT_TEST23_BAR:%.*]], ptr [[TMP10]], i64 [[IDXPROM4]] // SANITIZE-WITH-ATTR-NEXT: ret ptr [[ARRAYIDX5]] // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local ptr @test27( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local ptr @test23( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 24 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[J_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[J]], ptr [[J_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST23_FOO:%.*]], ptr [[TMP0]], i32 0, i32 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM1:%.*]] = sext i32 [[J]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [[STRUCT_TEST27_BAR:%.*]], ptr [[TMP0]], i64 [[IDXPROM1]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = load i32, ptr [[J_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM1:%.*]] = sext i32 [[TMP3]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [[STRUCT_TEST23_BAR:%.*]], ptr [[TMP2]], i64 [[IDXPROM1]] // NO-SANITIZE-WITH-ATTR-NEXT: ret ptr [[ARRAYIDX2]] // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local ptr @test27( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local ptr @test23( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 24 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[J_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[J]], ptr [[J_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 24, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB98:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST23_FOO:%.*]], ptr [[TMP0]], i32 0, i32 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM3:%.*]] = sext i32 [[J]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [[STRUCT_TEST27_BAR:%.*]], ptr [[TMP0]], i64 [[IDXPROM3]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = icmp uge i64 [[TMP5]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP6]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB100:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = load i32, ptr [[J_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM3:%.*]] = sext i32 [[TMP9]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [[STRUCT_TEST23_BAR:%.*]], ptr [[TMP8]], i64 [[IDXPROM3]] // SANITIZE-WITHOUT-ATTR-NEXT: ret ptr [[ARRAYIDX4]] // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local ptr @test27( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) local_unnamed_addr #[[ATTR6]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local ptr @test23( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 24 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[J_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[J]], ptr [[J_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST23_FOO:%.*]], ptr [[TMP0]], i32 0, i32 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[I_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM1:%.*]] = sext i32 [[J]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [[STRUCT_TEST27_BAR:%.*]], ptr [[TMP0]], i64 [[IDXPROM1]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load i32, ptr [[J_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM1:%.*]] = sext i32 [[TMP3]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [[STRUCT_TEST23_BAR:%.*]], ptr [[TMP2]], i64 [[IDXPROM1]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret ptr [[ARRAYIDX2]] // -struct test27_bar *test27(struct test27_foo *p, int i, int j) { +struct test23_bar *test23(struct test23_foo *p, int i, int j) { return &p->entries[i][j]; } -struct test28_foo { - struct test28_foo *s; +struct test24_foo { + struct test24_foo *s; int count; int arr[] __counted_by(count); }; -// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test28( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test24( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB104:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO:%.*]], ptr [[TMP0]], i32 0, i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[S]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp uge i64 [[TMP4]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[S]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB106:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = load ptr, ptr [[S]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP7]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP9]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch3: +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP7]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB107:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont4: +// SANITIZE-WITH-ATTR-NEXT: [[S5:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP7]], i32 0, i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[S5]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = icmp uge i64 [[TMP11]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP12]], label [[CONT7:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch6: +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = ptrtoint ptr [[S5]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB108:[0-9]+]], i64 [[TMP13]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont7: +// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = load ptr, ptr [[S5]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP14]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = icmp uge i64 [[TMP15]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP16]], label [[CONT9:%.*]], label [[HANDLER_TYPE_MISMATCH8:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch8: +// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = ptrtoint ptr [[TMP14]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB109:[0-9]+]], i64 [[TMP17]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont9: +// SANITIZE-WITH-ATTR-NEXT: [[S10:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP14]], i32 0, i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[S10]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = icmp uge i64 [[TMP18]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP19]], label [[CONT12:%.*]], label [[HANDLER_TYPE_MISMATCH11:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch11: +// SANITIZE-WITH-ATTR-NEXT: [[TMP20:%.*]] = ptrtoint ptr [[S10]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB110:[0-9]+]], i64 [[TMP20]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont12: +// SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = load ptr, ptr [[S10]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP22:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP21]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP23:%.*]] = icmp uge i64 [[TMP22]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP23]], label [[CONT14:%.*]], label [[HANDLER_TYPE_MISMATCH13:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch13: +// SANITIZE-WITH-ATTR-NEXT: [[TMP24:%.*]] = ptrtoint ptr [[TMP21]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB111:[0-9]+]], i64 [[TMP24]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont14: +// SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP21]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP25:%.*]] = load i32, ptr [[I_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP25]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARR]], i32 -4 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// 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-NEXT: [[TMP26:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP27:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP26]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP27]], label [[CONT15:%.*]], 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 @[[GLOB34:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB113:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont17: -// SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 +// SANITIZE-WITH-ATTR: cont15: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP5]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP28:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP29:%.*]] = icmp uge i64 [[TMP28]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP29]], label [[CONT17:%.*]], label [[HANDLER_TYPE_MISMATCH16:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch16: +// SANITIZE-WITH-ATTR-NEXT: [[TMP30:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB114:[0-9]+]], i64 [[TMP30]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont17: +// SANITIZE-WITH-ATTR-NEXT: [[TMP31:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP31]] // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test28( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR8]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test24( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO:%.*]], ptr [[TMP0]], i32 0, i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[S]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[S1:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP1]], i32 0, i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[S1]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[S2:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP2]], i32 0, i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = load ptr, ptr [[S2]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP3]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP3]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP5]] // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test28( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test24( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB102:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO:%.*]], ptr [[TMP0]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[S]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = icmp uge i64 [[TMP4]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP5]], label [[CONT2:%.*]], label [[HANDLER_TYPE_MISMATCH1:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[S]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB104:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = load ptr, ptr [[S]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP7]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP9]], label [[CONT4:%.*]], label [[HANDLER_TYPE_MISMATCH3:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[TMP7]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB105:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[S5:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP7]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[S5]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = icmp uge i64 [[TMP11]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP12]], label [[CONT7:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch6: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP13:%.*]] = ptrtoint ptr [[S5]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB106:[0-9]+]], i64 [[TMP13]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont7: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP14:%.*]] = load ptr, ptr [[S5]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP15:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP14]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP16:%.*]] = icmp uge i64 [[TMP15]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP16]], label [[CONT9:%.*]], label [[HANDLER_TYPE_MISMATCH8:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch8: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP17:%.*]] = ptrtoint ptr [[TMP14]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB107:[0-9]+]], i64 [[TMP17]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont9: +// SANITIZE-WITHOUT-ATTR-NEXT: [[S10:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP14]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP18:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[S10]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP19:%.*]] = icmp uge i64 [[TMP18]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP19]], label [[CONT12:%.*]], label [[HANDLER_TYPE_MISMATCH11:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch11: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP20:%.*]] = ptrtoint ptr [[S10]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB108:[0-9]+]], i64 [[TMP20]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont12: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP21:%.*]] = load ptr, ptr [[S10]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP22:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP21]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP23:%.*]] = icmp uge i64 [[TMP22]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP23]], label [[CONT14:%.*]], label [[HANDLER_TYPE_MISMATCH13:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch13: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP24:%.*]] = ptrtoint ptr [[TMP21]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB109:[0-9]+]], i64 [[TMP24]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont14: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP21]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP25:%.*]] = load i32, ptr [[I_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP25]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP3]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP26:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP27:%.*]] = icmp uge i64 [[TMP26]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP27]], label [[CONT16:%.*]], label [[HANDLER_TYPE_MISMATCH15:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch15: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP28:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB110:[0-9]+]], i64 [[TMP28]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont16: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP29:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP29]] // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test28( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR7]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test24( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[P]], ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO:%.*]], ptr [[TMP0]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[S]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[S1:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP1]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[S1]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[S2:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP2]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load ptr, ptr [[S2]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST24_FOO]], ptr [[TMP3]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[I_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP3]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP5]] // -int test28(struct test28_foo *p, int i) { +int test24(struct test24_foo *p, int i) { return p->s->s->s->arr[i]; } @@ -1716,162 +3832,484 @@ struct annotated_struct_array { int array[] __counted_by(count); }; -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test29( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test25( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[IDX1]], 10 -// 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-NEXT: [[ANN_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[IDX1_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDX2_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[ANN]], ptr [[ANN_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX1]], ptr [[IDX1_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX2]], ptr [[IDX2_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ANN_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 96, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB116:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[ANN_ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED_STRUCT_ARRAY:%.*]], ptr [[TMP0]], i32 0, i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[IDX1_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = sext i32 [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp ult i64 [[TMP5]], 10, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], 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 @[[GLOB36:[0-9]+]], i64 [[TMP1]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB118:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN_ARRAY]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP9]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB120:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !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]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP11]], i32 0, i32 1 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM15:%.*]] = sext i32 [[IDX2]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// 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-NEXT: [[TMP12:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = mul nsw i64 [[TMP12]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = icmp sgt i64 [[TMP12]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = select i1 [[TMP14]], i64 [[TMP13]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP15]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = load ptr, ptr [[ANN_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP16]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = icmp uge i64 [[TMP17]], 96, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP18]], label [[CONT5:%.*]], label [[HANDLER_TYPE_MISMATCH4:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch4: +// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = ptrtoint ptr [[TMP16]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB121:[0-9]+]], i64 [[TMP19]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont5: +// SANITIZE-WITH-ATTR-NEXT: [[ANN_ARRAY6:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED_STRUCT_ARRAY]], ptr [[TMP16]], i32 0, i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[TMP20:%.*]] = load i32, ptr [[IDX1_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = sext i32 [[TMP20]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP22:%.*]] = icmp ult i64 [[TMP21]], 10, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP22]], label [[CONT8:%.*]], label [[HANDLER_OUT_OF_BOUNDS7:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds7: +// SANITIZE-WITH-ATTR-NEXT: [[TMP23:%.*]] = zext i32 [[TMP20]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB122:[0-9]+]], i64 [[TMP23]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont8: +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM9:%.*]] = sext i32 [[TMP20]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN_ARRAY6]], i64 0, i64 [[IDXPROM9]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP24:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX10]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP25:%.*]] = icmp uge i64 [[TMP24]], 8, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP25]], label [[CONT12:%.*]], label [[HANDLER_TYPE_MISMATCH11:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch11: +// SANITIZE-WITH-ATTR-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[ARRAYIDX10]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB123:[0-9]+]], i64 [[TMP26]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont12: +// SANITIZE-WITH-ATTR-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX10]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP28:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP27]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP29:%.*]] = icmp uge i64 [[TMP28]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP29]], label [[CONT14:%.*]], label [[HANDLER_TYPE_MISMATCH13:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch13: +// SANITIZE-WITH-ATTR-NEXT: [[TMP30:%.*]] = ptrtoint ptr [[TMP27]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB124:[0-9]+]], i64 [[TMP30]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont14: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP27]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP31:%.*]] = load i32, ptr [[IDX2_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP31]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i32 -4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP32:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP33:%.*]] = icmp ult i64 [[IDXPROM15]], [[TMP32]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP33]], label [[CONT17:%.*]], 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 @[[GLOB37:[0-9]+]], i64 [[IDXPROM15]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB125:[0-9]+]], i64 [[IDXPROM15]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont20: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 +// SANITIZE-WITH-ATTR: cont17: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM15]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP5]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX18]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP34:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX18]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP35:%.*]] = icmp uge i64 [[TMP34]], 4, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP35]], label [[CONT20:%.*]], label [[HANDLER_TYPE_MISMATCH19:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch19: +// SANITIZE-WITH-ATTR-NEXT: [[TMP36:%.*]] = ptrtoint ptr [[ARRAYIDX18]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB126:[0-9]+]], i64 [[TMP36]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont20: +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX18]], align 4 // SANITIZE-WITH-ATTR-NEXT: ret void // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test29( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR9:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test25( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX1]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ANN_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDX1_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDX2_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[ANN]], ptr [[ANN_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX1]], ptr [[IDX1_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX2]], ptr [[IDX2_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ANN_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ANN_ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED_STRUCT_ARRAY:%.*]], ptr [[TMP0]], i32 0, i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX1_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN_ARRAY]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_ANNOTATED:%.*]], ptr [[TMP2]], i32 0, i32 1 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP1]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM4:%.*]] = sext i32 [[IDX2]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = mul nsw i64 [[TMP3]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i64 [[TMP3]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = select i1 [[TMP5]], i64 [[TMP4]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP6]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = load ptr, ptr [[ANN_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ANN_ARRAY1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED_STRUCT_ARRAY]], ptr [[TMP7]], i32 0, i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = load i32, ptr [[IDX1_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM2:%.*]] = sext i32 [[TMP8]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN_ARRAY1]], i64 0, i64 [[IDXPROM2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP9]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = load i32, ptr [[IDX2_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM4:%.*]] = sext i32 [[TMP10]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM4]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX5]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX5]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test29( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test25( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[IDX1]], 10 -// 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-NEXT: [[ANN_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDX1_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDX2_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[ANN]], ptr [[ANN_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX1]], ptr [[IDX1_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX2]], ptr [[IDX2_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ANN_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 96, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB112:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ANN_ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED_STRUCT_ARRAY:%.*]], ptr [[TMP0]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = load i32, ptr [[IDX1_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = sext i32 [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = icmp ult i64 [[TMP5]], 10, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP6]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[TMP4]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB114:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN_ARRAY]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = icmp uge i64 [[TMP8]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP9]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB116:[0-9]+]], i64 [[TMP10]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont3: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP11]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP13:%.*]] = icmp uge i64 [[TMP12]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP13]], label [[CONT5:%.*]], label [[HANDLER_TYPE_MISMATCH4:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch4: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP14:%.*]] = ptrtoint ptr [[TMP11]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB117:[0-9]+]], i64 [[TMP14]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont5: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP11]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP15:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP15]] to i32 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP16:%.*]] = load ptr, ptr [[ANN_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP17:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP16]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP18:%.*]] = icmp uge i64 [[TMP17]], 96, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP18]], label [[CONT7:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch6: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP19:%.*]] = ptrtoint ptr [[TMP16]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB118:[0-9]+]], i64 [[TMP19]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont7: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ANN_ARRAY8:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED_STRUCT_ARRAY]], ptr [[TMP16]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP20:%.*]] = load i32, ptr [[IDX1_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP21:%.*]] = sext i32 [[TMP20]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP22:%.*]] = icmp ult i64 [[TMP21]], 10, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP22]], label [[CONT10:%.*]], label [[HANDLER_OUT_OF_BOUNDS9:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.out_of_bounds9: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP23:%.*]] = zext i32 [[TMP20]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB119:[0-9]+]], i64 [[TMP23]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont10: +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM11:%.*]] = sext i32 [[TMP20]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN_ARRAY8]], i64 0, i64 [[IDXPROM11]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP24:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX12]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP25:%.*]] = icmp uge i64 [[TMP24]], 8, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP25]], label [[CONT14:%.*]], label [[HANDLER_TYPE_MISMATCH13:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch13: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[ARRAYIDX12]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB120:[0-9]+]], i64 [[TMP26]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont14: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP27:%.*]] = load ptr, ptr [[ARRAYIDX12]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP28:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP27]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP29:%.*]] = icmp uge i64 [[TMP28]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP29]], label [[CONT16:%.*]], label [[HANDLER_TYPE_MISMATCH15:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch15: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP30:%.*]] = ptrtoint ptr [[TMP27]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB121:[0-9]+]], i64 [[TMP30]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont16: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY17:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP27]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP31:%.*]] = load i32, ptr [[IDX2_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP31]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY17]], i64 0, i64 [[IDXPROM18]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP32:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX19]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP33:%.*]] = icmp uge i64 [[TMP32]], 4, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP33]], label [[CONT21:%.*]], label [[HANDLER_TYPE_MISMATCH20:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch20: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP34:%.*]] = ptrtoint ptr [[ARRAYIDX19]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB122:[0-9]+]], i64 [[TMP34]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITHOUT-ATTR: cont21: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[TMP1]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA14]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 -// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM18:%.*]] = sext i32 [[IDX2]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM18]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX19]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX19]], align 4 // SANITIZE-WITHOUT-ATTR-NEXT: ret void // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test29( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readonly [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR8:[0-9]+]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test25( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX1]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM5:%.*]] = sext i32 [[IDX2]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM5]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX6]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ANN_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDX1_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDX2_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[ANN]], ptr [[ANN_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX1]], ptr [[IDX1_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX2]], ptr [[IDX2_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ANN_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ANN_ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED_STRUCT_ARRAY:%.*]], ptr [[TMP0]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[IDX1_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN_ARRAY]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED:%.*]], ptr [[TMP2]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYDECAY]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP3]] to i32 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ANN_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ANN_ARRAY1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED_STRUCT_ARRAY]], ptr [[TMP4]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[IDX1_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM2:%.*]] = sext i32 [[TMP5]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN_ARRAY1]], i64 0, i64 [[IDXPROM2]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX3]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY4:%.*]] = getelementptr inbounds nuw [[STRUCT_ANNOTATED]], ptr [[TMP6]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = load i32, ptr [[IDX2_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM5:%.*]] = sext i32 [[TMP7]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY4]], i64 0, i64 [[IDXPROM5]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX6]], align 4 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // -void test29(struct annotated_struct_array *ann, int idx1, int idx2) { +void test25(struct annotated_struct_array *ann, int idx1, int idx2) { ann->ann_array[idx1]->array[idx2] = __builtin_dynamic_object_size(ann->ann_array[idx1]->array, 1); } typedef struct { char __padding[0]; -} test30_spinlock_t; +} test26_spinlock_t; -struct test30_struct { - struct test30_decl *name_node; +struct test26_struct { + struct test26_decl *name_node; int priv_len; - test30_spinlock_t pcpu_refcnt; + test26_spinlock_t pcpu_refcnt; char priv[] __counted_by(priv_len); }; -// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR4]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test26( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[IDX]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB39:[0-9]+]], i64 [[TMP0]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch: +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB128:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont: +// SANITIZE-WITH-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST26_STRUCT:%.*]], ptr [[TMP2]], i32 0, i32 2 +// SANITIZE-WITH-ATTR-NEXT: [[__PADDING:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST26_SPINLOCK_T:%.*]], ptr [[PCPU_REFCNT]], i32 0, i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = sext i32 [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp ult i64 [[TMP7]], 0, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP8]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds: +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = zext i32 [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB130:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[__PADDING]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 1, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.type_mismatch2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB132:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 +// SANITIZE-WITH-ATTR-NEXT: ret void // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30( -// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test26( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[PCPU_REFCNT]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST26_STRUCT:%.*]], ptr [[TMP2]], i32 0, i32 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[__PADDING:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST26_SPINLOCK_T:%.*]], ptr [[PCPU_REFCNT]], i32 0, i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP3]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[__PADDING]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // NO-SANITIZE-WITH-ATTR-NEXT: ret void // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test30( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test26( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[IDX]] to i64, !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP0]]) #[[ATTR8]], !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP2]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP4:%.*]] = icmp uge i64 [[TMP3]], 16, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB124:[0-9]+]], i64 [[TMP5]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont: +// SANITIZE-WITHOUT-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST26_STRUCT:%.*]], ptr [[TMP2]], i32 0, i32 2 +// SANITIZE-WITHOUT-ATTR-NEXT: [[__PADDING:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST26_SPINLOCK_T:%.*]], ptr [[PCPU_REFCNT]], i32 0, i32 0 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP6:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP7:%.*]] = sext i32 [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP8:%.*]] = icmp ult i64 [[TMP7]], 0, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP8]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP9:%.*]] = zext i32 [[TMP6]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_out_of_bounds_abort(ptr @[[GLOB126:[0-9]+]], i64 [[TMP9]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[__PADDING]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP10:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[ARRAYIDX]], i1 false, i1 false, i1 false), !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP11:%.*]] = icmp uge i64 [[TMP10]], 1, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP11]], label [[CONT3:%.*]], label [[HANDLER_TYPE_MISMATCH2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: handler.type_mismatch2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB128:[0-9]+]], i64 [[TMP12]]) #[[ATTR5]], !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITHOUT-ATTR: cont3: +// SANITIZE-WITHOUT-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 +// SANITIZE-WITHOUT-ATTR-NEXT: ret void // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test30( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test26( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 12 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[PCPU_REFCNT]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST26_STRUCT:%.*]], ptr [[TMP2]], i32 0, i32 2 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[__PADDING:%.*]] = getelementptr inbounds nuw [[STRUCT_TEST26_SPINLOCK_T:%.*]], ptr [[PCPU_REFCNT]], i32 0, i32 0 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = load i32, ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP3]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[__PADDING]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1 // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // -void test30(struct test30_struct *ptr, int idx) { +void test26(struct test26_struct *ptr, int idx) { ptr->pcpu_refcnt.__padding[idx] = __builtin_dynamic_object_size(ptr, 1); } -struct test31_empty {}; +struct test27_empty {}; -struct test31_struct { - struct test31_empty y; +struct test27_struct { + struct test27_empty y; int s; int x[] __counted_by(s); }; -// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test31( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test27( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: ret i32 -1 -// -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test31( -// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITH-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITH-ATTR-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[CONV]] +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test27( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 -1 -// -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test31( -// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[CONV]] +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test27( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 -1 -// -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test31( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// SANITIZE-WITHOUT-ATTR-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[CONV]] +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test27( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 -1 -// -int test31(struct test31_struct *ptr, int idx) { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDX_ADDR:%.*]] = alloca i32, align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 true) +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[CONV]] +// +int test27(struct test27_struct *ptr, int idx) { return __builtin_dynamic_object_size(ptr, 0); } diff --git a/clang/test/CodeGen/builtin-counted-by-ref.c b/clang/test/CodeGen/builtin-counted-by-ref.c new file mode 100644 index 00000000000000..8ad715879aa767 --- /dev/null +++ b/clang/test/CodeGen/builtin-counted-by-ref.c @@ -0,0 +1,177 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=X86_64 +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=I386 + +struct a { + char x; + short count; + int array[] __attribute__((counted_by(count))); +}; + +// X86_64-LABEL: define dso_local ptr @test1( +// X86_64-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0:[0-9]+]] { +// X86_64-NEXT: [[ENTRY:.*:]] +// X86_64-NEXT: [[SIZE_ADDR:%.*]] = alloca i32, align 4 +// X86_64-NEXT: [[P:%.*]] = alloca ptr, align 8 +// X86_64-NEXT: store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4 +// X86_64-NEXT: [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// X86_64-NEXT: [[CONV:%.*]] = sext i32 [[TMP0]] to i64 +// X86_64-NEXT: [[MUL:%.*]] = mul i64 4, [[CONV]] +// X86_64-NEXT: [[ADD:%.*]] = add i64 4, [[MUL]] +// X86_64-NEXT: [[CALL:%.*]] = call ptr @malloc(i64 noundef [[ADD]]) #[[ATTR2:[0-9]+]] +// X86_64-NEXT: store ptr [[CALL]], ptr [[P]], align 8 +// X86_64-NEXT: [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// X86_64-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP1]] to i16 +// X86_64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P]], align 8 +// X86_64-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[TMP2]], i32 0, i32 1 +// X86_64-NEXT: store i16 [[CONV1]], ptr [[DOT_COUNTED_BY_GEP]], align 2 +// X86_64-NEXT: [[TMP3:%.*]] = load ptr, ptr [[P]], align 8 +// X86_64-NEXT: ret ptr [[TMP3]] +// +// I386-LABEL: define dso_local ptr @test1( +// I386-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0:[0-9]+]] { +// I386-NEXT: [[ENTRY:.*:]] +// I386-NEXT: [[SIZE_ADDR:%.*]] = alloca i32, align 4 +// I386-NEXT: [[P:%.*]] = alloca ptr, align 4 +// I386-NEXT: store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4 +// I386-NEXT: [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// I386-NEXT: [[MUL:%.*]] = mul i32 4, [[TMP0]] +// I386-NEXT: [[ADD:%.*]] = add i32 4, [[MUL]] +// I386-NEXT: [[CALL:%.*]] = call ptr @malloc(i32 noundef [[ADD]]) #[[ATTR2:[0-9]+]] +// I386-NEXT: store ptr [[CALL]], ptr [[P]], align 4 +// I386-NEXT: [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// I386-NEXT: [[CONV:%.*]] = trunc i32 [[TMP1]] to i16 +// I386-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P]], align 4 +// I386-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[TMP2]], i32 0, i32 1 +// I386-NEXT: store i16 [[CONV]], ptr [[DOT_COUNTED_BY_GEP]], align 2 +// I386-NEXT: [[TMP3:%.*]] = load ptr, ptr [[P]], align 4 +// I386-NEXT: ret ptr [[TMP3]] +// +struct a *test1(int size) { + struct a *p = __builtin_malloc(sizeof(struct a) + sizeof(int) * size); + + *__builtin_counted_by_ref(p->array) = size; + return p; +} + +struct b { + int _filler; + struct { + int __filler; + struct { + int ___filler; + struct { + char count; + }; + }; + }; + struct { + int filler_; + struct { + int filler__; + struct { + long array[] __attribute__((counted_by(count))); + }; + }; + }; +}; + +// X86_64-LABEL: define dso_local ptr @test2( +// X86_64-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0]] { +// X86_64-NEXT: [[ENTRY:.*:]] +// X86_64-NEXT: [[SIZE_ADDR:%.*]] = alloca i32, align 4 +// X86_64-NEXT: [[P:%.*]] = alloca ptr, align 8 +// X86_64-NEXT: store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4 +// X86_64-NEXT: [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// X86_64-NEXT: [[CONV:%.*]] = sext i32 [[TMP0]] to i64 +// X86_64-NEXT: [[MUL:%.*]] = mul i64 4, [[CONV]] +// X86_64-NEXT: [[ADD:%.*]] = add i64 4, [[MUL]] +// X86_64-NEXT: [[CALL:%.*]] = call ptr @malloc(i64 noundef [[ADD]]) #[[ATTR2]] +// X86_64-NEXT: store ptr [[CALL]], ptr [[P]], align 8 +// X86_64-NEXT: [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// X86_64-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP1]] to i8 +// X86_64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P]], align 8 +// X86_64-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_B:%.*]], ptr [[TMP2]], i32 0, i32 1, i32 1, i32 1, i32 0 +// X86_64-NEXT: store i8 [[CONV1]], ptr [[DOT_COUNTED_BY_GEP]], align 1 +// X86_64-NEXT: [[TMP3:%.*]] = load ptr, ptr [[P]], align 8 +// X86_64-NEXT: ret ptr [[TMP3]] +// +// I386-LABEL: define dso_local ptr @test2( +// I386-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0]] { +// I386-NEXT: [[ENTRY:.*:]] +// I386-NEXT: [[SIZE_ADDR:%.*]] = alloca i32, align 4 +// I386-NEXT: [[P:%.*]] = alloca ptr, align 4 +// I386-NEXT: store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4 +// I386-NEXT: [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// I386-NEXT: [[MUL:%.*]] = mul i32 4, [[TMP0]] +// I386-NEXT: [[ADD:%.*]] = add i32 4, [[MUL]] +// I386-NEXT: [[CALL:%.*]] = call ptr @malloc(i32 noundef [[ADD]]) #[[ATTR2]] +// I386-NEXT: store ptr [[CALL]], ptr [[P]], align 4 +// I386-NEXT: [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// I386-NEXT: [[CONV:%.*]] = trunc i32 [[TMP1]] to i8 +// I386-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P]], align 4 +// I386-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_B:%.*]], ptr [[TMP2]], i32 0, i32 1, i32 1, i32 1, i32 0 +// I386-NEXT: store i8 [[CONV]], ptr [[DOT_COUNTED_BY_GEP]], align 1 +// I386-NEXT: [[TMP3:%.*]] = load ptr, ptr [[P]], align 4 +// I386-NEXT: ret ptr [[TMP3]] +// +struct b *test2(int size) { + struct b *p = __builtin_malloc(sizeof(struct a) + sizeof(int) * size); + + *__builtin_counted_by_ref(p->array) = size; + return p; +} + +struct c { + char x; + short count; + int array[]; +}; + +// X86_64-LABEL: define dso_local ptr @test3( +// X86_64-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0]] { +// X86_64-NEXT: [[ENTRY:.*:]] +// X86_64-NEXT: [[SIZE_ADDR:%.*]] = alloca i32, align 4 +// X86_64-NEXT: [[P:%.*]] = alloca ptr, align 8 +// X86_64-NEXT: [[__IGNORED:%.*]] = alloca i64, align 8 +// X86_64-NEXT: store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4 +// X86_64-NEXT: [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// X86_64-NEXT: [[CONV:%.*]] = sext i32 [[TMP0]] to i64 +// X86_64-NEXT: [[MUL:%.*]] = mul i64 4, [[CONV]] +// X86_64-NEXT: [[ADD:%.*]] = add i64 4, [[MUL]] +// X86_64-NEXT: [[CALL:%.*]] = call ptr @malloc(i64 noundef [[ADD]]) #[[ATTR2]] +// X86_64-NEXT: store ptr [[CALL]], ptr [[P]], align 8 +// X86_64-NEXT: [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// X86_64-NEXT: [[CONV1:%.*]] = sext i32 [[TMP1]] to i64 +// X86_64-NEXT: store i64 [[CONV1]], ptr [[__IGNORED]], align 8 +// X86_64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P]], align 8 +// X86_64-NEXT: ret ptr [[TMP2]] +// +// I386-LABEL: define dso_local ptr @test3( +// I386-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0]] { +// I386-NEXT: [[ENTRY:.*:]] +// I386-NEXT: [[SIZE_ADDR:%.*]] = alloca i32, align 4 +// I386-NEXT: [[P:%.*]] = alloca ptr, align 4 +// I386-NEXT: [[__IGNORED:%.*]] = alloca i32, align 4 +// I386-NEXT: store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4 +// I386-NEXT: [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// I386-NEXT: [[MUL:%.*]] = mul i32 4, [[TMP0]] +// I386-NEXT: [[ADD:%.*]] = add i32 4, [[MUL]] +// I386-NEXT: [[CALL:%.*]] = call ptr @malloc(i32 noundef [[ADD]]) #[[ATTR2]] +// I386-NEXT: store ptr [[CALL]], ptr [[P]], align 4 +// I386-NEXT: [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4 +// I386-NEXT: store i32 [[TMP1]], ptr [[__IGNORED]], align 4 +// I386-NEXT: [[TMP2:%.*]] = load ptr, ptr [[P]], align 4 +// I386-NEXT: ret ptr [[TMP2]] +// +struct c *test3(int size) { + struct c *p = __builtin_malloc(sizeof(struct c) + sizeof(int) * size); + unsigned long int __ignored; + + *_Generic( + __builtin_counted_by_ref(p->array), + void *: &__ignored, + default: __builtin_counted_by_ref(p->array)) = size; + + return p; +} diff --git a/clang/test/Sema/builtin-counted-by-ref.c b/clang/test/Sema/builtin-counted-by-ref.c new file mode 100644 index 00000000000000..4e3875b902acc8 --- /dev/null +++ b/clang/test/Sema/builtin-counted-by-ref.c @@ -0,0 +1,122 @@ +// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify %s + +typedef unsigned long int size_t; + +int global_array[42]; +int global_int; + +struct fam_struct { + int x; + char count; + int array[] __attribute__((counted_by(count))); +}; + +void test1(struct fam_struct *ptr, int size, int idx) { + size_t size_of = sizeof(__builtin_counted_by_ref(ptr->array)); // ok + + *__builtin_counted_by_ref(ptr->array) = size; // ok + + { + size_t __ignored_assignment; + *_Generic(__builtin_counted_by_ref(ptr->array), + void *: &__ignored_assignment, + default: __builtin_counted_by_ref(ptr->array)) = 42; // ok + } +} + +void test2(struct fam_struct *ptr, int idx) { + __builtin_counted_by_ref(); // expected-error {{too few arguments to function call, expected 1, have 0}} + __builtin_counted_by_ref(ptr->array, ptr->x, ptr->count); // expected-error {{too many arguments to function call, expected 1, have 3}} +} + +void test3(struct fam_struct *ptr, int idx) { + __builtin_counted_by_ref(&ptr->array[idx]); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} + __builtin_counted_by_ref(&ptr->array); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} + __builtin_counted_by_ref(ptr->x); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} + __builtin_counted_by_ref(&ptr->x); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} + __builtin_counted_by_ref(global_array); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} + __builtin_counted_by_ref(global_int); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} + __builtin_counted_by_ref(&global_int); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} +} + +void test4(struct fam_struct *ptr, int idx) { + __builtin_counted_by_ref(ptr++->array); // expected-error {{'__builtin_counted_by_ref' argument cannot have side-effects}} + __builtin_counted_by_ref(&ptr->array[idx++]); // expected-error {{'__builtin_counted_by_ref' argument cannot have side-effects}} +} + +void foo(char *); + +void *test5(struct fam_struct *ptr, int size, int idx) { + char *ref = __builtin_counted_by_ref(ptr->array); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}} + + ref = __builtin_counted_by_ref(ptr->array); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}} + ref = (char *)(int *)(42 + &*__builtin_counted_by_ref(ptr->array)); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}} + foo(__builtin_counted_by_ref(ptr->array)); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}} + foo(ref = __builtin_counted_by_ref(ptr->array)); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}} + + if ((ref = __builtin_counted_by_ref(ptr->array))) // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}} + ; + + for (char *p = __builtin_counted_by_ref(ptr->array); p && *p; ++p) // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}} + ; + + return __builtin_counted_by_ref(ptr->array); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}} +} + +void test6(struct fam_struct *ptr, int size, int idx) { + *(__builtin_counted_by_ref(ptr->array) + 4) = 37; // expected-error {{value returned by '__builtin_counted_by_ref' cannot be used in a binary expression}} + __builtin_counted_by_ref(ptr->array)[3] = 37; // expected-error {{value returned by '__builtin_counted_by_ref' cannot be used in an array subscript expression}} +} + +struct non_fam_struct { + char x; + long *pointer; + int array[42]; + short count; +}; + +void *test7(struct non_fam_struct *ptr, int size) { + *__builtin_counted_by_ref(ptr->array) = size // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} + *__builtin_counted_by_ref(&ptr->array[0]) = size; // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} + *__builtin_counted_by_ref(ptr->pointer) = size; // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} + *__builtin_counted_by_ref(&ptr->pointer[0]) = size; // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}} +} + +struct char_count { + char count; + int array[] __attribute__((counted_by(count))); +} *cp; + +struct short_count { + short count; + int array[] __attribute__((counted_by(count))); +} *sp; + +struct int_count { + int count; + int array[] __attribute__((counted_by(count))); +} *ip; + +struct unsigned_count { + unsigned count; + int array[] __attribute__((counted_by(count))); +} *up; + +struct long_count { + long count; + int array[] __attribute__((counted_by(count))); +} *lp; + +struct unsigned_long_count { + unsigned long count; + int array[] __attribute__((counted_by(count))); +} *ulp; + +void test8(void) { + _Static_assert(_Generic(__builtin_counted_by_ref(cp->array), char * : 1, default : 0) == 1, "wrong return type"); + _Static_assert(_Generic(__builtin_counted_by_ref(sp->array), short * : 1, default : 0) == 1, "wrong return type"); + _Static_assert(_Generic(__builtin_counted_by_ref(ip->array), int * : 1, default : 0) == 1, "wrong return type"); + _Static_assert(_Generic(__builtin_counted_by_ref(up->array), unsigned int * : 1, default : 0) == 1, "wrong return type"); + _Static_assert(_Generic(__builtin_counted_by_ref(lp->array), long * : 1, default : 0) == 1, "wrong return type"); + _Static_assert(_Generic(__builtin_counted_by_ref(ulp->array), unsigned long * : 1, default : 0) == 1, "wrong return type"); +} diff --git a/clang/test/Sema/builtin-counted-by-ref.cpp b/clang/test/Sema/builtin-counted-by-ref.cpp new file mode 100644 index 00000000000000..b9ec9c908dcaa6 --- /dev/null +++ b/clang/test/Sema/builtin-counted-by-ref.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify %s + +struct fam_struct { + int x; + char count; + int array[] __attribute__((counted_by(count))); // expected-warning {{'counted_by' attribute ignored}} +}; +