[llvm] 712b31e - [NFC] factor isStandardLifetime out of HWASan
Florian Mayer via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 2 13:24:05 PST 2022
Author: Florian Mayer
Date: 2022-02-02T13:23:55-08:00
New Revision: 712b31e2d4dca878f732163783816387760936fc
URL: https://github.com/llvm/llvm-project/commit/712b31e2d4dca878f732163783816387760936fc
DIFF: https://github.com/llvm/llvm-project/commit/712b31e2d4dca878f732163783816387760936fc.diff
LOG: [NFC] factor isStandardLifetime out of HWASan
this is so we can use it for aarch64 stack tagging.
Reviewed By: eugenis
Differential Revision: https://reviews.llvm.org/D118836
Added:
llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h
llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
Modified:
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
llvm/lib/Target/AArch64/AArch64StackTagging.cpp
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
llvm/lib/Transforms/Utils/CMakeLists.txt
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
index 0a5456c5956f9..7858a1c4b2fdf 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
@@ -47,51 +47,6 @@ class InterestingMemoryOperand {
Value *getPtr() { return PtrUse->get(); }
};
-// For an alloca valid between lifetime markers Start and Ends, call the
-// Callback for all possible exits out of the lifetime in the containing
-// function, which can return from the instructions in RetVec.
-//
-// Returns whether Ends covered all possible exits. If they did not,
-// the caller should remove Ends to ensure that work done at the other
-// exits does not happen outside of the lifetime.
-template <typename F>
-bool forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT,
- const Instruction *Start,
- const SmallVectorImpl<IntrinsicInst *> &Ends,
- const SmallVectorImpl<Instruction *> &RetVec,
- F Callback) {
- if (Ends.size() == 1 && PDT.dominates(Ends[0], Start)) {
- Callback(Ends[0]);
- return true;
- }
- SmallVector<Instruction *, 8> ReachableRetVec;
- unsigned NumCoveredExits = 0;
- for (auto *RI : RetVec) {
- if (!isPotentiallyReachable(Start, RI, nullptr, &DT))
- continue;
- ReachableRetVec.push_back(RI);
- // TODO(fmayer): We don't support diamond shapes, where multiple lifetime
- // ends together dominate the RI, but none of them does by itself.
- // Check how often this happens and decide whether to support this here.
- if (std::any_of(Ends.begin(), Ends.end(),
- [&](Instruction *End) { return 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()) {
- for (auto *End : Ends)
- Callback(End);
- } else {
- for (auto *RI : ReachableRetVec)
- Callback(RI);
- // 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;
-}
-
// Get AddressSanitizer parameters.
void getAddressSanitizerParams(const Triple &TargetTriple, int LongSize,
bool IsKasan, uint64_t *ShadowBase,
diff --git a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h
new file mode 100644
index 0000000000000..8168b515099fa
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h
@@ -0,0 +1,73 @@
+//===- MemoryTaggingSupport.h - helpers for memory tagging implementations ===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares common infrastructure for HWAddressSanitizer and
+// Aarch64StackTagging.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TRANSFORMS_UTILS_MEMORYTAGGINGSUPPORT_H
+#define LLVM_TRANSFORMS_UTILS_MEMORYTAGGINGSUPPORT_H
+
+#include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+
+namespace llvm {
+// For an alloca valid between lifetime markers Start and Ends, call the
+// Callback for all possible exits out of the lifetime in the containing
+// function, which can return from the instructions in RetVec.
+//
+// Returns whether Ends covered all possible exits. If they did not,
+// the caller should remove Ends to ensure that work done at the other
+// exits does not happen outside of the lifetime.
+template <typename F>
+bool forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT,
+ const Instruction *Start,
+ const SmallVectorImpl<IntrinsicInst *> &Ends,
+ const SmallVectorImpl<Instruction *> &RetVec,
+ F Callback) {
+ if (Ends.size() == 1 && PDT.dominates(Ends[0], Start)) {
+ Callback(Ends[0]);
+ return true;
+ }
+ SmallVector<Instruction *, 8> ReachableRetVec;
+ unsigned NumCoveredExits = 0;
+ for (auto *RI : RetVec) {
+ if (!isPotentiallyReachable(Start, RI, nullptr, &DT))
+ continue;
+ ReachableRetVec.push_back(RI);
+ // TODO(fmayer): We don't support diamond shapes, where multiple lifetime
+ // ends together dominate the RI, but none of them does by itself.
+ // Check how often this happens and decide whether to support this here.
+ if (std::any_of(Ends.begin(), Ends.end(),
+ [&](Instruction *End) { return 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()) {
+ for (auto *End : Ends)
+ Callback(End);
+ } else {
+ for (auto *RI : ReachableRetVec)
+ Callback(RI);
+ // 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;
+}
+
+bool isStandardLifetime(const SmallVectorImpl<IntrinsicInst *> &LifetimeStart,
+ const SmallVectorImpl<IntrinsicInst *> &LifetimeEnd,
+ const DominatorTree &DT, size_t MaxLifetimes);
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/AArch64/AArch64StackTagging.cpp b/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
index 566c7a16db235..13ae5027dad91 100644
--- a/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
+++ b/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
@@ -52,8 +52,8 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/MemoryTaggingSupport.h"
#include <cassert>
#include <iterator>
#include <utility>
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 7b3741d19a1b2..b664e6a4f9c0e 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -53,6 +53,7 @@
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/MemoryTaggingSupport.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include <sstream>
@@ -301,8 +302,6 @@ 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);
- static bool isStandardLifetime(const AllocaInfo &AllocaInfo,
- const DominatorTree &DT);
bool instrumentStack(
bool ShouldDetectUseAfterScope,
MapVector<AllocaInst *, AllocaInfo> &AllocasToInstrument,
@@ -1330,34 +1329,7 @@ bool HWAddressSanitizer::instrumentLandingPads(
return true;
}
-static bool
-maybeReachableFromEachOther(const SmallVectorImpl<IntrinsicInst *> &Insts,
- const DominatorTree &DT) {
- // If we have too many lifetime ends, give up, as the algorithm below is N^2.
- if (Insts.size() > ClMaxLifetimes)
- return true;
- for (size_t I = 0; I < Insts.size(); ++I) {
- for (size_t J = 0; J < Insts.size(); ++J) {
- if (I == J)
- continue;
- if (isPotentiallyReachable(Insts[I], Insts[J], nullptr, &DT))
- return true;
- }
- }
- return false;
-}
-// static
-bool HWAddressSanitizer::isStandardLifetime(const AllocaInfo &AllocaInfo,
- const DominatorTree &DT) {
- // An alloca that has exactly one start and end in every possible execution.
- // If it has multiple ends, they have to be unreachable from each other, so
- // at most one of them is actually used for each execution of the function.
- return AllocaInfo.LifetimeStart.size() == 1 &&
- (AllocaInfo.LifetimeEnd.size() == 1 ||
- (AllocaInfo.LifetimeEnd.size() > 0 &&
- !maybeReachableFromEachOther(AllocaInfo.LifetimeEnd, DT)));
-}
bool HWAddressSanitizer::instrumentStack(
bool ShouldDetectUseAfterScope,
@@ -1411,7 +1383,9 @@ bool HWAddressSanitizer::instrumentStack(
tagAlloca(IRB, AI, UARTag, AlignedSize);
};
bool StandardLifetime =
- UnrecognizedLifetimes.empty() && isStandardLifetime(Info, GetDT());
+ UnrecognizedLifetimes.empty() &&
+ isStandardLifetime(Info.LifetimeStart, Info.LifetimeEnd, GetDT(),
+ ClMaxLifetimes);
if (ShouldDetectUseAfterScope && StandardLifetime) {
IntrinsicInst *Start = Info.LifetimeStart[0];
IRB.SetInsertPoint(Start->getNextNode());
diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt
index aa14ba9eefe79..ca442d89b9804 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -49,6 +49,7 @@ add_llvm_component_library(LLVMTransformUtils
LowerSwitch.cpp
MatrixUtils.cpp
MemoryOpRemark.cpp
+ MemoryTaggingSupport.cpp
Mem2Reg.cpp
MetaRenamer.cpp
ModuleUtils.cpp
diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
new file mode 100644
index 0000000000000..a2ba28aff9a6b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
@@ -0,0 +1,45 @@
+//== MemoryTaggingSupport.cpp - helpers for memory tagging implementations ===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares common infrastructure for HWAddressSanitizer and
+// Aarch64StackTagging.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/MemoryTaggingSupport.h"
+
+namespace llvm {
+namespace {
+bool maybeReachableFromEachOther(const SmallVectorImpl<IntrinsicInst *> &Insts,
+ const DominatorTree &DT, size_t MaxLifetimes) {
+ // If we have too many lifetime ends, give up, as the algorithm below is N^2.
+ if (Insts.size() > MaxLifetimes)
+ return true;
+ for (size_t I = 0; I < Insts.size(); ++I) {
+ for (size_t J = 0; J < Insts.size(); ++J) {
+ if (I == J)
+ continue;
+ if (isPotentiallyReachable(Insts[I], Insts[J], nullptr, &DT))
+ return true;
+ }
+ }
+ return false;
+}
+} // namespace
+
+bool isStandardLifetime(const SmallVectorImpl<IntrinsicInst *> &LifetimeStart,
+ const SmallVectorImpl<IntrinsicInst *> &LifetimeEnd,
+ const DominatorTree &DT, size_t MaxLifetimes) {
+ // An alloca that has exactly one start and end in every possible execution.
+ // If it has multiple ends, they have to be unreachable from each other, so
+ // at most one of them is actually used for each execution of the function.
+ return LifetimeStart.size() == 1 &&
+ (LifetimeEnd.size() == 1 ||
+ (LifetimeEnd.size() > 0 &&
+ !maybeReachableFromEachOther(LifetimeEnd, DT, MaxLifetimes)));
+}
+} // namespace llvm
More information about the llvm-commits
mailing list