[llvm] r374182 - [AArch64] Ensure no tagged memory is left in the unallocated portion of the

Momchil Velikov via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 9 09:31:50 PDT 2019


Author: chill
Date: Wed Oct  9 09:31:50 2019
New Revision: 374182

URL: http://llvm.org/viewvc/llvm-project?rev=374182&view=rev
Log:
[AArch64] Ensure no tagged memory is left in the unallocated portion of the
stack

This patch makes sure that if we tag some memory, we untag that memory before
the function returns/throws via any exit, reachable from the tag operation. For
that we place the untag operation either at:

  a) the lifetime end call for the alloca, if that call post-dominates the
     lifetime start call (where the tag operation is placed), or it (the
     lifetime end call) dominates all reachable exits, otherwise
  b) at the reachable exits

Differential Revision: https://reviews.llvm.org/D68469

Added:
    llvm/trunk/test/CodeGen/AArch64/stack-tagging-ex-1.ll
    llvm/trunk/test/CodeGen/AArch64/stack-tagging-ex-2.ll
    llvm/trunk/test/CodeGen/AArch64/stack-tagging-untag-placement.ll
Modified:
    llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp

Modified: llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp?rev=374182&r1=374181&r2=374182&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp Wed Oct  9 09:31:50 2019
@@ -19,6 +19,7 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/CFG.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/ScalarEvolution.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
@@ -491,6 +492,24 @@ void AArch64StackTagging::alignAndPadAll
   Info.AI = NewAI;
 }
 
