File tree 3 files changed +17
-8
lines changed
rustc_codegen_llvm/src/back
3 files changed +17
-8
lines changed Original file line number Diff line number Diff line change @@ -370,8 +370,9 @@ fn get_pgo_use_path(config: &ModuleConfig) -> Option<CString> {
370
370
}
371
371
372
372
pub ( crate ) fn should_use_new_llvm_pass_manager ( config : & ModuleConfig ) -> bool {
373
- // The new pass manager is disabled by default.
374
- config. new_llvm_pass_manager . unwrap_or ( false )
373
+ // The new pass manager is enabled by default for LLVM >= 13.
374
+ // This matches Clang, which also enables it since Clang 13.
375
+ config. new_llvm_pass_manager . unwrap_or_else ( || llvm_util:: get_version ( ) >= ( 13 , 0 , 0 ) )
375
376
}
376
377
377
378
pub ( crate ) unsafe fn optimize_with_new_llvm_pass_manager (
Original file line number Diff line number Diff line change @@ -1004,7 +1004,10 @@ LLVMRustOptimizeWithNewPassManager(
1004
1004
#endif
1005
1005
bool NeedThinLTOBufferPasses = UseThinLTOBuffers;
1006
1006
if (!NoPrepopulatePasses) {
1007
- if (OptLevel == OptimizationLevel::O0) {
1007
+ // The pre-link pipelines don't support O0 and require using budilO0DefaultPipeline() instead.
1008
+ // At the same time, the LTO pipelines do support O0 and using them is required.
1009
+ bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO || OptStage == LLVMRustOptStage::FatLTO;
1010
+ if (OptLevel == OptimizationLevel::O0 && !IsLTO) {
1008
1011
#if LLVM_VERSION_GE(12, 0)
1009
1012
for (const auto &C : PipelineStartEPCallbacks)
1010
1013
PB.registerPipelineStartEPCallback (C);
Original file line number Diff line number Diff line change 1
- // compile-flags: -Z panic-in-drop=abort -O
1
+ // compile-flags: -Z panic-in-drop=abort -O -Z new-llvm-pass-manager=no
2
2
3
3
// Ensure that unwinding code paths are eliminated from the output after
4
4
// optimization.
5
5
6
+ // This test uses -Z new-llvm-pass-manager=no, because the expected optimization does not happen
7
+ // on targets using SEH exceptions (i.e. MSVC) anymore. The core issue is that Rust promises that
8
+ // the drop_in_place() function can't unwind, but implements it in a way that *can*, because we
9
+ // currently go out of our way to allow longjmps, which also use the unwinding mechanism on MSVC
10
+ // targets. We should either forbid longjmps, or not assume nounwind, making this optimization
11
+ // incompatible with the current behavior of running cleanuppads on longjmp unwinding.
12
+
13
+ // CHECK-NOT: {{(call|invoke).*}}should_not_appear_in_output
14
+
6
15
#![ crate_type = "lib" ]
7
16
use std:: any:: Any ;
8
17
use std:: mem:: forget;
@@ -35,17 +44,13 @@ impl Drop for AssertNeverDrop {
35
44
}
36
45
}
37
46
38
- // CHECK-LABEL: normal_drop
39
- // CHECK-NOT: should_not_appear_in_output
40
47
#[ no_mangle]
41
48
pub fn normal_drop ( x : ExternDrop ) {
42
49
let guard = AssertNeverDrop ;
43
50
drop ( x) ;
44
51
forget ( guard) ;
45
52
}
46
53
47
- // CHECK-LABEL: indirect_drop
48
- // CHECK-NOT: should_not_appear_in_output
49
54
#[ no_mangle]
50
55
pub fn indirect_drop ( x : Box < dyn Any > ) {
51
56
let guard = AssertNeverDrop ;
You can’t perform that action at this time.
0 commit comments