[llvm-branch-commits] [HWASan] add optimization remark for supported lifetimes (PR #183858)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Feb 27 14:56:48 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Florian Mayer (fmayer)

<details>
<summary>Changes</summary>

This lets us find functions where we pessimize codegen by removing
lifetimes.


---
Full diff: https://github.com/llvm/llvm-project/pull/183858.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp (+14-5) 
- (modified) llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll (+26-1) 


``````````diff
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index d57e2ee0839e3..6363028f423ce 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -388,9 +388,9 @@ class HWAddressSanitizer {
   void tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag, size_t Size);
   Value *tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong, Value *Tag);
   Value *untagPointer(IRBuilder<> &IRB, Value *PtrLong);
-  void instrumentStack(memtag::StackInfo &Info, Value *StackTag, Value *UARTag,
-                       const DominatorTree &DT, const PostDominatorTree &PDT,
-                       const LoopInfo &LI);
+  void instrumentStack(OptimizationRemarkEmitter &ORE, memtag::StackInfo &Info,
+                       Value *StackTag, Value *UARTag, const DominatorTree &DT,
+                       const PostDominatorTree &PDT, const LoopInfo &LI);
   void instrumentLandingPads(SmallVectorImpl<Instruction *> &RetVec);
   Value *getNextTagWithCall(IRBuilder<> &IRB);
   Value *getStackBaseTag(IRBuilder<> &IRB);
@@ -1464,7 +1464,8 @@ void HWAddressSanitizer::instrumentLandingPads(
   }
 }
 
