Skip to content

Commit 587ca17

Browse files
authored
Rollup merge of #69665 - tmiasko:new-pass-manager-thin-lto-opt, r=nikic
Invoke OptimizerLastEPCallbacks in PreLinkThinLTO The default ThinLTO pre-link pipeline does not include optimizer last extension points. Thus, when using the new LLVM pass manager & ThinLTO & sanitizers on any opt-level different from zero, the sanitizer function passes would be omitted from the pipeline. Add optimizer last extensions points manually to the pipeline, but guard registration with stage check in the case this behaviour changes in the future.
2 parents 099cd7f + b0e288d commit 587ca17

File tree

4 files changed

+57
-4
lines changed

4 files changed

+57
-4
lines changed

Diff for: src/rustllvm/PassWrapper.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -868,15 +868,23 @@ LLVMRustOptimizeWithNewPassManager(
868868
} else {
869869
for (const auto &C : PipelineStartEPCallbacks)
870870
PB.registerPipelineStartEPCallback(C);
871-
for (const auto &C : OptimizerLastEPCallbacks)
872-
PB.registerOptimizerLastEPCallback(C);
871+
if (OptStage != LLVMRustOptStage::PreLinkThinLTO) {
872+
for (const auto &C : OptimizerLastEPCallbacks)
873+
PB.registerOptimizerLastEPCallback(C);
874+
}
873875

874876
switch (OptStage) {
875877
case LLVMRustOptStage::PreLinkNoLTO:
876878
MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
877879
break;
878880
case LLVMRustOptStage::PreLinkThinLTO:
879881
MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
882+
if (!OptimizerLastEPCallbacks.empty()) {
883+
FunctionPassManager FPM(DebugPassManager);
884+
for (const auto &C : OptimizerLastEPCallbacks)
885+
C(FPM, OptLevel);
886+
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
887+
}
880888
break;
881889
case LLVMRustOptStage::PreLinkFatLTO:
882890
MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);

Diff for: src/test/codegen/sanitizer-recover.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
//[MSAN-RECOVER-LTO] compile-flags: -Zsanitizer=memory -Zsanitizer-recover=memory -C lto=fat
1515
//
1616
// MSAN-NOT: @__msan_keep_going
17-
// MSAN-RECOVER: @__msan_keep_going = weak_odr {{.*}} constant i32 1
18-
// MSAN-RECOVER-LTO: @__msan_keep_going = weak_odr {{.*}} constant i32 1
17+
// MSAN-RECOVER: @__msan_keep_going = weak_odr {{.*}}constant i32 1
18+
// MSAN-RECOVER-LTO: @__msan_keep_going = weak_odr {{.*}}constant i32 1
1919

2020
// ASAN-LABEL: define i32 @penguin(
2121
// ASAN: call void @__asan_report_load4(i64 %0)
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Regression test for sanitizer function instrumentation passes not
2+
// being run when compiling with new LLVM pass manager and ThinLTO.
3+
// Note: The issue occured only on non-zero opt-level.
4+
//
5+
// min-llvm-version 9.0
6+
// needs-sanitizer-support
7+
// only-x86_64
8+
//
9+
// no-prefer-dynamic
10+
// revisions: opt0 opt1
11+
// compile-flags: -Znew-llvm-pass-manager=yes -Zsanitizer=address -Clto=thin
12+
//[opt0]compile-flags: -Copt-level=0
13+
//[opt1]compile-flags: -Copt-level=1
14+
// run-fail
15+
// error-pattern: ERROR: AddressSanitizer: stack-use-after-scope
16+
17+
static mut P: *mut usize = std::ptr::null_mut();
18+
19+
fn main() {
20+
unsafe {
21+
{
22+
let mut x = 0;
23+
P = &mut x;
24+
}
25+
std::ptr::write_volatile(P, 123);
26+
}
27+
}

Diff for: src/tools/compiletest/src/header/tests.rs

+18
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,24 @@ fn no_system_llvm() {
109109
assert!(parse_rs(&config, "// no-system-llvm").ignore);
110110
}
111111

112+
#[test]
113+
fn llvm_version() {
114+
let mut config = config();
115+
116+
config.llvm_version = Some("8.1.2-rust".to_owned());
117+
assert!(parse_rs(&config, "// min-llvm-version 9.0").ignore);
118+
119+
config.llvm_version = Some("9.0.1-rust-1.43.0-dev".to_owned());
120+
assert!(parse_rs(&config, "// min-llvm-version 9.2").ignore);
121+
122+
config.llvm_version = Some("9.3.1-rust-1.43.0-dev".to_owned());
123+
assert!(!parse_rs(&config, "// min-llvm-version 9.2").ignore);
124+
125+
// FIXME.
126+
// config.llvm_version = Some("10.0.0-rust".to_owned());
127+
// assert!(!parse_rs(&config, "// min-llvm-version 9.0").ignore);
128+
}
129+
112130
#[test]
113131
fn ignore_target() {
114132
let mut config = config();

0 commit comments

Comments
 (0)