Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion compiler/rustc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ features = ['override_allocator_on_supported_platforms']
check_only = ['rustc_driver_impl/check_only']
jemalloc = ['dep:tikv-jemalloc-sys']
llvm = ['rustc_driver_impl/llvm']
llvm_enzyme = ['rustc_driver_impl/llvm_enzyme']
llvm_offload = ['rustc_driver_impl/llvm_offload']
max_level_info = ['rustc_driver_impl/max_level_info']
rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts']
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_builtin_macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,4 @@ tracing = "0.1"

[features]
# tidy-alphabetical-start
llvm_enzyme = []
# tidy-alphabetical-end
1 change: 0 additions & 1 deletion compiler/rustc_codegen_llvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ tracing = "0.1"
[features]
# tidy-alphabetical-start
check_only = ["rustc_llvm/check_only"]
llvm_enzyme = []
llvm_offload = []
# tidy-alphabetical-end

2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ pub(crate) fn run_pass_manager(
);
}

if cfg!(feature = "llvm_enzyme") && enable_ad && !thin {
if enable_ad && !thin {
let opt_stage = llvm::OptStage::FatLTO;
let stage = write::AutodiffStage::PostAD;
if !config.autodiff.contains(&config::AutoDiff::NoPostopt)
Expand Down
10 changes: 2 additions & 8 deletions compiler/rustc_codegen_llvm/src/typetree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,9 @@ enum TTLocation {
Callsite,
}

#[cfg_attr(not(feature = "llvm_enzyme"), allow(unused))]
pub(crate) fn add_tt<'tcx, 'll>(cx: &FullCx<'ll, 'tcx>, fn_def: &'ll Value, tt: FncTree) {
// TypeTree processing uses functions from Enzyme, which we might not have available if we did
// not build this compiler with `llvm_enzyme`. This feature is not strictly necessary, but
// skipping this function increases the chance that Enzyme fails to compile some code.
// FIXME(autodiff): In the future we should conditionally run this function even without the
// `llvm_enzyme` feature, in case that libEnzyme was provided via rustup.
#[cfg(not(feature = "llvm_enzyme"))]
return;
// TypeTree processing uses functions from Enzyme. This feature is not strictly necessary,
// but skipping this function increases the chance that Enzyme fails to compile some code.

let tcx = cx.tcx;
if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) {
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_driver_impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ ctrlc = "3.4.4"
# tidy-alphabetical-start
check_only = ['rustc_interface/check_only']
llvm = ['rustc_interface/llvm']
llvm_enzyme = ['rustc_interface/llvm_enzyme']
llvm_offload = ['rustc_interface/llvm_offload']
max_level_info = ['rustc_log/max_level_info']
rustc_randomized_layouts = [
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,5 @@ rustc_abi = { path = "../rustc_abi" }
# tidy-alphabetical-start
check_only = ['rustc_codegen_llvm?/check_only']
llvm = ['dep:rustc_codegen_llvm']
llvm_enzyme = ['rustc_builtin_macros/llvm_enzyme', 'rustc_codegen_llvm/llvm_enzyme']
llvm_offload = ['rustc_codegen_llvm/llvm_offload']
# tidy-alphabetical-end
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(function_sections, Some(false));
tracked!(hint_mostly_unused, true);
tracked!(human_readable_cgu_names, true);
tracked!(implicit_sysroot_deps, false);
tracked!(incremental_ignore_spans, true);
tracked!(indirect_branch_cs_prefix, true);
tracked!(inline_mir, Some(true));
Expand Down
151 changes: 123 additions & 28 deletions compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,34 +129,8 @@ fn encode_const<'tcx>(
// Element type
s.push_str(&encode_ty(tcx, cv.ty, dict, options));

// The only allowed types of const values are bool, u8, u16, u32,
// u64, u128, usize i8, i16, i32, i64, i128, isize, and char. The
// bool value false is encoded as 0 and true as 1.
match cv.ty.kind() {
ty::Int(ity) => {
let bits = cv
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
.expect("expected monomorphic const in cfi");
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
if val < 0 {
s.push('n');
}
let _ = write!(s, "{val}");
}
ty::Uint(_) => {
let val = cv
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
.expect("expected monomorphic const in cfi");
let _ = write!(s, "{val}");
}
ty::Bool => {
let val = cv.try_to_bool().expect("expected monomorphic const in cfi");
let _ = write!(s, "{val}");
}
_ => {
bug!("encode_const: unexpected type `{:?}`", cv.ty);
}
}
// Element value
s.push_str(&encode_const_value(tcx, cv, dict, options));
}

_ => {
Expand All @@ -172,6 +146,127 @@ fn encode_const<'tcx>(
s
}

/// Encodes a const value using the Itanium C++ ABI as the element value of a literal argument (see
/// <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling.literal>).
fn encode_const_value<'tcx>(
tcx: TyCtxt<'tcx>,
cv: ty::Value<'tcx>,
dict: &mut FxHashMap<DictKey<'tcx>, usize>,
options: EncodeTyOptions,
) -> String {
let mut s = String::new();

match cv.ty.kind() {
// Primitive types

// The bool value false is encoded as 0 and true as 1.
ty::Bool => {
let val = cv.try_to_bool().expect("expected monomorphic const in cfi");
s.push(if val { '1' } else { '0' });
}

// Integer values are encoded as their decimal values, with negative values preceded by n.
ty::Int(ity) => {
let bits = cv
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
.expect("expected monomorphic const in cfi");
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
if val < 0 {
s.push('n');
}
let _ = write!(s, "{}", val.unsigned_abs());
}

ty::Uint(..) => {
let val = cv
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
.expect("expected monomorphic const in cfi");
let _ = write!(s, "{val}");
}

// char values are encoded as their Unicode scalar values (i.e., as their decimal u32
// values).
ty::Char => {
let val = cv
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
.expect("expected monomorphic const in cfi");
let _ = write!(s, "{val}");
}

// str values are encoded as their UTF-8 encodings in hexadecimal.
ty::Str => {
// Hide the str type behind a reference for try_to_raw_bytes (i.e., the valtree of a
// str value is the valtree of its reference).
let ref_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, cv.ty);
let cv = ty::Value { ty: ref_ty, valtree: cv.valtree };
let bytes = cv.try_to_raw_bytes(tcx).expect("expected monomorphic const in cfi");
for byte in bytes {
let _ = write!(s, "{byte:02x}");
}
}

// Sequence types
// Array, slice, and tuple values are encoded as their element values as literal arguments.
ty::Array(..) | ty::Slice(..) | ty::Tuple(..) => {
for field in cv.to_branch() {
let ty::ConstKind::Value(field_cv) = field.kind() else {
bug!("encode_const_value: unexpected kind `{:?}`", field.kind());
};
s.push_str(&encode_const(tcx, *field, field_cv.ty, dict, options));
}
}

// User-defined types
// Struct and enum values are encoded as their field values as literal arguments, preceded
// by V<variant-index> for enum values.
ty::Adt(adt_def, ..) => {
let contents = cv.destructure_adt_const();
if adt_def.is_enum() {
let _ = write!(s, "V{}", contents.variant.as_u32());
}
for field in contents.fields {
let ty::ConstKind::Value(field_cv) = field.kind() else {
bug!("encode_const_value: unexpected kind `{:?}`", field.kind());
};
s.push_str(&encode_const(tcx, *field, field_cv.ty, dict, options));
}
}

// Pointer types
// Reference values are encoded as the values of their referents (i.e., the valtree of a
// reference value is the valtree of its referent).
ty::Ref(_, ty0, ..) => {
let cv = ty::Value { ty: *ty0, valtree: cv.valtree };
s.push_str(&encode_const_value(tcx, cv, dict, options));
}

// Unexpected types
ty::Float(..)
| ty::Never
| ty::Foreign(..)
| ty::Pat(..)
| ty::FnDef(..)
| ty::FnPtr(..)
| ty::RawPtr(..)
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Dynamic(..)
| ty::UnsafeBinder(..)
| ty::Param(..)
| ty::Alias(..)
| ty::Bound(..)
| ty::Error(..)
| ty::Infer(..)
| ty::Placeholder(..) => {
bug!("encode_const_value: unexpected type `{:?}`", cv.ty);
}
}

s
}

/// Encodes a FnSig using the Itanium C++ ABI with vendor extended type qualifiers and types for
/// Rust types that are not used at the FFI boundary.
fn encode_fnsig<'tcx>(
Expand Down
16 changes: 14 additions & 2 deletions compiler/rustc_session/src/filesearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::search_paths::{PathKind, SearchPath};
pub struct FileSearch {
cli_search_paths: Vec<SearchPath>,
tlib_path: SearchPath,
use_implicit_sysroot_deps: bool,
}

impl FileSearch {
Expand All @@ -20,16 +21,27 @@ impl FileSearch {
}

pub fn search_paths<'b>(&'b self, kind: PathKind) -> impl Iterator<Item = &'b SearchPath> {
// If the crate is `PathKind::Crate` (a top level dependency)
// and `-Z implicit-sysroot-deps=false`, then don't include the sysroot in the search paths.
let exclude_sysroot = kind.matches(PathKind::Crate) && !self.use_implicit_sysroot_deps;
let maybe_tlib = (!exclude_sysroot).then_some(&self.tlib_path);

self.cli_search_paths
.iter()
.filter(move |sp| sp.kind.matches(kind))
.chain(std::iter::once(&self.tlib_path))
.chain(maybe_tlib.into_iter())
}

