[llvm-branch-commits] [clang] [Clang][counted_by] Don't re-evaluate the base of a counted_by pointer access for -fsanitize=array-bounds (PR #232228)
Bill Wendling via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Oct 15 01:46:41 PDT 2026
https://github.com/isanbard updated https://github.com/llvm/llvm-project/pull/232228
>From e45e8f0dd82f011a81f638e835f4c43d66356d4d Mon Sep 17 00:00:00 2001
From: Bill Wendling <isanbard at gmail.com>
Date: Wed, 14 Oct 2026 12:01:54 -0700
Subject: [PATCH] [Clang][counted_by] Don't re-evaluate the base of a
counted_by pointer access for -fsanitize=array-bounds
When indexing a 'counted_by' pointer field with -fsanitize=array-bounds,
EmitCountedByBoundsChecking was handed an invalid address and re-emitted
the field's l-value to locate the count. That re-evaluated the struct
base, duplicating its side-effects:
struct p { int count; int *buf __counted_by(count); };
struct p *q;
int f(int i) { return q++->buf[i]; } // 'q' incremented twice
int g(int i) { return get()->buf[i]; } // 'get' called twice
i.e. enabling the sanitizer changed the program's behavior.
When the subscript base is exactly the field load, emit the field's
l-value once, load the pointer from it (as the default case of
EmitPointerWithAlignment does, through EmitLoadOfLValue so that a
'__ptrauth'-qualified field is still authenticated), and pass the
field's address to the bounds check. When there's an intervening cast (e.g.
'((char *)p->buf)[i]') the base can't be shared, so the field's l-value
is still re-emitted, which only recomputes its address and so is safe
unless the struct base has side-effects. In that case the check is now
skipped instead of evaluating the base twice.
Assisted-by: Claude Opus 5.5
---
clang/lib/CodeGen/CGExpr.cpp | 63 +++++--
.../test/CodeGen/attr-counted-by-base-exprs.c | 162 +++++++++++++++---
.../CodeGen/attr-counted-by-for-pointers.c | 12 +-
.../attr-counted-by-or-null-for-pointers.c | 12 +-
clang/test/CodeGen/attr-counted-by-ptrauth.c | 24 +++
.../test/CodeGen/attr-sized-by-for-pointers.c | 24 +--
.../attr-sized-by-or-null-for-pointers.c | 24 +--
7 files changed, 246 insertions(+), 75 deletions(-)
create mode 100644 clang/test/CodeGen/attr-counted-by-ptrauth.c
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 927652c4609224..9cfcfc0aa68aaa 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5379,9 +5379,46 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
getContext().getTypeSizeInChars(E->getType()).getQuantity();
}
} else {
- // The base must be a pointer; emit it with an estimate of its alignment.
- Address BaseAddr =
- EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
+ // Find the load of a 'counted_by' pointer field (e.g. 'p->buf' in
+ // 'p->buf[i]') whose count bounds this access.
+ const CastExpr *CountedByLoad = nullptr;
+ const MemberExpr *CountedByME = nullptr;
+ if (SanOpts.has(SanitizerKind::ArrayBounds)) {
+ StructFieldAccess Visitor;
+ if (const auto *CE =
+ dyn_cast_if_present<CastExpr>(Visitor.Visit(E->getBase()));
+ CE && CE->getCastKind() == CK_LValueToRValue) {
+ const auto *ME = dyn_cast<MemberExpr>(CE->getSubExpr());
+ if (ME && ME->getMemberDecl()->getType()->isCountAttributedType()) {
+ CountedByLoad = CE;
+ CountedByME = ME;
+ }
+ }
+ }
+
+ // The bounds check locates the count relative to the pointer field's
+ // address. When the base is exactly the field load, emit the field's
+ // l-value once and load the pointer from it, so that the struct base
+ // (which may have side-effects, e.g. 'get()->buf[i]' or 'p++->buf[i]')
+ // isn't evaluated a second time for the check. This mirrors the default
+ // case of EmitPointerWithAlignment. The load goes through EmitLoadOfLValue,
+ // not EmitLoadOfScalar, so that a '__ptrauth'-qualified field is
+ // authenticated before it's used.
+ Address CountedByFieldAddr = Address::invalid();
+ Address BaseAddr = Address::invalid();
+ if (CountedByME && E->getBase()->IgnoreParens() == CountedByLoad) {
+ LValue FieldLV = EmitCheckedLValue(CountedByME, TCK_Load);
+ CountedByFieldAddr = FieldLV.getAddress();
+ BaseAddr = makeNaturalAddressForPointer(
+ EmitLoadOfLValue(FieldLV, CountedByME->getExprLoc()).getScalarVal(),
+ E->getBase()->getType()->getPointeeType(), CharUnits(),
+ /*ForPointeeType=*/true, &EltBaseInfo, &EltTBAAInfo);
+ } else {
+ // The base must be a pointer; emit it with an estimate of its alignment.
+ BaseAddr =
+ EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
+ }
+
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
QualType ptrType = E->getBase()->getType();
Addr = emitArraySubscriptGEP(*this, BaseAddr, Idx, E->getType(),
@@ -5389,16 +5426,16 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
SignedIndices, E->getExprLoc(), &ptrType,
E->getBase());
- if (SanOpts.has(SanitizerKind::ArrayBounds)) {
- StructFieldAccess Visitor;
- const Expr *Base = Visitor.Visit(E->getBase());
-
- if (const auto *CE = dyn_cast_if_present<CastExpr>(Base);
- CE && CE->getCastKind() == CK_LValueToRValue)
- EmitCountedByBoundsChecking(CE, ptrType, Address::invalid(),
- E->getIdx()->getType(), Idx, Accessed,
- /*FlexibleArray=*/false);
- }
+ // Without the field's address (e.g. '((char *)p->buf)[i]'),
+ // EmitCountedByBoundsChecking re-emits the field's l-value. That only
+ // recomputes the field's address, so it's safe unless the struct base has
+ // side-effects. In that case skip the check rather than evaluating the
+ // base twice.
+ if (CountedByME && (CountedByFieldAddr.isValid() ||
+ !CountedByME->getBase()->HasSideEffects(getContext())))
+ EmitCountedByBoundsChecking(CountedByLoad, ptrType, CountedByFieldAddr,
+ E->getIdx()->getType(), Idx, Accessed,
+ /*FlexibleArray=*/false);
}
LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo);
diff --git a/clang/test/CodeGen/attr-counted-by-base-exprs.c b/clang/test/CodeGen/attr-counted-by-base-exprs.c
index 403b9de7a0b3ad..7f8aa45545c077 100644
--- a/clang/test/CodeGen/attr-counted-by-base-exprs.c
+++ b/clang/test/CodeGen/attr-counted-by-base-exprs.c
@@ -20,6 +20,11 @@ struct s {
int array[] __attribute__((counted_by(count)));
};
+struct p {
+ int count;
+ int *buf __attribute__((counted_by(count)));
+};
+
struct wrap {
long tag;
struct s *s;
@@ -33,6 +38,7 @@ struct e {
};
struct s *get_s(void);
+struct p *get_p(void);
// A call has side-effects, so __bdos can't use it to load the count.
// CHECK-LABEL: define dso_local noundef i64 @test_bdos_call_base(
@@ -48,14 +54,14 @@ unsigned long test_bdos_call_base(void) {
// CHECK-LABEL: define dso_local i32 @test_index_call_base(
// CHECK-SAME: i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call ptr @get_s() #[[ATTR8:[0-9]+]]
+// CHECK-NEXT: [[CALL:%.*]] = tail call ptr @get_s() #[[ATTR9:[0-9]+]]
// CHECK-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[CALL]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[I]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6:![0-9]+]]
// CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
// CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
// CHECK-NEXT: br i1 [[TMP2]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]]
// CHECK: [[TRAP]]:
-// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR9:[0-9]+]], !nosanitize [[META6]]
+// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR10:[0-9]+]], !nosanitize [[META6]]
// CHECK-NEXT: unreachable, !nosanitize [[META6]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[CALL]], i64 4
@@ -68,6 +74,104 @@ int test_index_call_base(int i) {
return get_s()->array[i];
}
+//
+// For a 'counted_by' pointer, the bounds check must not re-evaluate the base
+// to find the count: 'get_p' must be called only once, and 'pp' incremented
+// only once.
+// CHECK-LABEL: define dso_local i32 @test_index_call_base_ptr(
+// CHECK-SAME: i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR1]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[CALL:%.*]] = tail call ptr @get_p() #[[ATTR9]]
+// CHECK-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[CALL]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[I]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
+// CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
+// CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
+// CHECK-NEXT: br i1 [[TMP2]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// CHECK: [[TRAP]]:
+// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR10]], !nosanitize [[META6]]
+// CHECK-NEXT: unreachable, !nosanitize [[META6]]
+// CHECK: [[CONT]]:
+// CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[CALL]], i64 8
+// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[INTPTR_TBAA9:![0-9]+]]
+// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64
+// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP3]], i64 [[IDXPROM]]
+// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[INT_TBAA8]]
+// CHECK-NEXT: ret i32 [[TMP4]]
+//
+int test_index_call_base_ptr(int i) {
+ return get_p()->buf[i];
+}
+
+// CHECK-LABEL: define dso_local i32 @test_index_side_effect_base_ptr(
+// CHECK-SAME: ptr nofree noundef readonly captures(none) [[PP:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PP]], align 8, !tbaa [[_ZTS1PPTR_TBAA13:![0-9]+]]
+// CHECK-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[I]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
+// CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
+// CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
+// CHECK-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// CHECK: [[TRAP]]:
+// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR10]], !nosanitize [[META6]]
+// CHECK-NEXT: unreachable, !nosanitize [[META6]]
+// CHECK: [[CONT]]:
+// CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8
+// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[INTPTR_TBAA9]]
+// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64
+// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP4]], i64 [[IDXPROM]]
+// CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[INT_TBAA8]]
+// CHECK-NEXT: ret i32 [[TMP5]]
+//
+int test_index_side_effect_base_ptr(struct p **pp, int i) {
+ return (*pp++)->buf[i];
+}
+
+struct p *global_p;
+
+// CHECK-LABEL: define dso_local i32 @test_index_post_inc_base_ptr(
+// CHECK-SAME: i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr @global_p, align 8, !tbaa [[_ZTS1PPTR_TBAA13]]
+// CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16
+// CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr @global_p, align 8, !tbaa [[_ZTS1PPTR_TBAA13]]
+// CHECK-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[I]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
+// CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
+// CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
+// CHECK-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// CHECK: [[TRAP]]:
+// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR10]], !nosanitize [[META6]]
+// CHECK-NEXT: unreachable, !nosanitize [[META6]]
+// CHECK: [[CONT]]:
+// CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8
+// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[INTPTR_TBAA9]]
+// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64
+// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP4]], i64 [[IDXPROM]]
+// CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[INT_TBAA8]]
+// CHECK-NEXT: ret i32 [[TMP5]]
+//
+int test_index_post_inc_base_ptr(int i) {
+ return global_p++->buf[i];
+}
+
+// When there's a cast in between, the base can't be shared with the check, so
+// the check is skipped instead of evaluating the base twice.
+// CHECK-LABEL: define dso_local range(i32 -128, 128) i32 @test_index_side_effect_base_ptr_through_cast(
+// CHECK-SAME: i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR1]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[CALL:%.*]] = tail call ptr @get_p() #[[ATTR9]]
+// CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[CALL]], i64 8
+// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[INTPTR_TBAA9]]
+// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64
+// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1, !tbaa [[CHAR_TBAA15:![0-9]+]]
+// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT: ret i32 [[CONV]]
+//
+int test_index_side_effect_base_ptr_through_cast(int i) {
+ return ((char *)get_p()->buf)[i];
+}
+
// CHECK-LABEL: define dso_local noundef i64 @test_bdos_side_effect_base(
// CHECK-SAME: ptr nofree noundef readnone captures(none) [[PP:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -78,16 +182,16 @@ unsigned long test_bdos_side_effect_base(struct s **pp) {
}
// CHECK-LABEL: define dso_local i32 @test_index_side_effect_base(
-// CHECK-SAME: ptr nofree noundef readonly captures(none) [[PP:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] {
+// CHECK-SAME: ptr nofree noundef readonly captures(none) [[PP:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR4]] {
// CHECK-NEXT: [[ENTRY:.*:]]
-// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PP]], align 8, !tbaa [[_ZTS1SPTR_TBAA9:![0-9]+]]
+// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PP]], align 8, !tbaa [[_ZTS1SPTR_TBAA16:![0-9]+]]
// CHECK-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4
// CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[I]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
// CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
// CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
// CHECK-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// CHECK: [[TRAP]]:
-// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR9]], !nosanitize [[META6]]
+// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR10]], !nosanitize [[META6]]
// CHECK-NEXT: unreachable, !nosanitize [[META6]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 4
@@ -101,11 +205,11 @@ int test_index_side_effect_base(struct s **pp, int i) {
}
// CHECK-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test_bdos_array_of_ptrs(
-// CHECK-SAME: ptr nofree noundef readonly captures(none) [[PP:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] {
+// CHECK-SAME: ptr nofree noundef readonly captures(none) [[PP:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR6:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64
// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[PP]], i64 [[IDXPROM]]
-// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS1SPTR_TBAA9]]
+// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS1SPTR_TBAA16]]
// CHECK-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4
// CHECK-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
// CHECK-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nsw i64 [[COUNT]], 2
@@ -118,10 +222,10 @@ unsigned long test_bdos_array_of_ptrs(struct s **pp, int i) {
}
// CHECK-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test_bdos_through_ptr_member(
-// CHECK-SAME: ptr nofree noundef readonly captures(none) [[W:%.*]]) local_unnamed_addr #[[ATTR5]] {
+// CHECK-SAME: ptr nofree noundef readonly captures(none) [[W:%.*]]) local_unnamed_addr #[[ATTR6]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[S:%.*]] = getelementptr inbounds nuw i8, ptr [[W]], i64 8
-// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S]], align 8, !tbaa [[_ZTS1SPTR_TBAA12:![0-9]+]]
+// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S]], align 8, !tbaa [[_ZTS1SPTR_TBAA18:![0-9]+]]
// CHECK-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4
// CHECK-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
// CHECK-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nsw i64 [[COUNT]], 2
@@ -137,14 +241,14 @@ unsigned long test_bdos_through_ptr_member(struct wrap *w) {
// CHECK-SAME: ptr nofree noundef readonly captures(none) [[W:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR4]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[S:%.*]] = getelementptr inbounds nuw i8, ptr [[W]], i64 8
-// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S]], align 8, !tbaa [[_ZTS1SPTR_TBAA12]]
+// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S]], align 8, !tbaa [[_ZTS1SPTR_TBAA18]]
// CHECK-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4
// CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[I]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
// CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
// CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
// CHECK-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// CHECK: [[TRAP]]:
-// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR9]], !nosanitize [[META6]]
+// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR10]], !nosanitize [[META6]]
// CHECK-NEXT: unreachable, !nosanitize [[META6]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 4
@@ -158,7 +262,7 @@ int test_index_through_ptr_member(struct wrap *w, int i) {
}
// CHECK-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test_bdos_explicit_deref(
-// CHECK-SAME: ptr nofree noundef readonly captures(none) [[A:%.*]]) local_unnamed_addr #[[ATTR6:[0-9]+]] {
+// CHECK-SAME: ptr nofree noundef readonly captures(none) [[A:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[A]], align 4
// CHECK-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
@@ -191,7 +295,7 @@ unsigned long test_bdos_conditional_base(struct s *a, struct s *b, int c) {
// CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
// CHECK-NEXT: br i1 [[TMP2]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// CHECK: [[TRAP]]:
-// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR9]], !nosanitize [[META6]]
+// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR10]], !nosanitize [[META6]]
// CHECK-NEXT: unreachable, !nosanitize [[META6]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[COND]], i64 4
@@ -214,7 +318,7 @@ unsigned long test_bdos_negative_const_index(struct s *a) {
}
// CHECK-LABEL: define dso_local range(i64 0, 17179869181) i64 @test_bdos_enum_count(
-// CHECK-SAME: ptr nofree noundef readonly captures(none) [[A:%.*]]) local_unnamed_addr #[[ATTR6]] {
+// CHECK-SAME: ptr nofree noundef readonly captures(none) [[A:%.*]]) local_unnamed_addr #[[ATTR7]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[A]], align 4
// CHECK-NEXT: [[COUNT:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64
@@ -226,13 +330,13 @@ unsigned long test_bdos_enum_count(struct e *a) {
}
// CHECK-LABEL: define dso_local i32 @test_index_enum_count(
-// CHECK-SAME: ptr nofree noundef readonly captures(none) [[A:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] {
+// CHECK-SAME: ptr nofree noundef readonly captures(none) [[A:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR8:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[A]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[I]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
// CHECK-NEXT: br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// CHECK: [[TRAP]]:
-// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR9]], !nosanitize [[META6]]
+// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR10]], !nosanitize [[META6]]
// CHECK-NEXT: unreachable, !nosanitize [[META6]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 4
@@ -247,7 +351,7 @@ int test_index_enum_count(struct e *a, int i) {
// Index types narrower and wider than the count.
// CHECK-LABEL: define dso_local i32 @test_index_char(
-// CHECK-SAME: ptr nofree noundef readonly captures(none) [[A:%.*]], i8 noundef signext [[I:%.*]]) local_unnamed_addr #[[ATTR7]] {
+// CHECK-SAME: ptr nofree noundef readonly captures(none) [[A:%.*]], i8 noundef signext [[I:%.*]]) local_unnamed_addr #[[ATTR8]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[A]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = sext i8 [[I]] to i32
@@ -256,7 +360,7 @@ int test_index_enum_count(struct e *a, int i) {
// CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
// CHECK-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// CHECK: [[TRAP]]:
-// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR9]], !nosanitize [[META6]]
+// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR10]], !nosanitize [[META6]]
// CHECK-NEXT: unreachable, !nosanitize [[META6]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[IDXPROM:%.*]] = sext i8 [[I]] to i64
@@ -270,7 +374,7 @@ int test_index_char(struct s *a, signed char i) {
}
// CHECK-LABEL: define dso_local i32 @test_index_unsigned_long(
-// CHECK-SAME: ptr nofree noundef readonly captures(none) [[A:%.*]], i64 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR7]] {
+// CHECK-SAME: ptr nofree noundef readonly captures(none) [[A:%.*]], i64 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR8]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[A]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META6]]
@@ -279,7 +383,7 @@ int test_index_char(struct s *a, signed char i) {
// CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
// CHECK-NEXT: br i1 [[TMP3]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// CHECK: [[TRAP]]:
-// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR9]], !nosanitize [[META6]]
+// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 18) #[[ATTR10]], !nosanitize [[META6]]
// CHECK-NEXT: unreachable, !nosanitize [[META6]]
// CHECK: [[CONT]]:
// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 4
@@ -297,10 +401,16 @@ int test_index_unsigned_long(struct s *a, unsigned long i) {
// CHECK: [[META6]] = !{}
// CHECK: [[PROF7]] = !{!"branch_weights", i32 1048575, i32 1}
// CHECK: [[INT_TBAA8]] = !{[[META3]], [[META3]], i64 0}
-// CHECK: [[_ZTS1SPTR_TBAA9]] = !{[[META10:![0-9]+]], [[META10]], i64 0}
-// CHECK: [[META10]] = !{!"p1 _ZTS1s", [[META11:![0-9]+]], i64 0}
-// CHECK: [[META11]] = !{!"any pointer", [[META4]], i64 0}
-// CHECK: [[_ZTS1SPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META10]], i64 8}
-// CHECK: [[META13]] = !{!"wrap", [[META14:![0-9]+]], i64 0, [[META10]], i64 8}
-// CHECK: [[META14]] = !{!"long", [[META4]], i64 0}
+// CHECK: [[INTPTR_TBAA9]] = !{[[META10:![0-9]+]], [[META11:![0-9]+]], i64 8}
+// CHECK: [[META10]] = !{!"p", [[META3]], i64 0, [[META11]], i64 8}
+// CHECK: [[META11]] = !{!"p1 int", [[META12:![0-9]+]], i64 0}
+// CHECK: [[META12]] = !{!"any pointer", [[META4]], i64 0}
+// CHECK: [[_ZTS1PPTR_TBAA13]] = !{[[META14:![0-9]+]], [[META14]], i64 0}
+// CHECK: [[META14]] = !{!"p1 _ZTS1p", [[META12]], i64 0}
+// CHECK: [[CHAR_TBAA15]] = !{[[META4]], [[META4]], i64 0}
+// CHECK: [[_ZTS1SPTR_TBAA16]] = !{[[META17:![0-9]+]], [[META17]], i64 0}
+// CHECK: [[META17]] = !{!"p1 _ZTS1s", [[META12]], i64 0}
+// CHECK: [[_ZTS1SPTR_TBAA18]] = !{[[META19:![0-9]+]], [[META17]], i64 8}
+// CHECK: [[META19]] = !{!"wrap", [[META20:![0-9]+]], i64 0, [[META17]], i64 8}
+// CHECK: [[META20]] = !{!"long", [[META4]], i64 0}
//.
diff --git a/clang/test/CodeGen/attr-counted-by-for-pointers.c b/clang/test/CodeGen/attr-counted-by-for-pointers.c
index ef0f3ac23a67f3..5aa7dfbc6b76aa 100644
--- a/clang/test/CodeGen/attr-counted-by-for-pointers.c
+++ b/clang/test/CodeGen/attr-counted-by-for-pointers.c
@@ -33,12 +33,12 @@ struct annotated_ptr {
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6:![0-9]+]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT5:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP3]]) #[[ATTR4:[0-9]+]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT5]]:
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA8:![0-9]+]]
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
@@ -143,12 +143,12 @@ void test_store_subscript_through_cast(struct annotated_ptr *p, int index, struc
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT5:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP3]]) #[[ATTR4]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT5]]:
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA8]]
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
@@ -270,12 +270,12 @@ size_t test_bdos_of_pointer_through_cast(struct annotated_ptr *p, int index) {
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT3:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[TMP3]]) #[[ATTR4]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
+// SANITIZE-WITH-ATTR: [[CONT3]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = sub nuw nsw i64 [[COUNT]], [[IDXPROM]]
diff --git a/clang/test/CodeGen/attr-counted-by-or-null-for-pointers.c b/clang/test/CodeGen/attr-counted-by-or-null-for-pointers.c
index f7de00e62d4b27..185937acfec289 100644
--- a/clang/test/CodeGen/attr-counted-by-or-null-for-pointers.c
+++ b/clang/test/CodeGen/attr-counted-by-or-null-for-pointers.c
@@ -43,12 +43,12 @@ struct annotated_ptr {
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ult i32 [[INDEX]], [[TMP2]], !nosanitize [[META12:![0-9]+]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13:![0-9]+]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT5:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13:![0-9]+]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP6]]) #[[ATTR5:[0-9]+]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT5]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14:![0-9]+]]
@@ -157,12 +157,12 @@ void test_store_subscript_through_cast(struct annotated_ptr *p, int index, struc
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ule i32 [[INDEX]], [[TMP2]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT5:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT5]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14]]
@@ -298,12 +298,12 @@ size_t test_bdos_of_pointer_through_cast(struct annotated_ptr *p, int index) {
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ule i32 [[INDEX]], [[TMP2]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT3:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
+// SANITIZE-WITH-ATTR: [[CONT3]]:
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = shl nsw i64 [[COUNT]], 3
diff --git a/clang/test/CodeGen/attr-counted-by-ptrauth.c b/clang/test/CodeGen/attr-counted-by-ptrauth.c
new file mode 100644
index 00000000000000..18f727f88f3da3
--- /dev/null
+++ b/clang/test/CodeGen/attr-counted-by-ptrauth.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-intrinsics -fsanitize=array-bounds -fsanitize-trap=array-bounds -emit-llvm -o - %s | FileCheck %s
+
+// A '__ptrauth'-qualified 'counted_by' pointer must still be authenticated
+// before it's indexed when -fsanitize=array-bounds emits the field's l-value
+// itself to share it with the bounds check.
+
+struct pa {
+ int count;
+ int *__ptrauth(1, 1, 42) buf __attribute__((counted_by(count)));
+};
+
+// CHECK-LABEL: define {{.*}} @test_index(
+// CHECK: [[BUF:%.*]] = getelementptr inbounds nuw %struct.pa, ptr {{%.*}}, i32 0, i32 1
+// CHECK: [[SIGNED:%.*]] = load ptr, ptr [[BUF]]
+// CHECK: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 42)
+// CHECK: [[INT:%.*]] = ptrtoint ptr [[SIGNED]] to i64
+// CHECK: [[AUTH:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[INT]], i32 1, i64 [[DISC]])
+// CHECK: [[PTR:%.*]] = inttoptr i64 [[AUTH]] to ptr
+// CHECK: [[PHI:%.*]] = phi ptr [ null, {{.*}} ], [ [[PTR]], {{.*}} ]
+// CHECK: getelementptr inbounds i32, ptr [[PHI]], i64
+// CHECK: call void @llvm.ubsantrap(
+int test_index(struct pa *p, int i) {
+ return p->buf[i];
+}
diff --git a/clang/test/CodeGen/attr-sized-by-for-pointers.c b/clang/test/CodeGen/attr-sized-by-for-pointers.c
index dabe3163571a5d..b7eb0d1f244e06 100644
--- a/clang/test/CodeGen/attr-sized-by-for-pointers.c
+++ b/clang/test/CodeGen/attr-sized-by-for-pointers.c
@@ -34,12 +34,12 @@ struct annotated_ptr {
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i32 [[INDEX]], [[TMP0]], !nosanitize [[META6:![0-9]+]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 7
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT5:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP4]]) #[[ATTR6:[0-9]+]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT5]]:
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA8:![0-9]+]]
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
@@ -146,12 +146,12 @@ void test_store_subscript_through_cast(struct annotated_ptr *p, int index, struc
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ule i32 [[INDEX]], [[TMP0]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 7
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT5:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP4]]) #[[ATTR6]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT5]]:
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA8]]
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
@@ -217,12 +217,12 @@ struct annotated_sized_ptr_odd_pointee {
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = udiv i32 [[DOTCOUNTED_BY_LOAD]], 3
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i32 [[INDEX]], [[TMP0]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label %[[CONT15:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[TMP2]]) #[[ATTR6]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR: [[CONT15]]:
+// SANITIZE-WITH-ATTR: [[CONT10]]:
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS18THREE_BYTE_POINTEEPTR_TBAA16:![0-9]+]]
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
@@ -281,12 +281,12 @@ struct annotated_sized_ptr_pow2_unsigned_count {
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = lshr i32 [[DOTCOUNTED_BY_LOAD]], 3
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i32 [[INDEX]], [[TMP0]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label %[[CONT5:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[TMP2]]) #[[ATTR6]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT5]]:
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA20:![0-9]+]]
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
@@ -472,12 +472,12 @@ size_t test_bdos_of_pointer(struct annotated_sized_ptr *p) {
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT3:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP3]]) #[[ATTR6]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
+// SANITIZE-WITH-ATTR: [[CONT3]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nuw nsw i64 [[COUNT]], [[IDXPROM]]
@@ -598,12 +598,12 @@ size_t test_bdos_of_pointer_multibyte_pointee(struct annotated_sized_ptr_non_byt
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ule i32 [[INDEX]], [[TMP0]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 7
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT3:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB18:[0-9]+]], i64 [[TMP4]]) #[[ATTR6]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
+// SANITIZE-WITH-ATTR: [[CONT3]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[INDEX_SIZE:%.*]] = shl nsw i64 [[IDXPROM]], 3
diff --git a/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c b/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c
index 05f3c57d861498..06452acfc03fbc 100644
--- a/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c
+++ b/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c
@@ -44,12 +44,12 @@ struct annotated_ptr {
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i32 [[INDEX]], [[TMP3]], !nosanitize [[META12:![0-9]+]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP3]], 0, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13:![0-9]+]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT5:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13:![0-9]+]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP7]]) #[[ATTR6:[0-9]+]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT5]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14:![0-9]+]]
@@ -160,12 +160,12 @@ void test_store_subscript_through_cast(struct annotated_ptr *p, int index, struc
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ule i32 [[INDEX]], [[TMP3]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP3]], 0, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT5:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP7]]) #[[ATTR6]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT5]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14]]
@@ -233,12 +233,12 @@ struct annotated_sized_ptr_odd_pointee {
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = udiv i32 [[DOTCOUNTED_BY_LOAD]], 3
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[TMP2]], [[INDEX]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i1 [[TMP3]], i1 false
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label %[[CONT15:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[TMP5]]) #[[ATTR6]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT15]]:
+// SANITIZE-WITH-ATTR: [[CONT10]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [3 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = load i8, ptr [[ARRAYIDX]], align 1, !tbaa [[CHAR_TBAA19:![0-9]+]]
@@ -299,12 +299,12 @@ struct annotated_sized_ptr_pow2_unsigned_count {
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = lshr i32 [[DOTCOUNTED_BY_LOAD]], 3
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[TMP2]], [[INDEX]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i1 [[TMP3]], i1 false
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label %[[CONT5:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[TMP5]]) #[[ATTR6]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT5]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14]]
@@ -500,12 +500,12 @@ size_t test_bdos_of_pointer(struct annotated_sized_ptr *p) {
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ule i32 [[INDEX]], [[TMP2]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT3:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP6]]) #[[ATTR6]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
+// SANITIZE-WITH-ATTR: [[CONT3]]:
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP1]], i64 0, i64 [[COUNT]]
@@ -649,12 +649,12 @@ size_t test_bdos_of_pointer_multibyte_pointee(struct annotated_sized_ptr_non_byt
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ule i32 [[INDEX]], [[TMP3]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP3]], 0, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT3:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB18:[0-9]+]], i64 [[TMP7]]) #[[ATTR6]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
+// SANITIZE-WITH-ATTR: [[CONT3]]:
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP1]], i64 0, i64 [[COUNT]]
More information about the llvm-branch-commits
mailing list