This is an archive of the discontinued LLVM Phabricator instance.

[CodeGen][Asan] Emit lifetime intrinsic for bypassed label
AbandonedPublic

Authored by StephenFan on Jul 10 2022, 9:56 AM.

Details

Summary

Fix https://github.com/llvm/llvm-project/issues/56356
For following test case:

extern int bar(char *A, int n);
void goto_bypass(void) {
  {
    char x;
  l1:
    bar(&x, 1);
  }
  goto l1;
}

And using clang -cc1 -O2 -S -emit-llvm to compile it.

In the past, due to the existence of bypassed label, the lifetime
intrinsic would not be generated. This was also the cause of pr56356.
In this patch, if the variable is bypassed, we do variable
allocation, emit lifetime-start intrinsic and record the lifetime-start
intrinsic in LexicalScope. Then When emitting the bypass label, we emit
the lifetime instrinsic again to make sure the lifetime of the bypassed
variable is start again. Address sanitizer will capture these lifetime
intrinsics and instrument poison and unpoison code. Finally pr56356 can
be resolved.

Here is the new llvm-ir of the test case above.

define dso_local void @goto_bypass() local_unnamed_addr #0 {
entry:
  %x = alloca i8, align 1
  call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %x) #3
  br label %l1

l1:                                               ; preds = %l1, %entry
  call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %x) #3
  %call = call i32 @bar(ptr noundef nonnull %x, i32 noundef 1) #3
  call void @llvm.lifetime.end.p0(i64 1, ptr nonnull %x) #3
  br label %l1
}

Diff Detail

Event Timeline

StephenFan created this revision.Jul 10 2022, 9:56 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 10 2022, 9:56 AM
StephenFan requested review of this revision.Jul 10 2022, 9:56 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 10 2022, 9:56 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
StephenFan edited the summary of this revision. (Show Details)Jul 10 2022, 9:58 AM

looks like check-asan tests fail

vitalybuka added inline comments.Jul 10 2022, 8:25 PM
clang/lib/CodeGen/CodeGenFunction.h
935

LifetimeStartMarkers -> BypassedLifetimeStartMarkers
and below

if I read this correctly this is not any start marker

clang/test/CodeGen/lifetime2.c
41–42

It assume this will break Msan Transforms/Instrumentation/MemorySanitizer.cpp:1298 as it assume variable is not initialized on start

void goto_bypass(void) {
  {
    char x;
  l1:
    bar(&x, 1);
   if (x)
     goto l1
  }
  goto l1;
}
76–77

Please check for lifetime markers, I assume case 2 will have a new one

vitalybuka added inline comments.Jul 11 2022, 10:51 AM
clang/test/CodeGen/lifetime2.c
76–77

Please check for lifetime markers, I assume case 2 will have a new one

Please check for *all* lifetime markers

you can add use "FileCheck --implicit-check-not llvm.lifetime" so it will fail if something has no corresponding match

  1. Record bypassed lifetime start markers in codegenfunction class instead of lexicalscope. Since bypassed variables may be defined when lexicalscope is nullptr. This can also fix test fail of use-after-scope-goto.cpp.
  2. Check more lifetime.start or end intrinsics in lifetime2.c test file.
StephenFan added inline comments.Jul 14 2022, 10:10 AM
clang/test/CodeGen/lifetime2.c
41–42

Yes. I still need some time to see how to deal with it.

76–77

I have checked for all lifetime markers in Diff 444701. What's the point of adding --implicit-check-not llvm.lifetime?

StephenFan marked an inline comment as done.Jul 14 2022, 10:10 AM
vitalybuka added inline comments.Jul 14 2022, 10:23 AM
clang/test/CodeGen/lifetime2.c
76–77

Point is to have en error, if lifetime emitted, but we don't have a check for that.
Which is very reasonable for the test.

vitalybuka added inline comments.Jul 14 2022, 11:07 AM
clang/test/CodeGen/lifetime2.c
76–77

actually converting the test into --implicit-check-not in a separate patch could be nice, so we would be be confused by previously missed markers. https://reviews.llvm.org/D129789

  1. Rebase.
  2. Add a test case of goto_bypass.
Herald added a project: Restricted Project. · View Herald TranscriptJul 18 2022, 1:43 AM
StephenFan added inline comments.Jul 18 2022, 2:21 AM
clang/test/CodeGen/lifetime2.c
76–77

Thanks!

StephenFan added inline comments.Jul 20 2022, 10:35 PM
clang/test/CodeGen/lifetime2.c
41–42

Candidate solution: D129991

I am not sure what to do with this patch. I really prefer to avoid it to minimize the risk of regressions.

We probably considered/prototyped to insert starts like in this solution then in 2016. But at the time of the solution was a comment by @rsmith https://reviews.llvm.org/D24693#559609
Even if it works for asan, I still don't know how this patch will affect miss-compiles in other places. Dropping intrinsics completely as is must not miscompile.

If the goal to fix asan, then it's extremely rare case, I measured it on llvm codebase and entire Google code. This is not worth of effort to me.
Also HWAsan and MTE, which can be considered asan successors, does not even bother to handle allocas with multiple lifetime start.

I am not sure what to do with this patch. I really prefer to avoid it to minimize the risk of regressions.

We probably considered/prototyped to insert starts like in this solution then in 2016. But at the time of the solution was a comment by @rsmith https://reviews.llvm.org/D24693#559609
Even if it works for asan, I still don't know how this patch will affect miss-compiles in other places. Dropping intrinsics completely as is must not miscompile.

If the goal to fix asan, then it's extremely rare case, I measured it on llvm codebase and entire Google code. This is not worth of effort to me.
Also HWAsan and MTE, which can be considered asan successors, does not even bother to handle allocas with multiple lifetime start.

Ok. I'm just fixing this out of interest, and it doesn't look like it's a rigid demand to fix it. If this patch may cause potential regression, I respect your decision.

vitalybuka requested changes to this revision.Dec 7 2022, 1:51 PM

Abandon?

This revision now requires changes to proceed.Dec 7 2022, 1:51 PM
StephenFan abandoned this revision.Dec 8 2022, 3:16 AM