pub fn new(cli_search_paths: &[SearchPath], tlib_path: &SearchPath, target: &Target) -> Self {
pub fn new(
cli_search_paths: &[SearchPath],
tlib_path: &SearchPath,
target: &Target,
use_implicit_sysroot_deps: bool,
) -> Self {
let this = FileSearch {
cli_search_paths: cli_search_paths.to_owned(),
tlib_path: tlib_path.clone(),
use_implicit_sysroot_deps,
};
this.refine(&["lib", &target.staticlib_prefix, &target.dll_prefix])
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2531,6 +2531,8 @@ options! {
"display unnamed regions as `'<id>`, using a non-ident unique id (default: no)"),
ignore_directory_in_diagnostics_source_blocks: Vec<String> = (Vec::new(), parse_string_push, [UNTRACKED],
"do not display the source code block in diagnostics for files in the directory"),
implicit_sysroot_deps: bool = (true, parse_bool, [TRACKED],
"allows rust to search sysroot for a crate's dependencies (default: yes)"),
incremental_ignore_spans: bool = (false, parse_bool, [TRACKED],
"ignore spans during ICH computation -- used for testing (default: no)"),
incremental_info: bool = (false, parse_bool, [UNTRACKED],
Expand Down
15 changes: 12 additions & 3 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1335,9 +1335,18 @@ pub fn build_session(
});

let asm_arch = if target.allow_asm { InlineAsmArch::from_arch(&target.arch) } else { None };
let target_filesearch =
filesearch::FileSearch::new(&sopts.search_paths, &target_tlib_path, &target);
let host_filesearch = filesearch::FileSearch::new(&sopts.search_paths, &host_tlib_path, &host);
let target_filesearch = filesearch::FileSearch::new(
&sopts.search_paths,
&target_tlib_path,
&target,
sopts.unstable_opts.implicit_sysroot_deps,
);
let host_filesearch = filesearch::FileSearch::new(
&sopts.search_paths,
&host_tlib_path,
&host,
sopts.unstable_opts.implicit_sysroot_deps,
);

let timings = TimingSectionHandler::new(sopts.json_timings);

Expand Down
2 changes: 0 additions & 2 deletions library/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ optimize_for_size = []
# Make `RefCell` store additional debugging information, which is printed out when
# a borrow error occurs
debug_refcell = []
llvm_enzyme = []

[lints.rust.unexpected_cfgs]
level = "warn"
Expand All @@ -39,7 +38,6 @@ check-cfg = [
'cfg(target_has_reliable_f16_math)',
'cfg(target_has_reliable_f128)',
'cfg(target_has_reliable_f128_math)',
'cfg(llvm_enzyme)',
# Prevents use of a static variable for providing platform specific RawOsError
# functionality
'cfg(no_io_statics)',
Expand Down
2 changes: 0 additions & 2 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,6 @@ optimize_for_size = ["core/optimize_for_size", "alloc/optimize_for_size"]
# a borrow error occurs
debug_refcell = ["core/debug_refcell"]

llvm_enzyme = ["core/llvm_enzyme"]

# Enable using raw-dylib for Windows imports.
# This will eventually be the default.
windows_raw_dylib = ["windows-link/windows_raw_dylib"]
Expand Down
1 change: 0 additions & 1 deletion library/sysroot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,3 @@ optimize_for_size = ["std/optimize_for_size"]
panic-unwind = ["std/panic-unwind"]
profiler = ["dep:profiler_builtins"]
windows_raw_dylib = ["std/windows_raw_dylib"]
llvm_enzyme = ["std/llvm_enzyme"]
Loading
Loading