[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
Fri Oct 16 15:48:42 PDT 2026


https://github.com/isanbard updated https://github.com/llvm/llvm-project/pull/232228

>From 75d65b56642866dba3fb461e91507db57a5dd66b 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 96c6022f599b7..8755772dad8af 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5333,9 +5333,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(),
@@ -5343,16 +5380,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 403b9de7a0b3a..7f8aa45545c07 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 ef0f3ac23a67f..5aa7dfbc6b76a 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 f7de00e62d4b2..185937acfec28 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 0000000000000..18f727f88f3da
--- /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 dabe3163571a5..b7eb0d1f244e0 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 05f3c57d86149..06452acfc03fb 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