This is an archive of the discontinued LLVM Phabricator instance.

[hwasan] Detect use after scope within function.
ClosedPublic

Authored by fmayer on Jun 30 2021, 8:45 AM.

Diff Detail

Event Timeline

fmayer created this revision.Jun 30 2021, 8:45 AM
fmayer updated this revision to Diff 356727.Jul 6 2021, 8:01 AM

Add lots of tests. Fix logic.

fmayer updated this revision to Diff 356743.Jul 6 2021, 8:41 AM

Fix formatting.

fmayer updated this revision to Diff 356802.Jul 6 2021, 12:26 PM

Fix failing test.

fmayer updated this revision to Diff 356808.Jul 6 2021, 1:14 PM

Fix formatting.

fmayer updated this revision to Diff 356816.Jul 6 2021, 1:43 PM

Formatting.

fmayer updated this revision to Diff 356984.Jul 7 2021, 9:43 AM

Check that use after scope is off by default.

fmayer updated this revision to Diff 357550.Jul 9 2021, 9:54 AM

Rebase.

fmayer published this revision for review.Jul 12 2021, 3:18 AM
fmayer added a reviewer: eugenis.

I built Android with this (+ the stack safety change), and after fixing a bug I found it booted and works fine.

Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJul 12 2021, 3:18 AM
Herald added subscribers: llvm-commits, Restricted Project. · View Herald Transcript

Could you investigate how common multi-region lifetimes are? I.e. how much worse is use-after-scope detection in hwasan compared to asan. You can just dump variable and function names and overall numbers into llvm::errs() and compile something big.

I'm sure I've seen allocas getting merged in IR after inlining, but I can not reproduce it now. I see a comment in lib/Transforms/IPO/Inliner.cpp about it being removed. Maybe we do not need to worry about it.

llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
52 ↗(On Diff #358026)

tagLifetimeEnd is not descriptive enough for namespace llvm. M/b something like ForAllReachableExits? Start and End can be just Instruction *, and RetVec should be const. Instead of erasing End I'd rather return a bool that's true if any callbacks were invoked on any of the RetVec, and caller can remove lifetime.end then.

This refactoring is better done in a separate change.

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
125

Probably should be on by default.

364

DetectUseAfterScope

399–400

why?

471

Please support this in the new pass manager, too.

fmayer updated this revision to Diff 358626.Jul 14 2021, 8:59 AM
fmayer marked 2 inline comments as done.

address some comments

fmayer updated this revision to Diff 358629.Jul 14 2021, 9:03 AM
fmayer marked an inline comment as done.

formatting

llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
52 ↗(On Diff #358026)

This refactoring is better done in a separate change.

Confirming that you mean I should split this change and pull this helper function out before?

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
125

Wouldn't it be prudent to leave it behind a disabled flag until we get some more experience, and then make it opt-out?

399–400

I uploaded a new version of the stack safety change (where I had accidentally introduced this), and then forgot to upload the rebased change.

fmayer updated this revision to Diff 358638.Jul 14 2021, 9:23 AM

test with old and new pass manager.

fmayer updated this revision to Diff 358888.Jul 15 2021, 3:10 AM

accidentally added file

eugenis added inline comments.Jul 15 2021, 2:36 PM
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
52 ↗(On Diff #358026)

yes

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
125

hmm ok lets start with that

vitalybuka added inline comments.Jul 15 2021, 5:51 PM
compiler-rt/test/hwasan/TestCases/stack-uas.c
11

It looks all these test ported version of asan
it would be nice if in a separate patch you commit them as exact copy (with XFAIL: *)

so in D105201 we can see only change you need to make for HWASAN

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
420

do we save anything with this if(shouldDetectUseAfterScope)?

486

same here, if it's cached why do we need to avoid forwarding them even if we don't use them later

1275–1281

only if you wish to that later, but it would be nice to refactor HWAddressSanitizer into module and function classes
so we can have all these arguments as member of function one

1288–1289

Range-based looks better to me

for (auto &KV : AllocasToInstrument) {
  auto *AI = KV.first;

  Value *Tag = getAllocaTag(IRB, StackTag, AI, N++);
1338

can we avoid removing them? it can break other optimizations.
I guess the goal is to avoid them in tagLifetimeEnd, but recalculating them in StandardLifetime there is cheap.

1495
for (auto &KV : AllocasToInstrument) {
  AllocaInst *AI = KV.first;
vitalybuka added inline comments.Jul 15 2021, 6:34 PM
compiler-rt/test/hwasan/TestCases/stack-uas.c
11

Actually compiler-rt should not be in this patch. Ideally two additional patches

  1. D105201 only llvm/
  2. I guess we will add proper clang fronted flag to avoid "-mllvm -hwasan-use-after-scope" ? similar -fsanitize-address-use-after-scope. Doing this before 4 will save one patch to replace them "-mllvm -hwasan-use-after-scope" -> -fsanitize-hwaddress-use-after-scope
  3. Clone compiler-rt tests with XFAIL:*
  4. Update and enable -hwasan-use-after-scope

D105201 changes llvm/lib/Transforms/Instrumentation/, so we need tests in llvm/test/Instrumentation/, similar to AddressSanitizer/lifetime.ll

if you move AArch64StackTagging.cpp into a separate refactoring NFC patch, it does not need new tests

eugenis added inline comments.Jul 15 2021, 7:43 PM
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
1338

We can't. Tagging before/after lifetime is UB - consider that this memory may be reused for another alloca with different tag value.

fmayer updated this revision to Diff 359255.Jul 16 2021, 2:21 AM
fmayer marked 10 inline comments as done.

address comments.

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
1275–1281

Will keep in mind.

1338

Yes, like eugenis said, this is fixing a bug that we would potentially use the alloca outside of its lifetime.

fmayer updated this revision to Diff 359262.Jul 16 2021, 2:42 AM

address comment

llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
52 ↗(On Diff #358026)

Done.

The instructions (except Start) cannot be const because they will eventually end up in the IRBuilder constructor (which does not take a const).

fmayer added inline comments.Jul 16 2021, 8:10 AM
compiler-rt/test/hwasan/TestCases/stack-uas.c
11

Ad 2. I will let eugenis comment on that, but to me it seems a lot of the HWAsan feature flags are passed via -mllvm without any intention to make them first-class clang options. Especially given we want to make this the default soon (see the other comment thread between eugenis and me).

fmayer updated this revision to Diff 359343.Jul 16 2021, 9:05 AM

remove unneded test.

eugenis added inline comments.Jul 16 2021, 9:33 AM
compiler-rt/test/hwasan/TestCases/stack-uas.c
11

Let's look at performance and code size impact first, but I'd like that to just be on all the time, and the -mllvm option can be used to opt out if something goes wrong.

Note that memtag does not have a frontend flag for use-after-scope, either.

fmayer added inline comments.Jul 16 2021, 9:36 AM
compiler-rt/test/hwasan/TestCases/stack-uas.c
11

So is it okay to leave as is? I'll add an LLVM IR level test as well to this change.

eugenis added inline comments.Jul 16 2021, 9:44 AM
compiler-rt/test/hwasan/TestCases/stack-uas.c
11

Yes. I'd rather not introduce a clang flag unless we know that there will be users who would want it both ways. We can not easily deprecate clang flags.

fmayer added inline comments.Jul 16 2021, 10:21 AM
compiler-rt/test/hwasan/TestCases/use-after-scope-types.cpp
24

i'll sort out the autoformatting diff.

vitalybuka added inline comments.Jul 16 2021, 12:53 PM
compiler-rt/test/hwasan/TestCases/stack-uas.c
11

Yes. I'd rather not introduce a clang flag unless we know that there will be users who would want it both ways. We can not easily deprecate clang flags.

OK

So is it okay to leave as is? I'll add an LLVM IR level test as well to this change.

OK

compiler-rt/test/hwasan/TestCases/use-after-scope-types.cpp
24

That's would be great after D106159 and before this one

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
1294

Probably not important but now it's starts with N==1

1319

I guess asan handles multiple starts/ends?

1331

{} unneeded

1476

why we need these empty Trees?

fmayer updated this revision to Diff 359827.Jul 19 2021, 9:51 AM
fmayer marked an inline comment as done.

fix debug info.

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
1294

Actually this was broken when I changed to the range-based for, sorry about that. Fixed now.

vitalybuka added inline comments.Jul 19 2021, 11:33 AM
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
238

Someone added "#ifdef GNUC" above.

To much effort for this simple check. If it needs #ifdef then I'd rather remove pragma GCC poison at all. (in a separate patch)

fmayer updated this revision to Diff 360748.Jul 22 2021, 3:01 AM
fmayer marked 7 inline comments as done.

style nit

fmayer updated this revision to Diff 360749.Jul 22 2021, 3:01 AM
fmayer marked 2 inline comments as done.

remove pragma poison

Harbormaster completed remote builds in B115525: Diff 360749.
fmayer added inline comments.Jul 22 2021, 3:02 AM
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
1476

They aren't empty, they are constructed from the function.

We need the unique_ptrs because sometimes we borrow the LocalDT from the passmanager, and sometimes we construct it ourselves, in which case we need to destruct it again.

I assume we still wait for IR tests?

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
1475

Code around mostly uses if (!LocalDT) { style

1476

I think it's very unusuall, you should get if from pass manager with getAnalysis<DominatorTreeWrapperPass>()
and addRequired or getResult<DominatorTreeAnalysis>
@eugenis ?

Yes a couple an IR test would be great. It does not need to cover the analysis logic, that is done separately, just the fact that a "safe" alloca is not tagged.

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
1476

This is a copy of the code from AArch64StackTagging. The idea is to implement on-demand function analysis in the old pass manager so that, in the common case when none of the functions in a module have a sanitize_* attribute, the analysis is not run.

We get the analysis from the passmanager if it is available, otherwise we run one locally and then destroy it with unique_ptr.

maybe this lazy Tree construction?

maybe this lazy Tree construction?

This change doesn't preserve the property that Evgenii mentioned in the comment thread about this. In Aarch64StackTagging this is done in the way it was in this change before to avoid running the analysis on the whole module if not all of the functions actually need to be instrumented. In general I think it would be nice to have the AArch64StackTagging and this implementation as close as possible, that makes it easier to reason about and I am planning to refactor this a bit to factor out the common pieces down the line.

I assume we still wait for IR tests?

I have an IR test ready, but don't want to stomp over your change or have to rebase back and forth while we decide which way we want the DT and PDT analyses :)

vitalybuka added a comment.EditedJul 23 2021, 10:37 AM

maybe this lazy Tree construction?

This change doesn't preserve the property that Evgenii mentioned in the comment thread about this. In Aarch64StackTagging this is done in the way it was in this change before to avoid running the analysis on the whole module if not all of the functions actually need to be instrumented. In general I think it would be nice to have the AArch64StackTagging and this implementation as close as possible, that makes it easier to reason about and I am planning to refactor this a bit to factor out the common pieces down the line.

Reasons not to optimize:

  1. AArch64StackTagging is different. AArch64StackTagging is added always for aarch64, so it can compile modules where almost all functions have no attribute. However HWAddressSanitizerLegacyPass one added only for stuff compiler with -fsanitizer=hwaddres, so almost everything will have this attribute.
  1. For new PM llvm::function does exactly as you like and even better, it will avoid DT for empty AllocasToInstrument, and legacy PM is deprecated and will be removed.

If you still want optimize even legacy PM:
This stuff is Pass specific, but HWAddressSanitizer class is not a pass, it's a tool used by Pass, so it's more reasonable to have this optimization inside of HWAddressSanitizerLegacyPass.
E.g.:

bool runOnFunction(Function &F) override {
    auto TargetTriple = Triple(F.getParent()->getTargetTriple());
    if (shouldUseStackSafetyAnalysis(TargetTriple, DisableOptimization)) {
      // We cannot call getAnalysis in doInitialization, that would cause a
      // crash as the required analyses are not initialized yet.
      HWASan->setSSI(
          &getAnalysis<StackSafetyGlobalInfoWrapperPass>().getResult());
    }
    std::unique_ptr<DominatorTree> DeleteDT;
    std::unique_ptr<PostDominatorTree> DeletePDT;
    return HWASan->sanitizeFunction(
        F,
        [&]() -> const DominatorTree & {
          if (auto *P = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
            return P->getDomTree();
          if (!DeleteDT)
            DeleteDT = std::make_unique<DominatorTree>(F);
          return *DeleteDT;
        },
        [&]() -> const PostDominatorTree & {
          if (auto *P = getAnalysisIfAvailable<PostDominatorTreeWrapperPass>())
            return P->getPostDomTree();
          if (!DeletePDT)
            DeletePDT = std::make_unique<PostDominatorTree>(F);
          return *DeletePDT;
        });
  }

# AU.addRequired<>() -> AU.addUsedIfAvailable<>();
# And you need to keep INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) either way

maybe this lazy Tree construction?

This change doesn't preserve the property that Evgenii mentioned in the comment thread about this. In Aarch64StackTagging this is done in the way it was in this change before to avoid running the analysis on the whole module if not all of the functions actually need to be instrumented. In general I think it would be nice to have the AArch64StackTagging and this implementation as close as possible, that makes it easier to reason about and I am planning to refactor this a bit to factor out the common pieces down the line.

Reasons not to optimize:

  1. AArch64StackTagging is different. AArch64StackTagging is added always for aarch64, so it can compile modules where almost all functions have no attribute. However HWAddressSanitizerLegacyPass one added only for stuff compiler with -fsanitizer=hwaddres, so almost everything will have this attribute.
  1. For new PM llvm::function does exactly as you like and even better, it will avoid DT for empty AllocasToInstrument, and legacy PM is deprecated and will be removed.

If you still want optimize even legacy PM:
This stuff is Pass specific, but HWAddressSanitizer class is not a pass, it's a tool used by Pass, so it's more reasonable to have this optimization inside of HWAddressSanitizerLegacyPass.
E.g.:

bool runOnFunction(Function &F) override {
    auto TargetTriple = Triple(F.getParent()->getTargetTriple());
    if (shouldUseStackSafetyAnalysis(TargetTriple, DisableOptimization)) {
      // We cannot call getAnalysis in doInitialization, that would cause a
      // crash as the required analyses are not initialized yet.
      HWASan->setSSI(
          &getAnalysis<StackSafetyGlobalInfoWrapperPass>().getResult());
    }
    std::unique_ptr<DominatorTree> DeleteDT;
    std::unique_ptr<PostDominatorTree> DeletePDT;
    return HWASan->sanitizeFunction(
        F,
        [&]() -> const DominatorTree & {
          if (auto *P = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
            return P->getDomTree();
          if (!DeleteDT)
            DeleteDT = std::make_unique<DominatorTree>(F);
          return *DeleteDT;
        },
        [&]() -> const PostDominatorTree & {
          if (auto *P = getAnalysisIfAvailable<PostDominatorTreeWrapperPass>())
            return P->getPostDomTree();
          if (!DeletePDT)
            DeletePDT = std::make_unique<PostDominatorTree>(F);
          return *DeletePDT;
        });
  }

# AU.addRequired<>() -> AU.addUsedIfAvailable<>();
# And you need to keep INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) either way

Makes sense, thanks a lot for the explanation :)

  1. AArch64StackTagging is different. AArch64StackTagging is added always for aarch64, so it can compile modules where almost all functions have no attribute.

However HWAddressSanitizerLegacyPass one added only for stuff compiler with -fsanitizer=hwaddres, so almost everything will have this attribute.

True. I don't really like this setup, it's not very compatible with LTO, but that's what we have and changing it is low priority.

I'm fine either way.

fmayer updated this revision to Diff 361950.Jul 27 2021, 2:25 AM

add llvm ir test

vitalybuka accepted this revision.Jul 27 2021, 11:23 AM

LGTM if you improve the test

llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll
9 ↗(On Diff #361950)

this tests StandardLifetime && forAllReachableExits
but it would be nice to have these cases:
StandardLifetime && !forAllReachableExits
!StandardLifetime

also depending on conditions above we may keep or remove lifetime markers.
So we need to test
could you please add corresponding CHECKs here?

to my taste the following produces good enough result, but I don't ask to switch to auto-generated tests. It's your call.
llvm/utils/update_test_checks.py --opt-binary <build_dir>/bin/opt llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope.ll

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -hwasan -hwasan-use-after-scope=1 -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=SCOPE
; RUN: opt -hwasan -hwasan-use-after-scope=0 -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=NOSCOPE

; ModuleID = 'use-after-scope.c'
source_filename = "use-after-scope.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define dso_local i32 @main() local_unnamed_addr sanitize_hwaddress {
; SCOPE-LABEL: @main(
; SCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call i8* asm "", "=r,0"(i8* null)
; SCOPE-NEXT:    [[TMP1:%.*]] = alloca { i8, [15 x i8] }, align 16
; SCOPE-NEXT:    [[TMP2:%.*]] = bitcast { i8, [15 x i8] }* [[TMP1]] to i8*
; SCOPE-NEXT:    [[TMP3:%.*]] = call i8 @__hwasan_generate_tag()
; SCOPE-NEXT:    [[TMP4:%.*]] = zext i8 [[TMP3]] to i64
; SCOPE-NEXT:    [[TMP5:%.*]] = ptrtoint i8* [[TMP2]] to i64
; SCOPE-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP4]], 57
; SCOPE-NEXT:    [[TMP7:%.*]] = or i64 [[TMP5]], [[TMP6]]
; SCOPE-NEXT:    [[ALLOCA_0_HWASAN:%.*]] = inttoptr i64 [[TMP7]] to i8*
; SCOPE-NEXT:    br label [[TMP8:%.*]]
; SCOPE:       8:
; SCOPE-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[ALLOCA_0_HWASAN]])
; SCOPE-NEXT:    [[TMP9:%.*]] = trunc i64 [[TMP4]] to i8
; SCOPE-NEXT:    call void @__hwasan_tag_memory(i8* [[TMP2]], i8 [[TMP9]], i64 16)
; SCOPE-NEXT:    [[TMP10:%.*]] = tail call i32 (...) @cond()
; SCOPE-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0
; SCOPE-NEXT:    call void @__hwasan_tag_memory(i8* [[TMP2]], i8 0, i64 16)
; SCOPE-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[ALLOCA_0_HWASAN]])
; SCOPE-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP8]]
; SCOPE:       12:
; SCOPE-NEXT:    call void @use(i8* nonnull [[ALLOCA_0_HWASAN]])
; SCOPE-NEXT:    ret i32 0
;
; NOSCOPE-LABEL: @main(
; NOSCOPE-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call i8* asm "", "=r,0"(i8* null)
; NOSCOPE-NEXT:    [[TMP1:%.*]] = alloca { i8, [15 x i8] }, align 16
; NOSCOPE-NEXT:    [[TMP2:%.*]] = bitcast { i8, [15 x i8] }* [[TMP1]] to i8*
; NOSCOPE-NEXT:    [[TMP3:%.*]] = call i8 @__hwasan_generate_tag()
; NOSCOPE-NEXT:    [[TMP4:%.*]] = zext i8 [[TMP3]] to i64
; NOSCOPE-NEXT:    [[TMP5:%.*]] = ptrtoint i8* [[TMP2]] to i64
; NOSCOPE-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP4]], 57
; NOSCOPE-NEXT:    [[TMP7:%.*]] = or i64 [[TMP5]], [[TMP6]]
; NOSCOPE-NEXT:    [[ALLOCA_0_HWASAN:%.*]] = inttoptr i64 [[TMP7]] to i8*
; NOSCOPE-NEXT:    [[TMP8:%.*]] = trunc i64 [[TMP4]] to i8
; NOSCOPE-NEXT:    call void @__hwasan_tag_memory(i8* [[TMP2]], i8 [[TMP8]], i64 16)
; NOSCOPE-NEXT:    br label [[TMP9:%.*]]
; NOSCOPE:       9:
; NOSCOPE-NEXT:    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[ALLOCA_0_HWASAN]])
; NOSCOPE-NEXT:    [[TMP10:%.*]] = tail call i32 (...) @cond()
; NOSCOPE-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0
; NOSCOPE-NEXT:    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[ALLOCA_0_HWASAN]])
; NOSCOPE-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP9]]
; NOSCOPE:       12:
; NOSCOPE-NEXT:    call void @use(i8* nonnull [[ALLOCA_0_HWASAN]])
; NOSCOPE-NEXT:    call void @__hwasan_tag_memory(i8* [[TMP2]], i8 0, i64 16)
; NOSCOPE-NEXT:    ret i32 0
;
  %1 = alloca i8, align 1
  br label %2

