This is an archive of the discontinued LLVM Phabricator instance.

Run Coverage pass before other *San passes under new pass manager, round 2
ClosedPublic

Authored by aeubanks on May 27 2020, 11:26 PM.

Details

Summary

This was attempted once before in https://reviews.llvm.org/D79698, but
was reverted due to the coverage pass running in the wrong part of the
pipeline. This commit puts it in the same place as the other sanitizers.

This changes PassBuilder.OptimizerLastEPCallbacks to work on a
ModulePassManager instead of a FunctionPassManager. That is because
SanitizerCoverage cannot (easily) be split into a module pass and a
function pass like some of the other sanitizers since in its current
implementation it conditionally inserts module constructors based on
whether or not it successfully modified functions.

This fixes compiler-rt/test/msan/coverage-levels.cpp under the new pass
manager (last check-msan test).

Diff Detail

Event Timeline

aeubanks created this revision.May 27 2020, 11:26 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptMay 27 2020, 11:26 PM
leonardchan added inline comments.May 28 2020, 11:28 AM
llvm/include/llvm/Passes/PassBuilder.h
597–598

Will need to change the wording on this if this doesn't handle function passes anymore.

llvm/lib/Passes/PassBuilder.cpp
1079

Would it be better to add another SmallVector and register*Calback() for modules in in PassBuilder that we could loop through here instead of changing how these extension points work?

I imagine it would still be meaningful in the future to be able to add function passes at the end of the function optimization pipeline.

aeubanks marked 2 inline comments as done.May 28 2020, 12:33 PM
aeubanks added inline comments.
llvm/include/llvm/Passes/PassBuilder.h
597–598

This doesn't say that registerOptimizerLastEPCallback() handles function passes, it says it handles passes that will run right after all the default function optimization passes. I believe that's still true. The passes were previously added at the end of OptimizePM, now they're added right after OptimizePM, which is the same thing.

llvm/lib/Passes/PassBuilder.cpp
1079

You can still add function passes via createModuleToFunctionPassAdaptor(), which is what I've done here for the existing usages. Given that the number of calls to registerOptimizerLastEPCallback() is small, I don't see a huge benefit to create a both a vector of module passes and function passes that run at the same place. If in the future we end up calling registerOptimizerLastEPCallback() with lots of function passes we can revisit this but for now it seems unnecessary.

This change doesn't change the ordering of any passes aside from sanitizer coverage (I believe), all usages of registerOptimizerLastEPCallback() will still end up putting the passes in the same place in the pipeline.

leonardchan accepted this revision.May 28 2020, 12:58 PM

Would be worthwhile to write a small test that asserts Sancov runs before the other sanitizers under the new PM?

Aside from this, LGTM.

llvm/include/llvm/Passes/PassBuilder.h
597–598

Ah I see. You're right. I misread.

llvm/lib/Passes/PassBuilder.cpp
1079

I see. Makes sense.

This revision is now accepted and ready to land.May 28 2020, 12:58 PM

Would be worthwhile to write a small test that asserts Sancov runs before the other sanitizers under the new PM?

Aside from this, LGTM.

Asserting that sancov runs before other sanitizers seems like overspecification to me. Really all we want to know is that something like msan + sancov work together, and there are tests for that which we are fixing with this.

This revision was automatically updated to reflect the committed changes.
aeubanks reopened this revision.May 28 2020, 4:00 PM
This revision is now accepted and ready to land.May 28 2020, 4:00 PM
aeubanks updated this revision to Diff 267073.May 28 2020, 4:00 PM

I foolishly submitted without running check-all, and it turns out this broke a test under check-clang.
Looks like https://reviews.llvm.org/D62888 added tests in sancov-new-pm.c to make sure that sancov + LTO work together, but they won't after this change since the (Thin)LTO pipeline doesn't run things under registerOptimizerLastEPCallback(). So I deleted those tests. Other sanitizers don't work under LTO right now (at least for non-O0) because of the same thing. Does this make sense?

leonardchan accepted this revision.May 28 2020, 4:17 PM

I foolishly submitted without running check-all, and it turns out this broke a test under check-clang.
Looks like https://reviews.llvm.org/D62888 added tests in sancov-new-pm.c to make sure that sancov + LTO work together, but they won't after this change since the (Thin)LTO pipeline doesn't run things under registerOptimizerLastEPCallback(). So I deleted those tests. Other sanitizers don't work under LTO right now (at least for non-O0) because of the same thing. Does this make sense?

Makes sense. Could you also remove any CHECK lines for RUNs that were removed?

aeubanks updated this revision to Diff 267087.May 28 2020, 5:02 PM

Update some CHECKs

This revision was automatically updated to reflect the committed changes.