[llvm] [HWASan] [MTE] use precise lifetimes even if they don't cover all exits (PR #174875)
Florian Mayer via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 8 13:44:05 PST 2026
https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/174875
>From 262f4c9ddec512f436d9bdb52834849fa7dfa913 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Wed, 7 Jan 2026 14:21:33 -0800
Subject: [PATCH 1/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
=?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6
---
.../Transforms/Utils/MemoryTaggingSupport.cpp | 24 ++-----
.../CodeGen/AArch64/stack-tagging-ex-1.ll | 3 +-
.../AArch64/stack-tagging-split-lifetime.ll | 48 ++++++++++++-
.../AArch64/stack-tagging-untag-placement.ll | 6 +-
.../HWAddressSanitizer/use-after-scope.ll | 68 +++++++++----------
5 files changed, 93 insertions(+), 56 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
index 1f59b1782c709..68eef553d3428 100644
--- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
+++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
@@ -58,32 +58,22 @@ bool forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT,
for (auto *End : Ends) {
EndBlocks.insert(End->getParent());
}
- SmallVector<Instruction *, 8> ReachableRetVec;
- unsigned NumCoveredExits = 0;
+ bool UncoveredRets = false;
for (auto *RI : RetVec) {
if (!isPotentiallyReachable(Start, RI, nullptr, &DT, &LI))
continue;
- ReachableRetVec.push_back(RI);
// If there is an end in the same basic block as the return, we know for
// sure that the return is covered. Otherwise, we can check whether there
// is a way to reach the RI from the start of the lifetime without passing
// through an end.
- if (EndBlocks.contains(RI->getParent()) ||
- !isPotentiallyReachable(Start, RI, &EndBlocks, &DT, &LI)) {
- ++NumCoveredExits;
+ if (!EndBlocks.contains(RI->getParent()) &&
+ isPotentiallyReachable(Start, RI, &EndBlocks, &DT, &LI)) {
+ Callback(RI);
+ UncoveredRets = true;
}
}
- if (NumCoveredExits == ReachableRetVec.size()) {
- for_each(Ends, Callback);
- } else {
- // If there's a mix of covered and non-covered exits, just put the untag
- // on exits, so we avoid the redundancy of untagging twice.
- for_each(ReachableRetVec, Callback);
- // We may have inserted untag outside of the lifetime interval.
- // Signal the caller to remove the lifetime end call for this alloca.
- return false;
- }
- return true;
+ for_each(Ends, Callback);
+ return !UncoveredRets;
}
bool isStandardLifetime(const SmallVectorImpl<IntrinsicInst *> &LifetimeStart,
diff --git a/llvm/test/CodeGen/AArch64/stack-tagging-ex-1.ll b/llvm/test/CodeGen/AArch64/stack-tagging-ex-1.ll
index 22abb8ccceb19..1b846cbb0a222 100644
--- a/llvm/test/CodeGen/AArch64/stack-tagging-ex-1.ll
+++ b/llvm/test/CodeGen/AArch64/stack-tagging-ex-1.ll
@@ -20,7 +20,8 @@ next0:
call void @llvm.lifetime.end.p0(i64 40, ptr nonnull %a)
call void @llvm.lifetime.end.p0(i64 40, ptr nonnull %b)
br label %exit
-; CHECK-NOT: settag
+; CHECK-DAG: call void @llvm.aarch64.settag(ptr %a, i64 48)
+; CHECK-DAG: call void @llvm.aarch64.settag(ptr %b, i64 48)
lpad0:
; CHECK-LABEL: lpad0:
diff --git a/llvm/test/CodeGen/AArch64/stack-tagging-split-lifetime.ll b/llvm/test/CodeGen/AArch64/stack-tagging-split-lifetime.ll
index e2c41cad29452..0fac7ec0ac0e1 100644
--- a/llvm/test/CodeGen/AArch64/stack-tagging-split-lifetime.ll
+++ b/llvm/test/CodeGen/AArch64/stack-tagging-split-lifetime.ll
@@ -140,13 +140,13 @@ start1:
next0:
; CHECK-LABEL: next0:
-; CHECK-NOT: call void @llvm.aarch64.settag
+; CHECK: call void @llvm.aarch64.settag
call void @llvm.lifetime.end.p0(i64 40, ptr nonnull %a)
br label %exit1
next1:
; CHECK-LABEL: next1:
-; CHECK-NOT: call void @llvm.aarch64.settag
+; CHECK: call void @llvm.aarch64.settag
call void @llvm.lifetime.end.p0(i64 40, ptr nonnull %a)
br label %exit1
@@ -161,5 +161,49 @@ exit1:
ret void
}
+define void @diamond4_nocover(i1 %cond, i1 %cond1, i1 %cond2) local_unnamed_addr sanitize_memtag {
+start:
+; CHECK-LABEL: start:
+ %a = alloca i8, i32 48, align 8
+ call void @llvm.lifetime.start.p0(i64 48, ptr nonnull %a)
+ call void @use8(ptr %a)
+; CHECK: call void @llvm.aarch64.settag(ptr %a.tag, i64 48)
+ br i1 %cond, label %next0, label %start1
+
+start1:
+ br i1 %cond1, label %exit2, label %start2
+
+start2:
+ br i1 %cond2, label %next1, label %next2
+
+next0:
+; CHECK-LABEL: next0:
+; CHECK: call void @llvm.aarch64.settag
+ call void @llvm.lifetime.end.p0(i64 40, ptr nonnull %a)
+ br label %exit1
+
+next1:
+; CHECK-LABEL: next1:
+; CHECK: call void @llvm.aarch64.settag
+ call void @llvm.lifetime.end.p0(i64 40, ptr nonnull %a)
+ br label %exit1
+
+next2:
+; CHECK-LABEL: next2:
+; CHECK: call void @llvm.aarch64.settag
+ call void @llvm.lifetime.end.p0(i64 40, ptr nonnull %a)
+ br label %exit1
+
+exit1:
+; CHECK-LABEL: exit1:
+; CHECK-NOT: call void @llvm.aarch64.settag
+ ret void
+
+exit2:
+; CHECK-LABEL: exit2:
+; CHECK: call void @llvm.aarch64.settag
+ ret void
+}
+
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
diff --git a/llvm/test/CodeGen/AArch64/stack-tagging-untag-placement.ll b/llvm/test/CodeGen/AArch64/stack-tagging-untag-placement.ll
index 74836224052b0..59b6ec7011f6b 100644
--- a/llvm/test/CodeGen/AArch64/stack-tagging-untag-placement.ll
+++ b/llvm/test/CodeGen/AArch64/stack-tagging-untag-placement.ll
@@ -43,16 +43,18 @@ S3:
call void @llvm.lifetime.end.p0(ptr nonnull %v) #1
tail call void @z1() #1
br label %exit2
-; CHECK-NOT: settag
+; CHECK: call void @llvm.aarch64.settag(ptr %v, i64 48)
+; Dominated by S1 and S2
exit1:
; CHECK-LABEL: exit1:
; CHECK: call void @llvm.aarch64.settag(ptr %v, i64 48)
ret void
+; Dominated by S3
exit2:
; CHECK-LABEL: exit2:
-; CHECK: call void @llvm.aarch64.settag(ptr %v, i64 48)
+; CHECK-NOT: call void @llvm.aarch64.settag
ret void
exit3:
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll b/llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll
index cfded025dce7f..6e8b009db02a8 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll
@@ -69,7 +69,7 @@ define dso_local i32 @standard_lifetime() local_unnamed_addr sanitize_hwaddress
; AARCH64-SCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1:![0-9]+]])
+; AARCH64-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2:![0-9]+]])
; AARCH64-SCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -121,7 +121,7 @@ define dso_local i32 @standard_lifetime() local_unnamed_addr sanitize_hwaddress
; AARCH64-NOSCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-NOSCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-NOSCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1:![0-9]+]])
+; AARCH64-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2:![0-9]+]])
; AARCH64-NOSCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-NOSCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-NOSCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -171,7 +171,7 @@ define dso_local i32 @standard_lifetime() local_unnamed_addr sanitize_hwaddress
; AARCH64-SHORT-SCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SHORT-SCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SHORT-SCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SHORT-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1:![0-9]+]])
+; AARCH64-SHORT-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2:![0-9]+]])
; AARCH64-SHORT-SCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SHORT-SCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SHORT-SCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -226,7 +226,7 @@ define dso_local i32 @standard_lifetime() local_unnamed_addr sanitize_hwaddress
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1:![0-9]+]])
+; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2:![0-9]+]])
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -350,7 +350,7 @@ define dso_local i32 @standard_lifetime_optnone() local_unnamed_addr optnone noi
; AARCH64-SCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -402,7 +402,7 @@ define dso_local i32 @standard_lifetime_optnone() local_unnamed_addr optnone noi
; AARCH64-NOSCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-NOSCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-NOSCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-NOSCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-NOSCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-NOSCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -452,7 +452,7 @@ define dso_local i32 @standard_lifetime_optnone() local_unnamed_addr optnone noi
; AARCH64-SHORT-SCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SHORT-SCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SHORT-SCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SHORT-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SHORT-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SHORT-SCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SHORT-SCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SHORT-SCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -507,7 +507,7 @@ define dso_local i32 @standard_lifetime_optnone() local_unnamed_addr optnone noi
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -621,7 +621,7 @@ define dso_local i32 @multiple_lifetimes() local_unnamed_addr sanitize_hwaddress
; AARCH64-SCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -667,7 +667,7 @@ define dso_local i32 @multiple_lifetimes() local_unnamed_addr sanitize_hwaddress
; AARCH64-NOSCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-NOSCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-NOSCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-NOSCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-NOSCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-NOSCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -713,7 +713,7 @@ define dso_local i32 @multiple_lifetimes() local_unnamed_addr sanitize_hwaddress
; AARCH64-SHORT-SCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SHORT-SCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SHORT-SCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SHORT-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SHORT-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SHORT-SCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SHORT-SCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SHORT-SCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -762,7 +762,7 @@ define dso_local i32 @multiple_lifetimes() local_unnamed_addr sanitize_hwaddress
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -840,8 +840,8 @@ define dso_local i32 @unreachable_exit() local_unnamed_addr sanitize_hwaddress {
; X86-SCOPE-NEXT: br i1 [[TMP12]], label [[TMP13:%.*]], label [[TMP15:%.*]]
; X86-SCOPE: 13:
; X86-SCOPE-NEXT: call void @use(ptr nonnull [[ALLOCA_0_HWASAN]])
-; X86-SCOPE-NEXT: [[TMP14:%.*]] = trunc i64 [[HWASAN_UAR_TAG]] to i8
-; X86-SCOPE-NEXT: call void @__hwasan_tag_memory(ptr [[TMP4]], i8 [[TMP14]], i64 16)
+; X86-SCOPE-NEXT: [[TMP17:%.*]] = trunc i64 [[HWASAN_UAR_TAG]] to i8
+; X86-SCOPE-NEXT: call void @__hwasan_tag_memory(ptr [[TMP4]], i8 [[TMP17]], i64 16)
; X86-SCOPE-NEXT: ret i32 0
; X86-SCOPE: 15:
; X86-SCOPE-NEXT: [[TMP16:%.*]] = trunc i64 [[HWASAN_UAR_TAG]] to i8
@@ -881,7 +881,7 @@ define dso_local i32 @unreachable_exit() local_unnamed_addr sanitize_hwaddress {
; AARCH64-SCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -917,12 +917,12 @@ define dso_local i32 @unreachable_exit() local_unnamed_addr sanitize_hwaddress {
; AARCH64-SCOPE-NEXT: br i1 [[TMP30]], label [[TMP31:%.*]], label [[TMP37:%.*]]
; AARCH64-SCOPE: 31:
; AARCH64-SCOPE-NEXT: call void @use(ptr nonnull [[ALLOCA_0_HWASAN]])
-; AARCH64-SCOPE-NEXT: [[TMP32:%.*]] = trunc i64 [[HWASAN_UAR_TAG]] to i8
-; AARCH64-SCOPE-NEXT: [[TMP33:%.*]] = ptrtoint ptr [[TMP18]] to i64
-; AARCH64-SCOPE-NEXT: [[TMP34:%.*]] = and i64 [[TMP33]], 72057594037927935
-; AARCH64-SCOPE-NEXT: [[TMP35:%.*]] = lshr i64 [[TMP34]], 4
-; AARCH64-SCOPE-NEXT: [[TMP36:%.*]] = getelementptr i8, ptr [[TMP17]], i64 [[TMP35]]
-; AARCH64-SCOPE-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP36]], i8 [[TMP32]], i64 1, i1 false)
+; AARCH64-SCOPE-NEXT: [[TMP43:%.*]] = trunc i64 [[HWASAN_UAR_TAG]] to i8
+; AARCH64-SCOPE-NEXT: [[TMP44:%.*]] = ptrtoint ptr [[TMP18]] to i64
+; AARCH64-SCOPE-NEXT: [[TMP45:%.*]] = and i64 [[TMP44]], 72057594037927935
+; AARCH64-SCOPE-NEXT: [[TMP46:%.*]] = lshr i64 [[TMP45]], 4
+; AARCH64-SCOPE-NEXT: [[TMP47:%.*]] = getelementptr i8, ptr [[TMP17]], i64 [[TMP46]]
+; AARCH64-SCOPE-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP47]], i8 [[TMP43]], i64 1, i1 false)
; AARCH64-SCOPE-NEXT: ret i32 0
; AARCH64-SCOPE: 37:
; AARCH64-SCOPE-NEXT: [[TMP38:%.*]] = trunc i64 [[HWASAN_UAR_TAG]] to i8
@@ -938,7 +938,7 @@ define dso_local i32 @unreachable_exit() local_unnamed_addr sanitize_hwaddress {
; AARCH64-NOSCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-NOSCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-NOSCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-NOSCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-NOSCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-NOSCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -994,7 +994,7 @@ define dso_local i32 @unreachable_exit() local_unnamed_addr sanitize_hwaddress {
; AARCH64-SHORT-SCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SHORT-SCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SHORT-SCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SHORT-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SHORT-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SHORT-SCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SHORT-SCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SHORT-SCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -1033,12 +1033,12 @@ define dso_local i32 @unreachable_exit() local_unnamed_addr sanitize_hwaddress {
; AARCH64-SHORT-SCOPE-NEXT: br i1 [[TMP32]], label [[TMP33:%.*]], label [[TMP39:%.*]]
; AARCH64-SHORT-SCOPE: 33:
; AARCH64-SHORT-SCOPE-NEXT: call void @use(ptr nonnull [[ALLOCA_0_HWASAN]])
-; AARCH64-SHORT-SCOPE-NEXT: [[TMP34:%.*]] = trunc i64 [[HWASAN_UAR_TAG]] to i8
-; AARCH64-SHORT-SCOPE-NEXT: [[TMP35:%.*]] = ptrtoint ptr [[TMP18]] to i64
-; AARCH64-SHORT-SCOPE-NEXT: [[TMP36:%.*]] = and i64 [[TMP35]], 72057594037927935
-; AARCH64-SHORT-SCOPE-NEXT: [[TMP37:%.*]] = lshr i64 [[TMP36]], 4
-; AARCH64-SHORT-SCOPE-NEXT: [[TMP38:%.*]] = getelementptr i8, ptr [[TMP17]], i64 [[TMP37]]
-; AARCH64-SHORT-SCOPE-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP38]], i8 [[TMP34]], i64 1, i1 false)
+; AARCH64-SHORT-SCOPE-NEXT: [[TMP45:%.*]] = trunc i64 [[HWASAN_UAR_TAG]] to i8
+; AARCH64-SHORT-SCOPE-NEXT: [[TMP46:%.*]] = ptrtoint ptr [[TMP18]] to i64
+; AARCH64-SHORT-SCOPE-NEXT: [[TMP47:%.*]] = and i64 [[TMP46]], 72057594037927935
+; AARCH64-SHORT-SCOPE-NEXT: [[TMP48:%.*]] = lshr i64 [[TMP47]], 4
+; AARCH64-SHORT-SCOPE-NEXT: [[TMP49:%.*]] = getelementptr i8, ptr [[TMP17]], i64 [[TMP48]]
+; AARCH64-SHORT-SCOPE-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP49]], i8 [[TMP45]], i64 1, i1 false)
; AARCH64-SHORT-SCOPE-NEXT: ret i32 0
; AARCH64-SHORT-SCOPE: 39:
; AARCH64-SHORT-SCOPE-NEXT: [[TMP40:%.*]] = trunc i64 [[HWASAN_UAR_TAG]] to i8
@@ -1054,7 +1054,7 @@ define dso_local i32 @unreachable_exit() local_unnamed_addr sanitize_hwaddress {
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -1189,7 +1189,7 @@ define dso_local i32 @diamond_lifetime() local_unnamed_addr sanitize_hwaddress {
; AARCH64-SCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -1250,7 +1250,7 @@ define dso_local i32 @diamond_lifetime() local_unnamed_addr sanitize_hwaddress {
; AARCH64-NOSCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-NOSCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-NOSCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-NOSCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-NOSCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-NOSCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -1302,7 +1302,7 @@ define dso_local i32 @diamond_lifetime() local_unnamed_addr sanitize_hwaddress {
; AARCH64-SHORT-SCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SHORT-SCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SHORT-SCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SHORT-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SHORT-SCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SHORT-SCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SHORT-SCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SHORT-SCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
@@ -1366,7 +1366,7 @@ define dso_local i32 @diamond_lifetime() local_unnamed_addr sanitize_hwaddress {
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3
-; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META1]])
+; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP5:%.*]] = call i64 @llvm.read_register.i64(metadata [[META2]])
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP6:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[TMP6]] to i64
; AARCH64-SHORT-NOSCOPE-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 44
>From 62e9df8725d25036cd68e944e0bd74394b88de58 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Thu, 8 Jan 2026 13:35:12 -0800
Subject: [PATCH 2/3] simplify
Created using spr 1.3.6
---
llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
index 68eef553d3428..f847ae057b1e3 100644
--- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
+++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
@@ -60,8 +60,6 @@ bool forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT,
}
bool UncoveredRets = false;
for (auto *RI : RetVec) {
- if (!isPotentiallyReachable(Start, RI, nullptr, &DT, &LI))
- continue;
// If there is an end in the same basic block as the return, we know for
// sure that the return is covered. Otherwise, we can check whether there
// is a way to reach the RI from the start of the lifetime without passing
>From 901404c3ca4bd3bc08868aedfebe9b582838dca4 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Thu, 8 Jan 2026 13:43:49 -0800
Subject: [PATCH 3/3] cmt
Created using spr 1.3.6
---
llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
index f847ae057b1e3..ccd66b986f763 100644
--- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
+++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
@@ -71,6 +71,8 @@ bool forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT,
}
}
for_each(Ends, Callback);
+ // We may have inserted untag outside of the lifetime interval.
+ // Signal the caller to remove the lifetime end call for this alloca.
return !UncoveredRets;
}
More information about the llvm-commits
mailing list