-void HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo,
+void HWAddressSanitizer::instrumentStack(OptimizationRemarkEmitter &ORE,
+                                         memtag::StackInfo &SInfo,
                                          Value *StackTag, Value *UARTag,
                                          const DominatorTree &DT,
                                          const PostDominatorTree &PDT,
@@ -1527,6 +1528,10 @@ void HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo,
     // statement if return_twice functions are called.
     if (DetectUseAfterScope && !SInfo.CallsReturnTwice &&
         memtag::isSupportedLifetime(Info, &DT, &LI)) {
+      ORE.emit([&]() {
+        return OptimizationRemark(DEBUG_TYPE, "supportedLifetime", AI);
+      });
+
       TagStarts();
       if (!memtag::forAllReachableExits(DT, PDT, LI, Info, SInfo.RetVec,
                                         TagEnd)) {
@@ -1535,6 +1540,10 @@ void HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo,
       }
     } else if (DetectUseAfterScope && ClStrictUseAfterScope) {
       // SInfo.CallsReturnTwice || !isStandardLifetime
+      ORE.emit([&]() {
+        return OptimizationRemarkMissed(DEBUG_TYPE, "supportedLifetime", AI);
+      });
+
       tagAlloca(IRB, AI, Tag, Size);
       TagStarts();
       for_each(Info.LifetimeEnd, TagEnd);
@@ -1676,7 +1685,7 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,
     const LoopInfo &LI = FAM.getResult<LoopAnalysis>(F);
     Value *StackTag = getStackBaseTag(EntryIRB);
     Value *UARTag = getUARTag(EntryIRB);
-    instrumentStack(SInfo, StackTag, UARTag, DT, PDT, LI);
+    instrumentStack(ORE, SInfo, StackTag, UARTag, DT, PDT, LI);
   }
 
   // If we split the entry block, move any allocas that were originally in the
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll b/llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll
index a95d81bf3d2c1..bac659ca30480 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll
@@ -1,6 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; REQUIRES: aarch64-registered-target, x86-registered-target
-; RUN: opt -mtriple=x86_64-unknown-linux-gnu -passes=hwasan -hwasan-use-after-scope=1 -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=X86-SCOPE
+; RUN: opt -mtriple=x86_64-unknown-linux-gnu -passes=hwasan -hwasan-use-after-scope=1 -hwasan-generate-tags-with-calls -pass-remarks-output=%t.pass-remarks -S < %s | FileCheck %s --check-prefixes=X86-SCOPE
+; RUN: cat %t.pass-remarks | FileCheck %s --check-prefixes=REMARKS
 ; RUN: opt -mtriple=x86_64-unknown-linux-gnu -passes=hwasan -hwasan-use-after-scope=0 -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=X86-NOSCOPE
 
 ; RUN: opt -mtriple=aarch64-unknown-linux-android29 -passes=hwasan -hwasan-use-after-scope=1 -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=AARCH64-SCOPE
@@ -290,6 +291,8 @@ define dso_local i32 @standard_lifetime() local_unnamed_addr sanitize_hwaddress
   ret i32 0
 }
 
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: standard_lifetime
+
 define dso_local i32 @standard_lifetime_optnone() local_unnamed_addr optnone noinline sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @standard_lifetime_optnone(
 ; X86-SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
@@ -571,6 +574,8 @@ define dso_local i32 @standard_lifetime_optnone() local_unnamed_addr optnone noi
   ret i32 0
 }
 
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: standard_lifetime_optnone
+
 define dso_local i32 @multiple_lifetimes() local_unnamed_addr sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @multiple_lifetimes(
 ; X86-SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
@@ -861,6 +866,8 @@ define dso_local i32 @multiple_lifetimes() local_unnamed_addr sanitize_hwaddress
   ret i32 0
 }
 
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: multiple_lifetimes
+
 define dso_local i32 @multiple_lifetimes_unterminated() local_unnamed_addr sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @multiple_lifetimes_unterminated(
 ; X86-SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
@@ -1142,6 +1149,8 @@ define dso_local i32 @multiple_lifetimes_unterminated() local_unnamed_addr sanit
   ret i32 0
 }
 
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: multiple_lifetimes_unterminated
+
 define dso_local i32 @unreachable_exit() local_unnamed_addr sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @unreachable_exit(
 ; X86-SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
@@ -1446,6 +1455,9 @@ define dso_local i32 @unreachable_exit() local_unnamed_addr sanitize_hwaddress {
   ret i32 0
 }
 
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: unreachable_exit
+
+
 define dso_local i32 @diamond_lifetime() local_unnamed_addr sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @diamond_lifetime(
 ; X86-SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
@@ -1758,6 +1770,8 @@ define dso_local i32 @diamond_lifetime() local_unnamed_addr sanitize_hwaddress {
   ret i32 0
 }
 
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: diamond_lifetime
+
 define  void @diamond4_nocover(i1 %cond, i1 %cond1, i1 %cond2) local_unnamed_addr sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @diamond4_nocover(
 ; X86-SCOPE-NEXT:  start:
@@ -2161,6 +2175,8 @@ exit2:
   ret void
 }
 
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: diamond4_nocover
+
 define dso_local i32 @multiple_starts() local_unnamed_addr sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @multiple_starts(
 ; X86-SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
@@ -2476,6 +2492,8 @@ define dso_local i32 @multiple_starts() local_unnamed_addr sanitize_hwaddress {
   ret i32 0
 }
 
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: multiple_starts
+
 define dso_local i32 @multiple_starts_noend() local_unnamed_addr sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @multiple_starts_noend(
 ; X86-SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
@@ -2802,6 +2820,8 @@ define dso_local i32 @multiple_starts_noend() local_unnamed_addr sanitize_hwaddr
   ret i32 0
 }
 
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: multiple_starts_noend
+
 define dso_local i32 @double_lifetime() local_unnamed_addr sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @double_lifetime(
 ; X86-SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
@@ -3122,6 +3142,8 @@ define dso_local i32 @double_lifetime() local_unnamed_addr sanitize_hwaddress {
   ret i32 0
 }
 
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: double_lifetime
+
 define dso_local i32 @bad_lifetime() local_unnamed_addr sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @bad_lifetime(
 ; X86-SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
@@ -3443,6 +3465,8 @@ define dso_local i32 @bad_lifetime() local_unnamed_addr sanitize_hwaddress {
   ret i32 0
 }
 
+; REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: bad_lifetime
+
 define dso_local i32 @double_end() local_unnamed_addr sanitize_hwaddress {
 ; X86-SCOPE-LABEL: @double_end(
 ; X86-SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
@@ -3737,6 +3761,7 @@ define dso_local i32 @double_end() local_unnamed_addr sanitize_hwaddress {
   call void @use(ptr nonnull %1) #2
   ret i32 0
 }
+; REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: supportedLifetime{{[[:space:]]}}Function: double_end
 
 declare dso_local i1 @cond(...) local_unnamed_addr
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/183858


More information about the llvm-branch-commits mailing list