+// Helper function to check for post-dominance.
+static bool postDominates(const PostDominatorTree *PDT, const IntrinsicInst *A,
+                          const IntrinsicInst *B) {
+  const BasicBlock *ABB = A->getParent();
+  const BasicBlock *BBB = B->getParent();
+
+  if (ABB != BBB)
+    return PDT->dominates(ABB, BBB);
+
+  for (const Instruction &I : *ABB) {
+    if (&I == B)
+      return true;
+    if (&I == A)
+      return false;
+  }
+  llvm_unreachable("Corrupt instruction list");
+}
+
 // FIXME: check for MTE extension
 bool AArch64StackTagging::runOnFunction(Function &Fn) {
   if (!Fn.hasFnAttribute(Attribute::SanitizeMemTag))
@@ -565,23 +584,31 @@ bool AArch64StackTagging::runOnFunction(
   if (NumInterestingAllocas == 0)
     return true;
 
+  std::unique_ptr<DominatorTree> DeleteDT;
+  DominatorTree *DT = nullptr;
+  if (auto *P = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
+    DT = &P->getDomTree();
+
+  if (DT == nullptr && (NumInterestingAllocas > 1 ||
+                        !F->hasFnAttribute(Attribute::OptimizeNone))) {
+    DeleteDT = std::make_unique<DominatorTree>(*F);
+    DT = DeleteDT.get();
+  }
+
+  std::unique_ptr<PostDominatorTree> DeletePDT;
+  PostDominatorTree *PDT = nullptr;
+  if (auto *P = getAnalysisIfAvailable<PostDominatorTreeWrapperPass>())
+    PDT = &P->getPostDomTree();
+
+  if (PDT == nullptr && !F->hasFnAttribute(Attribute::OptimizeNone)) {
+    DeletePDT = std::make_unique<PostDominatorTree>(*F);
+    PDT = DeletePDT.get();
+  }
+
   SetTagFunc =
       Intrinsic::getDeclaration(F->getParent(), Intrinsic::aarch64_settag);
 
-  // Compute DT only if the function has the attribute, there are more than 1
-  // interesting allocas, and it is not available for free.
-  Instruction *Base;
-  if (NumInterestingAllocas > 1) {
-    auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
-    if (DTWP) {
-      Base = insertBaseTaggedPointer(Allocas, &DTWP->getDomTree());
-    } else {
-      DominatorTree DT(*F);
-      Base = insertBaseTaggedPointer(Allocas, &DT);
-    }
-  } else {
-    Base = insertBaseTaggedPointer(Allocas, nullptr);
-  }
+  Instruction *Base = insertBaseTaggedPointer(Allocas, DT);
 
   for (auto &I : Allocas) {
     const AllocaInfo &Info = I.second;
@@ -604,11 +631,37 @@ bool AArch64StackTagging::runOnFunction(
     if (UnrecognizedLifetimes.empty() && Info.LifetimeStart.size() == 1 &&
         Info.LifetimeEnd.size() == 1) {
       IntrinsicInst *Start = Info.LifetimeStart[0];
+      IntrinsicInst *End = Info.LifetimeEnd[0];
       uint64_t Size =
           dyn_cast<ConstantInt>(Start->getArgOperand(0))->getZExtValue();
       Size = alignTo(Size, kTagGranuleSize);
       tagAlloca(AI, Start->getNextNode(), Start->getArgOperand(1), Size);
-      untagAlloca(AI, Info.LifetimeEnd[0], Size);
+      // We need to ensure that if we tag some object, we certainly untag it
+      // before the function exits.
+      if (PDT != nullptr && postDominates(PDT, End, Start)) {
+        untagAlloca(AI, End, Size);
+      } else {
+        SmallVector<Instruction *, 8> ReachableRetVec;
+        unsigned NumCoveredExits = 0;
+        for (auto &RI : RetVec) {
+          if (!isPotentiallyReachable(Start, RI, nullptr, DT))
+            continue;
+          ReachableRetVec.push_back(RI);
+          if (DT != nullptr && DT->dominates(End, RI))
+            ++NumCoveredExits;
+        }
+        // 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.
+        if (NumCoveredExits == ReachableRetVec.size()) {
+          untagAlloca(AI, End, Size);
+        } else {
+          for (auto &RI : ReachableRetVec)
+            untagAlloca(AI, RI, Size);
+          // We may have inserted untag outside of the lifetime interval.
+          // Remove the lifetime end call for this alloca.
+          End->eraseFromParent();
+        }
+      }
     } else {
       uint64_t Size = Info.AI->getAllocationSizeInBits(*DL).getValue() / 8;
       Value *Ptr = IRB.CreatePointerCast(TagPCall, IRB.getInt8PtrTy());

Added: llvm/trunk/test/CodeGen/AArch64/stack-tagging-ex-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/stack-tagging-ex-1.ll?rev=374182&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/stack-tagging-ex-1.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/stack-tagging-ex-1.ll Wed Oct  9 09:31:50 2019
@@ -0,0 +1,69 @@
+; RUN: opt -S -stack-tagging %s -o - | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-arm-unknown-eabi"
+
+define  void @f() local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+start:
+; CHECK-LABEL: start:
+  %a = alloca i8, i32 48, align 8
+  call void @llvm.lifetime.start.p0i8(i64 48, i8* nonnull %a) #2
+; CHECK: call void @llvm.aarch64.settag(i8* %a.tag, i64 48)
+  %b = alloca i8, i32 48, align 8
+  call void @llvm.lifetime.start.p0i8(i64 48, i8* nonnull %b) #2
+; CHECK: call void @llvm.aarch64.settag(i8* %b.tag, i64 48)
+  invoke void @g (i8 * nonnull %a, i8 * nonnull %b) to label %next0 unwind label %lpad0
+; CHECK-NOT: settag
+
+next0:
+; CHECK-LABEL: next0:
+  call void @llvm.lifetime.end.p0i8(i64 40, i8* nonnull %a)
+  call void @llvm.lifetime.end.p0i8(i64 40, i8* nonnull %b)
+  br label %exit
+; CHECK-NOT: settag
+
+lpad0:
+; CHECK-LABEL: lpad0:
+  %pad0v = landingpad { i8*, i32 } catch i8* null
+  %v = extractvalue { i8*, i32 } %pad0v, 0
+  %x = call i8* @__cxa_begin_catch(i8* %v) #2
+  invoke void @__cxa_end_catch() to label %next1 unwind label %lpad1
+; CHECK-NOT: settag
+
+next1:
+; CHECK-LABEL: next1:
+  br label %exit
+; CHECK-NOT: settag
+
+lpad1:
+; CHECK-LABEL: lpad1:
+; CHECK-DAG: call void @llvm.aarch64.settag(i8* %a, i64 48)
+; CHECK-DAG: call void @llvm.aarch64.settag(i8* %b, i64 48)
+  %pad1v = landingpad { i8*, i32 } cleanup
+  resume { i8*, i32 } %pad1v
+
+exit:
+; CHECK-LABEL: exit:
+; CHECK-DAG: call void @llvm.aarch64.settag(i8* %a, i64 48)
+; CHECK-DAG: call void @llvm.aarch64.settag(i8* %b, i64 48)
+  ret void
+; CHECK: ret void
+}
+
+declare void @g(i8 *, i8 *) #0
+
+declare dso_local i32 @__gxx_personality_v0(...)
+
+declare dso_local i8* @__cxa_begin_catch(i8*) local_unnamed_addr
+
+declare dso_local void @__cxa_end_catch() local_unnamed_addr
+
+; Function Attrs: argmemonly nounwind willreturn
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1
+
+; Function Attrs: argmemonly nounwind willreturn
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1
+
+attributes #0 = { sanitize_memtag "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+mte,+neon,+v8.5a" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { argmemonly nounwind willreturn }
+attributes #2 = { nounwind }

Added: llvm/trunk/test/CodeGen/AArch64/stack-tagging-ex-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/stack-tagging-ex-2.ll?rev=374182&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/stack-tagging-ex-2.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/stack-tagging-ex-2.ll Wed Oct  9 09:31:50 2019
@@ -0,0 +1,183 @@
+; clang -target aarch64-eabi -O2 -march=armv8.5-a+memtag -fsanitize=memtag -S -emit-llvm test.cc
+; void bar() {
+;   throw 42;
+; }
+
+; void foo() {
+;   int A0;
+;   __asm volatile("" : : "r"(&A0));
+
+;   try {
+;     bar();
+;   } catch (int exc) {
+;   }
+
+;   throw 15532;
+; }
+
+; int main() {
+;   try {
+;     foo();
+;   } catch (int exc) {
+;   }
+
+;   return 0;
+; }
+
+; RUN: opt -S -stack-tagging %s -o - | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-unknown-eabi"
+
+ at _ZTIi = external dso_local constant i8*
+
+; Function Attrs: noreturn sanitize_memtag
+define dso_local void @_Z3barv() local_unnamed_addr #0 {
+entry:
+  %exception = tail call i8* @__cxa_allocate_exception(i64 4) #4
+  %0 = bitcast i8* %exception to i32*
+  store i32 42, i32* %0, align 16, !tbaa !2
+  tail call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #5
+  unreachable
+}
+
+declare dso_local i8* @__cxa_allocate_exception(i64) local_unnamed_addr
+
+declare dso_local void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr
+
+; Function Attrs: noreturn sanitize_memtag
+define dso_local void @_Z3foov() local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+entry:
+  %A0 = alloca i32, align 4
+  %0 = bitcast i32* %A0 to i8*
+  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #4
+  call void asm sideeffect "", "r"(i32* nonnull %A0) #4, !srcloc !6
+  invoke void @_Z3barv()
+          to label %try.cont unwind label %lpad
+
+lpad:                                             ; preds = %entry
+  %1 = landingpad { i8*, i32 }
+          cleanup
+          catch i8* bitcast (i8** @_ZTIi to i8*)
+  %2 = extractvalue { i8*, i32 } %1, 1
+  %3 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #4
+  %matches = icmp eq i32 %2, %3
+  br i1 %matches, label %catch, label %ehcleanup
+
+catch:                                            ; preds = %lpad
+  %4 = extractvalue { i8*, i32 } %1, 0
+  %5 = call i8* @__cxa_begin_catch(i8* %4) #4
+  call void @__cxa_end_catch() #4
+  br label %try.cont
+
+try.cont:                                         ; preds = %entry, %catch
+  %exception = call i8* @__cxa_allocate_exception(i64 4) #4
+  %6 = bitcast i8* %exception to i32*
+  store i32 15532, i32* %6, align 16, !tbaa !2
+  call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #5
+  unreachable
+
+ehcleanup:                                        ; preds = %lpad
+  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #4
+  resume { i8*, i32 } %1
+}
+
+; Function Attrs: argmemonly nounwind willreturn
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1
+
+declare dso_local i32 @__gxx_personality_v0(...)
+
+; Function Attrs: nounwind readnone
+declare i32 @llvm.eh.typeid.for(i8*) #2
+
+declare dso_local i8* @__cxa_begin_catch(i8*) local_unnamed_addr
+
+declare dso_local void @__cxa_end_catch() local_unnamed_addr
+
+; Function Attrs: argmemonly nounwind willreturn
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1
+
+; Function Attrs: norecurse sanitize_memtag
+define dso_local i32 @main() local_unnamed_addr #3 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+entry:
+; CHECK-LABEL: entry:
+  %A0.i = alloca i32, align 4
+  %0 = bitcast i32* %A0.i to i8*
+  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #4
+  call void asm sideeffect "", "r"(i32* nonnull %A0.i) #4, !srcloc !6
+; CHECK: call void @llvm.aarch64.settag(i8* %1, i64 16)
+; CHECK-NEXT: call void asm sideeffect
+  %exception.i6 = call i8* @__cxa_allocate_exception(i64 4) #4
+  %1 = bitcast i8* %exception.i6 to i32*
+  store i32 42, i32* %1, align 16, !tbaa !2
+  invoke void @__cxa_throw(i8* %exception.i6, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #5
+          to label %.noexc7 unwind label %lpad.i
+
+.noexc7:                                          ; preds = %entry
+  unreachable
+
+lpad.i:                                           ; preds = %entry
+  %2 = landingpad { i8*, i32 }
+          cleanup
+          catch i8* bitcast (i8** @_ZTIi to i8*)
+  %3 = extractvalue { i8*, i32 } %2, 1
+  %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #4
+  %matches.i = icmp eq i32 %3, %4
+  br i1 %matches.i, label %catch.i, label %ehcleanup.i
+
+catch.i:                                          ; preds = %lpad.i
+  %5 = extractvalue { i8*, i32 } %2, 0
+  %6 = call i8* @__cxa_begin_catch(i8* %5) #4
+  call void @__cxa_end_catch() #4
+  %exception.i = call i8* @__cxa_allocate_exception(i64 4) #4
+  %7 = bitcast i8* %exception.i to i32*
+  store i32 15532, i32* %7, align 16, !tbaa !2
+  invoke void @__cxa_throw(i8* %exception.i, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #5
+          to label %.noexc unwind label %lpad
+
+.noexc:                                           ; preds = %catch.i
+  unreachable
+
+ehcleanup.i:                                      ; preds = %lpad.i
+  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #4
+  br label %lpad.body
+
+lpad:                                             ; preds = %catch.i
+  %8 = landingpad { i8*, i32 }
+          catch i8* bitcast (i8** @_ZTIi to i8*)
+  %.pre = extractvalue { i8*, i32 } %8, 1
+  br label %lpad.body
+
+lpad.body:                                        ; preds = %ehcleanup.i, %lpad
+  %.pre-phi = phi i32 [ %3, %ehcleanup.i ], [ %.pre, %lpad ]
+  %eh.lpad-body = phi { i8*, i32 } [ %2, %ehcleanup.i ], [ %8, %lpad ]
+  %matches = icmp eq i32 %.pre-phi, %4
+  br i1 %matches, label %catch, label %eh.resume
+
+catch:                                            ; preds = %lpad.body
+  %9 = extractvalue { i8*, i32 } %eh.lpad-body, 0
+  %10 = call i8* @__cxa_begin_catch(i8* %9) #4
+  call void @__cxa_end_catch() #4
+  ret i32 0
+
+eh.resume:                                        ; preds = %lpad.body
+  resume { i8*, i32 } %eh.lpad-body
+}
+
+attributes #0 = { noreturn sanitize_memtag "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+mte,+neon,+v8.5a" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { argmemonly nounwind willreturn }
+attributes #2 = { nounwind readnone }
+attributes #3 = { norecurse sanitize_memtag "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+mte,+neon,+v8.5a" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #4 = { nounwind }
+attributes #5 = { noreturn }
+
+!llvm.module.flags = !{!0}
+!llvm.ident = !{!1}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git c38188c5fe41751fda095edde1a878b2a051ae58)"}
+!2 = !{!3, !3, i64 0}
+!3 = !{!"int", !4, i64 0}
+!4 = !{!"omnipotent char", !5, i64 0}
+!5 = !{!"Simple C++ TBAA"}
+!6 = !{i32 70}

Added: llvm/trunk/test/CodeGen/AArch64/stack-tagging-untag-placement.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/stack-tagging-untag-placement.ll?rev=374182&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/stack-tagging-untag-placement.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/stack-tagging-untag-placement.ll Wed Oct  9 09:31:50 2019
@@ -0,0 +1,82 @@
+;; RUN:  opt -S -stack-tagging %s -o - | FileCheck %s
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-arm-unknown-eabi"
+
+define void @f() local_unnamed_addr #0  {
+S0:
+; CHECK-LABEL: S0:
+; CHECK: %basetag = call i8* @llvm.aarch64.irg.sp(i64 0)
+  %v = alloca i8, i32 48, align 8
+; CHECK: %v.tag = call i8* @llvm.aarch64.tagp.p0i8(i8* %v, i8* %basetag, i64 0)
+  %w = alloca i8, i32 48, align 16
+; CHECK: %w.tag = call i8* @llvm.aarch64.tagp.p0i8(i8* %w, i8* %basetag, i64 1)
+
+  %t0 = call i32 @g0() #1
+  %b0 = icmp eq i32 %t0, 0
+  br i1 %b0, label %S1, label %exit3
+
+S1:
+; CHECK-LABEL: S1:
+  call void @llvm.lifetime.start.p0i8(i64 48, i8 * nonnull %v) #1
+; CHECK: call void @llvm.aarch64.settag(i8* %v.tag, i64 48)
+  call void @llvm.lifetime.start.p0i8(i64 48, i8 * nonnull %w) #1
+; CHECK: call void @llvm.aarch64.settag(i8* %w.tag, i64 48)
+  %t1 = call i32 @g1(i8 * nonnull %v, i8 * nonnull %w) #1
+; CHECK: call i32 @g1
+; CHECK-NOT: settag{{.*}}%v
+; CHECK: call void @llvm.aarch64.settag(i8* %w, i64 48)
+; CHECK-NOT: settag{{.*}}%v
+  call void @llvm.lifetime.end.p0i8(i64 48, i8 * nonnull %w) #1
+; CHECK: call void @llvm.lifetime.end.p0i8(i64 48, i8* nonnull %w.tag)
+  %b1 = icmp eq i32 %t1, 0
+  br i1 %b1, label %S2, label %S3
+; CHECK-NOT: settag
+
+S2:
+; CHECK-LABEL: S2:
+  call void @z0() #1
+  br label %exit1
+; CHECK-NOT: settag
+
+S3:
+; CHECK-LABEL: S3:
+  call void @llvm.lifetime.end.p0i8(i64 48, i8 * nonnull %v) #1
+  tail call void @z1() #1
+  br label %exit2
+; CHECK-NOT: settag
+
+exit1:
+; CHECK-LABEL: exit1:
+; CHECK: call void @llvm.aarch64.settag(i8* %v, i64 48)
+  ret void
+
+exit2:
+; CHECK-LABEL: exit2:
+; CHECK: call void @llvm.aarch64.settag(i8* %v, i64 48)
+  ret void
+
+exit3:
+; CHECK-LABEL: exit3:
+  call void @z2() #1
+; CHECK-NOT: settag
+  ret void
+; CHECK:  ret void
+}
+
+declare i32 @g0() #0
+
+declare i32 @g1(i8 *, i8 *) #0
+
+declare void @z0() #0
+
+declare void @z1() #0
+
+declare void @z2() #0
+
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8 * nocapture) #1
+
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8 * nocapture) #1
+
+attributes #0 = { sanitize_memtag "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+mte,+neon,+v8.5a" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind }
+




More information about the llvm-commits mailing list