1010
1111// The rustc crates we need
1212extern crate rustc_abi;
13+ extern crate rustc_codegen_ssa;
1314extern crate rustc_data_structures;
1415extern crate rustc_driver;
1516extern crate rustc_hir;
@@ -19,6 +20,7 @@ extern crate rustc_log;
1920extern crate rustc_middle;
2021extern crate rustc_session;
2122extern crate rustc_span;
23+ extern crate rustc_target;
2224
2325/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs
2426/// and https://github.com/rust-lang/rust/pull/146627 for why we need this.
@@ -43,12 +45,14 @@ use miri::{
4345 ProvenanceMode , TreeBorrowsParams , ValidationMode , run_genmc_mode,
4446} ;
4547use rustc_abi:: ExternAbi ;
48+ use rustc_codegen_ssa:: traits:: CodegenBackend ;
4649use rustc_data_structures:: sync:: { self , DynSync } ;
4750use rustc_driver:: Compilation ;
4851use rustc_hir:: def_id:: LOCAL_CRATE ;
4952use rustc_hir:: { self as hir, Node } ;
5053use rustc_hir_analysis:: check:: check_function_signature;
5154use rustc_interface:: interface:: Config ;
55+ use rustc_interface:: util:: DummyCodegenBackend ;
5256use rustc_log:: tracing:: debug;
5357use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
5458use rustc_middle:: middle:: exported_symbols:: {
@@ -58,8 +62,9 @@ use rustc_middle::query::LocalCrate;
5862use rustc_middle:: traits:: { ObligationCause , ObligationCauseCode } ;
5963use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
6064use rustc_session:: EarlyDiagCtxt ;
61- use rustc_session:: config:: { CrateType , ErrorOutputType , OptLevel } ;
65+ use rustc_session:: config:: { CrateType , ErrorOutputType , OptLevel , Options } ;
6266use rustc_span:: def_id:: DefId ;
67+ use rustc_target:: spec:: Target ;
6368
6469use crate :: log:: setup:: { deinit_loggers, init_early_loggers, init_late_loggers} ;
6570
@@ -161,7 +166,27 @@ fn run_many_seeds(
161166 }
162167}
163168
169+ fn make_codegen_backend ( opts : & Options , target : & Target ) -> Box < dyn CodegenBackend > {
170+ let early_dcx = EarlyDiagCtxt :: new ( opts. error_format ) ;
171+
172+ // Use the target_config method of the default codegen backend (eg LLVM) to ensure the
173+ // calculated target features match said backend by respecting eg -Ctarget-cpu.
174+ let target_config_backend =
175+ rustc_interface:: util:: get_codegen_backend ( & early_dcx, & opts. sysroot , None , & target) ;
176+
177+ Box :: new ( DummyCodegenBackend {
178+ target_config_override : Some ( Box :: new ( move |sess| {
179+ target_config_backend. init ( sess) ;
180+ target_config_backend. target_config ( sess)
181+ } ) ) ,
182+ } )
183+ }
184+
164185impl rustc_driver:: Callbacks for MiriCompilerCalls {
186+ fn config ( & mut self , config : & mut rustc_interface:: interface:: Config ) {
187+ config. make_codegen_backend = Some ( Box :: new ( make_codegen_backend) ) ;
188+ }
189+
165190 fn after_analysis < ' tcx > (
166191 & mut self ,
167192 _: & rustc_interface:: interface:: Compiler ,
@@ -244,6 +269,10 @@ struct MiriBeRustCompilerCalls {
244269impl rustc_driver:: Callbacks for MiriBeRustCompilerCalls {
245270 #[ allow( rustc:: potential_query_instability) ] // rustc_codegen_ssa (where this code is copied from) also allows this lint
246271 fn config ( & mut self , config : & mut Config ) {
272+ if self . target_crate {
273+ config. make_codegen_backend = Some ( Box :: new ( make_codegen_backend) ) ;
274+ }
275+
247276 if config. opts . prints . is_empty ( ) && self . target_crate {
248277 #[ allow( rustc:: bad_opt_access) ] // tcx does not exist yet
249278 {
0 commit comments