2:                                                ; preds = %2, %0
; We should tag the memory after the br (in the loop).
  call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %1)
  %3 = tail call i32 (...) @cond() #2
  %4 = icmp eq i32 %3, 0
; We should tag the memory before the next br (before the jump back).
  call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %1)
  br i1 %4, label %5, label %2

5:                                                ; preds = %2
  call void @use(i8* nonnull %1) #2
  ret i32 0
}

declare dso_local i32 @cond(...) local_unnamed_addr

declare dso_local void @use(i8*) local_unnamed_addr

; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)

; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
44 ↗(On Diff #361950)

please add new line

This revision is now accepted and ready to land.Jul 27 2021, 11:23 AM
fmayer updated this revision to Diff 362799.Jul 29 2021, 9:00 AM
fmayer marked 2 inline comments as done.

add more IR tests

fmayer marked 4 inline comments as done.Jul 29 2021, 9:48 AM
fmayer added inline comments.
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
1319

this is based on the MTE stack tagging code.

fmayer updated this revision to Diff 362821.Jul 29 2021, 10:39 AM
fmayer marked an inline comment as done.

remove comment

vitalybuka accepted this revision.Jul 29 2021, 4:44 PM

Thanks

This revision was automatically updated to reflect the committed changes.
fmayer reopened this revision.Aug 2 2021, 1:01 AM
This revision is now accepted and ready to land.Aug 2 2021, 1:01 AM
fmayer updated this revision to Diff 363390.Aug 2 2021, 1:01 AM

require stable runtime

fmayer added a comment.Aug 2 2021, 3:28 AM

Relanding without review as the only change is a minor test only change (adding REQUIRES: stable-runtime as with other tests in the directory).

This revision was automatically updated to reflect the committed changes.