Skip to content

Commit c22cb53

Browse files
committed
Auto merge of #31176 - frewsxcv:incorrect-pass-kind, r=dotdash
Register LLVM passes with the correct LLVM pass manager. LLVM was upgraded to a new version in this commit: f9d4149 which was part of this pull request: #26025 Consider the following two lines from that commit: f9d4149#diff-a3b24dbe2ea7c1981f9ac79f9745f40aL462 f9d4149#diff-a3b24dbe2ea7c1981f9ac79f9745f40aL469 The purpose of these lines is to register LLVM passes. Prior to the that commit, the passes being handled were assumed to be ModulePasses (a specific type of LLVM pass) since they were being added to a ModulePass manager. After that commit, both lines were refactored (presumably in an attempt to DRY out the code), but the ModulePasses were changed to be registered to a FunctionPass manager. This change resulted in ModulePasses being run, but a Function object was being passed as a parameter to the pass instead of a Module, which resulted in segmentation faults. In this commit, I changed relevant sections of the code to check the type of the passes being added and register them to the appropriate pass manager. Closes #31067
2 parents 6866f13 + d942621 commit c22cb53

File tree

4 files changed

+65
-12
lines changed

4 files changed

+65
-12
lines changed

src/librustc_llvm/lib.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,15 @@ pub enum ArchiveKind {
461461
K_COFF,
462462
}
463463

464+
/// Represents the different LLVM passes Rust supports
465+
#[derive(Copy, Clone, PartialEq, Debug)]
466+
#[repr(C)]
467+
pub enum SupportedPassKind {
468+
Function,
469+
Module,
470+
Unsupported,
471+
}
472+
464473
// Opaque pointer types
465474
#[allow(missing_copy_implementations)]
466475
pub enum Module_opaque {}
@@ -2008,7 +2017,10 @@ extern {
20082017
pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
20092018
pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
20102019

2011-
pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: *const c_char) -> bool;
2020+
pub fn LLVMRustPassKind(Pass: PassRef) -> SupportedPassKind;
2021+
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
2022+
pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef);
2023+
20122024
pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
20132025
CPU: *const c_char,
20142026
Features: *const c_char,

src/librustc_trans/back/lto.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,15 +145,19 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
145145
unsafe {
146146
let pm = llvm::LLVMCreatePassManager();
147147
llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod);
148-
llvm::LLVMRustAddPass(pm, "verify\0".as_ptr() as *const _);
148+
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
149+
assert!(!pass.is_null());
150+
llvm::LLVMRustAddPass(pm, pass);
149151

150152
with_llvm_pmb(llmod, config, &mut |b| {
151153
llvm::LLVMPassManagerBuilderPopulateLTOPassManager(b, pm,
152154
/* Internalize = */ False,
153155
/* RunInliner = */ True);
154156
});
155157

156-
llvm::LLVMRustAddPass(pm, "verify\0".as_ptr() as *const _);
158+
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
159+
assert!(!pass.is_null());
160+
llvm::LLVMRustAddPass(pm, pass);
157161

158162
time(sess.time_passes(), "LTO passes", ||
159163
llvm::LLVMRunPassManager(pm, llmod));

src/librustc_trans/back/write.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,22 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
446446

447447
// If we're verifying or linting, add them to the function pass
448448
// manager.
449-
let addpass = |pass: &str| {
450-
let pass = CString::new(pass).unwrap();
451-
llvm::LLVMRustAddPass(fpm, pass.as_ptr())
449+
let addpass = |pass_name: &str| {
450+
let pass_name = CString::new(pass_name).unwrap();
451+
let pass = llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr());
452+
if pass.is_null() {
453+
return false;
454+
}
455+
let pass_manager = match llvm::LLVMRustPassKind(pass) {
456+
llvm::SupportedPassKind::Function => fpm,
457+
llvm::SupportedPassKind::Module => mpm,
458+
llvm::SupportedPassKind::Unsupported => {
459+
cgcx.handler.err("Encountered LLVM pass kind we can't handle");
460+
return true
461+
},
462+
};
463+
llvm::LLVMRustAddPass(pass_manager, pass);
464+
true
452465
};
453466

454467
if !config.no_verify { assert!(addpass("verify")); }

src/rustllvm/PassWrapper.cpp

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,43 @@ LLVMInitializePasses() {
5858
initializeTarget(Registry);
5959
}
6060

61-
extern "C" bool
62-
LLVMRustAddPass(LLVMPassManagerRef PM, const char *PassName) {
63-
PassManagerBase *pm = unwrap(PM);
6461

62+
enum class SupportedPassKind {
63+
Function,
64+
Module,
65+
Unsupported
66+
};
67+
68+
extern "C" Pass*
69+
LLVMRustFindAndCreatePass(const char *PassName) {
6570
StringRef SR(PassName);
6671
PassRegistry *PR = PassRegistry::getPassRegistry();
6772

6873
const PassInfo *PI = PR->getPassInfo(SR);
6974
if (PI) {
70-
pm->add(PI->createPass());
71-
return true;
75+
return PI->createPass();
7276
}
73-
return false;
77+
return NULL;
78+
}
79+
80+
extern "C" SupportedPassKind
81+
LLVMRustPassKind(Pass *pass) {
82+
assert(pass);
83+
PassKind passKind = pass->getPassKind();
84+
if (passKind == PT_Module) {
85+
return SupportedPassKind::Module;
86+
} else if (passKind == PT_Function) {
87+
return SupportedPassKind::Function;
88+
} else {
89+
return SupportedPassKind::Unsupported;
90+
}
91+
}
92+
93+
extern "C" void
94+
LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) {
95+
assert(pass);
96+
PassManagerBase *pm = unwrap(PM);
97+
pm->add(pass);
7498
}
7599

76100
extern "C" LLVMTargetMachineRef

0 commit comments

Comments
 (0)