Auto merge of #150481 - matthiaskrgr:rollup-f5b2wkm, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang/rust#150108 (Offload: Build offload as a single Step) - rust-lang/rust#150262 (slice iter cleanup: replace checked_sub with saturating_sub) - rust-lang/rust#150427 (add has_offload/needs-offload to the test infra) - rust-lang/rust#150458 (fix running stdlib doctests in Miri in CI) - rust-lang/rust#150477 (Fix enum variant suggestion consuming trailing parenthesis) - rust-lang/rust#150478 (Fix new bors config) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7e7280f24b
23 changed files with 379 additions and 55 deletions
|
|
@ -106,6 +106,9 @@
|
|||
# Whether to build LLVM with support for it's gpu offload runtime.
|
||||
#llvm.offload = false
|
||||
|
||||
# Absolute path to the directory containing ClangConfig.cmake
|
||||
#llvm.offload-clang-dir = ""
|
||||
|
||||
# When true, link libstdc++ statically into the rustc_llvm.
|
||||
# This is useful if you don't want to use the dynamic version of that
|
||||
# library provided by LLVM.
|
||||
|
|
|
|||
|
|
@ -1384,13 +1384,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&& let hir::Node::Stmt(&hir::Stmt { kind: hir::StmtKind::Semi(parent), .. })
|
||||
| hir::Node::Expr(parent) = tcx.parent_hir_node(path_expr.hir_id)
|
||||
{
|
||||
let replacement_span =
|
||||
if let hir::ExprKind::Call(..) | hir::ExprKind::Struct(..) = parent.kind {
|
||||
// We want to replace the parts that need to go, like `()` and `{}`.
|
||||
// We want to replace the parts that need to go, like `()` and `{}`.
|
||||
let replacement_span = match parent.kind {
|
||||
hir::ExprKind::Call(callee, _) if callee.hir_id == path_expr.hir_id => {
|
||||
span.with_hi(parent.span.hi())
|
||||
} else {
|
||||
span
|
||||
};
|
||||
}
|
||||
hir::ExprKind::Struct(..) => span.with_hi(parent.span.hi()),
|
||||
_ => span,
|
||||
};
|
||||
match (variant.ctor, parent.kind) {
|
||||
(None, hir::ExprKind::Struct(..)) => {
|
||||
// We want a struct and we have a struct. We won't suggest changing
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ use crate::{mem, ptr};
|
|||
///
|
||||
/// To fix this we could use `MaybeDangling`:
|
||||
///
|
||||
/// ```rust
|
||||
// FIXME: remove `no_run` once the semantics are actually implemented
|
||||
/// ```rust,no_run
|
||||
/// #![feature(maybe_dangling, box_as_ptr)]
|
||||
/// # use std::alloc::{dealloc, Layout};
|
||||
/// # use std::mem::{self, MaybeDangling};
|
||||
|
|
|
|||
|
|
@ -2495,19 +2495,13 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
|
|||
&& end < self.v.len()
|
||||
{
|
||||
let end = self.v.len() - end;
|
||||
let start = match end.checked_sub(self.chunk_size) {
|
||||
Some(sum) => sum,
|
||||
None => 0,
|
||||
};
|
||||
// SAFETY: This type ensures that self.v is a valid pointer with a correct len.
|
||||
// Therefore the bounds check in split_at_mut guarantees the split point is inbounds.
|
||||
let (head, tail) = unsafe { self.v.split_at_mut(start) };
|
||||
// SAFETY: This type ensures that self.v is a valid pointer with a correct len.
|
||||
// Therefore the bounds check in split_at_mut guarantees the split point is inbounds.
|
||||
let (nth, _) = unsafe { tail.split_at_mut(end - start) };
|
||||
self.v = head;
|
||||
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
|
||||
let (rest, _) = unsafe { self.v.split_at_mut(end) };
|
||||
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
|
||||
let (rest, chunk) = unsafe { rest.split_at_mut(end.saturating_sub(self.chunk_size)) };
|
||||
self.v = rest;
|
||||
// SAFETY: Nothing else points to or will point to the contents of this slice.
|
||||
Some(unsafe { &mut *nth })
|
||||
Some(unsafe { &mut *chunk })
|
||||
} else {
|
||||
self.v = &mut [];
|
||||
None
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ labels_blocking_approval = [
|
|||
# If CI runs quicker than this duration, consider it to be a failure
|
||||
min_ci_time = 600
|
||||
|
||||
# Flip this once new bors is used for actual merges on this repository
|
||||
merge_queue_enabled = false
|
||||
report_merge_conflicts = true
|
||||
|
||||
[labels]
|
||||
approved = [
|
||||
"+S-waiting-on-bors",
|
||||
|
|
@ -60,7 +64,3 @@ auto_build_failed = [
|
|||
"-S-waiting-on-crater",
|
||||
"-S-waiting-on-team"
|
||||
]
|
||||
|
||||
# Flip this two once new bors is used for actual merges on this repository
|
||||
merge_queue_enabled = false
|
||||
report_merge_conflicts = true
|
||||
|
|
|
|||
|
|
@ -120,6 +120,11 @@ o("optimize-llvm", "llvm.optimize", "build optimized LLVM")
|
|||
o("llvm-assertions", "llvm.assertions", "build LLVM with assertions")
|
||||
o("llvm-enzyme", "llvm.enzyme", "build LLVM with enzyme")
|
||||
o("llvm-offload", "llvm.offload", "build LLVM with gpu offload support")
|
||||
o(
|
||||
"llvm-offload-clang-dir",
|
||||
"llvm.offload-clang-dir",
|
||||
"pass the absolute directory of ClangConfig.cmake",
|
||||
)
|
||||
o("llvm-plugins", "llvm.plugins", "build LLVM with plugin interface")
|
||||
o("debug-assertions", "rust.debug-assertions", "build with debugging assertions")
|
||||
o(
|
||||
|
|
|
|||
|
|
@ -56,8 +56,7 @@ check-aux:
|
|||
# Run standard library tests in Miri.
|
||||
$(Q)MIRIFLAGS="-Zmiri-strict-provenance" \
|
||||
$(BOOTSTRAP) miri --stage 2 \
|
||||
library/coretests \
|
||||
library/alloctests \
|
||||
library/core \
|
||||
library/alloc \
|
||||
$(BOOTSTRAP_ARGS) \
|
||||
--no-doc
|
||||
|
|
@ -65,8 +64,7 @@ check-aux:
|
|||
# so we have to run them with isolation disabled.
|
||||
$(Q)MIRIFLAGS="-Zmiri-disable-isolation" \
|
||||
$(BOOTSTRAP) miri --stage 2 \
|
||||
library/coretests \
|
||||
library/alloctests \
|
||||
library/core \
|
||||
library/alloc \
|
||||
$(BOOTSTRAP_ARGS) \
|
||||
--doc
|
||||
|
|
|
|||
|
|
@ -1430,10 +1430,12 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect
|
|||
if builder.config.llvm_enzyme {
|
||||
cargo.env("LLVM_ENZYME", "1");
|
||||
}
|
||||
let llvm::LlvmResult { host_llvm_config, .. } = builder.ensure(llvm::Llvm { target });
|
||||
if builder.config.llvm_offload {
|
||||
builder.ensure(llvm::OmpOffload { target });
|
||||
cargo.env("LLVM_OFFLOAD", "1");
|
||||
}
|
||||
let llvm::LlvmResult { host_llvm_config, .. } = builder.ensure(llvm::Llvm { target });
|
||||
|
||||
cargo.env("LLVM_CONFIG", &host_llvm_config);
|
||||
|
||||
// Some LLVM linker flags (-L and -l) may be needed to link `rustc_llvm`. Its build script
|
||||
|
|
@ -2296,6 +2298,24 @@ impl Step for Assemble {
|
|||
}
|
||||
}
|
||||
|
||||
if builder.config.llvm_offload && !builder.config.dry_run() {
|
||||
debug!("`llvm_offload` requested");
|
||||
let offload_install = builder.ensure(llvm::OmpOffload { target: build_compiler.host });
|
||||
if let Some(_llvm_config) = builder.llvm_config(builder.config.host_target) {
|
||||
let target_libdir =
|
||||
builder.sysroot_target_libdir(target_compiler, target_compiler.host);
|
||||
for p in offload_install.offload_paths() {
|
||||
let libname = p.file_name().unwrap();
|
||||
let dst_lib = target_libdir.join(libname);
|
||||
builder.resolve_symlink_and_copy(&p, &dst_lib);
|
||||
}
|
||||
// FIXME(offload): Add amdgcn-amd-amdhsa and nvptx64-nvidia-cuda folder
|
||||
// This one is slightly more tricky, since we have the same file twice, in two
|
||||
// subfolders for amdgcn and nvptx64. We'll likely find two more in the future, once
|
||||
// Intel and Spir-V support lands in offload.
|
||||
}
|
||||
}
|
||||
|
||||
// Build the libraries for this compiler to link to (i.e., the libraries
|
||||
// it uses at runtime).
|
||||
debug!(
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use std::path::{Path, PathBuf};
|
|||
use std::sync::OnceLock;
|
||||
use std::{env, fs};
|
||||
|
||||
use build_helper::exit;
|
||||
use build_helper::git::PathFreshness;
|
||||
|
||||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step, StepMetadata};
|
||||
|
|
@ -63,6 +64,25 @@ impl LlvmBuildStatus {
|
|||
}
|
||||
}
|
||||
|
||||
/// Allows each step to add C/Cxx flags which are only used for a specific cmake invocation.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
struct CcFlags {
|
||||
/// Additional values for CMAKE_CC_FLAGS, to be added before all other values.
|
||||
cflags: OsString,
|
||||
/// Additional values for CMAKE_CXX_FLAGS, to be added before all other values.
|
||||
cxxflags: OsString,
|
||||
}
|
||||
|
||||
impl CcFlags {
|
||||
fn push_all(&mut self, s: impl AsRef<OsStr>) {
|
||||
let s = s.as_ref();
|
||||
self.cflags.push(" ");
|
||||
self.cflags.push(s);
|
||||
self.cxxflags.push(" ");
|
||||
self.cxxflags.push(s);
|
||||
}
|
||||
}
|
||||
|
||||
/// Linker flags to pass to LLVM's CMake invocation.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
struct LdFlags {
|
||||
|
|
@ -454,16 +474,6 @@ impl Step for Llvm {
|
|||
enabled_llvm_runtimes.push("compiler-rt");
|
||||
}
|
||||
|
||||
// This is an experimental flag, which likely builds more than necessary.
|
||||
// We will optimize it when we get closer to releasing it on nightly.
|
||||
if builder.config.llvm_offload {
|
||||
enabled_llvm_runtimes.push("offload");
|
||||
//FIXME(ZuseZ4): LLVM intends to drop the offload dependency on openmp.
|
||||
//Remove this line once they achieved it.
|
||||
enabled_llvm_runtimes.push("openmp");
|
||||
enabled_llvm_projects.push("compiler-rt");
|
||||
}
|
||||
|
||||
if !enabled_llvm_projects.is_empty() {
|
||||
enabled_llvm_projects.sort();
|
||||
enabled_llvm_projects.dedup();
|
||||
|
|
@ -527,7 +537,7 @@ impl Step for Llvm {
|
|||
cfg.define("LLVM_VERSION_SUFFIX", suffix);
|
||||
}
|
||||
|
||||
configure_cmake(builder, target, &mut cfg, true, ldflags, &[]);
|
||||
configure_cmake(builder, target, &mut cfg, true, ldflags, CcFlags::default(), &[]);
|
||||
configure_llvm(builder, target, &mut cfg);
|
||||
|
||||
for (key, val) in &builder.config.llvm_build_config {
|
||||
|
|
@ -633,6 +643,7 @@ fn configure_cmake(
|
|||
cfg: &mut cmake::Config,
|
||||
use_compiler_launcher: bool,
|
||||
mut ldflags: LdFlags,
|
||||
ccflags: CcFlags,
|
||||
suppressed_compiler_flag_prefixes: &[&str],
|
||||
) {
|
||||
// Do not print installation messages for up-to-date files.
|
||||
|
|
@ -761,23 +772,21 @@ fn configure_cmake(
|
|||
.define("CMAKE_ASM_COMPILER", sanitize_cc(&cc));
|
||||
|
||||
cfg.build_arg("-j").build_arg(builder.jobs().to_string());
|
||||
let mut cflags = ccflags.cflags.clone();
|
||||
// FIXME(madsmtm): Allow `cmake-rs` to select flags by itself by passing
|
||||
// our flags via `.cflag`/`.cxxflag` instead.
|
||||
//
|
||||
// Needs `suppressed_compiler_flag_prefixes` to be gone, and hence
|
||||
// https://github.com/llvm/llvm-project/issues/88780 to be fixed.
|
||||
let mut cflags: OsString = builder
|
||||
for flag in builder
|
||||
.cc_handled_clags(target, CLang::C)
|
||||
.into_iter()
|
||||
.chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::C))
|
||||
.filter(|flag| {
|
||||
!suppressed_compiler_flag_prefixes
|
||||
.iter()
|
||||
.any(|suppressed_prefix| flag.starts_with(suppressed_prefix))
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
.into();
|
||||
.filter(|flag| !suppressed_compiler_flag_prefixes.iter().any(|p| flag.starts_with(p)))
|
||||
{
|
||||
cflags.push(" ");
|
||||
cflags.push(flag);
|
||||
}
|
||||
if let Some(ref s) = builder.config.llvm_cflags {
|
||||
cflags.push(" ");
|
||||
cflags.push(s);
|
||||
|
|
@ -789,7 +798,8 @@ fn configure_cmake(
|
|||
cflags.push(format!(" --target={target}"));
|
||||
}
|
||||
cfg.define("CMAKE_C_FLAGS", cflags);
|
||||
let mut cxxflags: OsString = builder
|
||||
let mut cxxflags = ccflags.cxxflags.clone();
|
||||
for flag in builder
|
||||
.cc_handled_clags(target, CLang::Cxx)
|
||||
.into_iter()
|
||||
.chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::Cxx))
|
||||
|
|
@ -798,9 +808,10 @@ fn configure_cmake(
|
|||
.iter()
|
||||
.any(|suppressed_prefix| flag.starts_with(suppressed_prefix))
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
.into();
|
||||
{
|
||||
cxxflags.push(" ");
|
||||
cxxflags.push(flag);
|
||||
}
|
||||
if let Some(ref s) = builder.config.llvm_cxxflags {
|
||||
cxxflags.push(" ");
|
||||
cxxflags.push(s);
|
||||
|
|
@ -811,6 +822,7 @@ fn configure_cmake(
|
|||
if builder.config.llvm_clang_cl.is_some() {
|
||||
cxxflags.push(format!(" --target={target}"));
|
||||
}
|
||||
|
||||
cfg.define("CMAKE_CXX_FLAGS", cxxflags);
|
||||
if let Some(ar) = builder.ar(target)
|
||||
&& ar.is_absolute()
|
||||
|
|
@ -896,6 +908,175 @@ fn get_var(var_base: &str, host: &str, target: &str) -> Option<OsString> {
|
|||
.or_else(|| env::var_os(var_base))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BuiltOmpOffload {
|
||||
/// Path to the omp and offload dylibs.
|
||||
offload: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
impl BuiltOmpOffload {
|
||||
pub fn offload_paths(&self) -> Vec<PathBuf> {
|
||||
self.offload.clone()
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(offload): In an ideal world, we would just enable the offload runtime in our previous LLVM
|
||||
// build step. For now, we still depend on the openmp runtime since we use some of it's API, so we
|
||||
// build both. However, when building those runtimes as part of the LLVM step, then LLVM's cmake
|
||||
// implicitly assumes that Clang has also been build and will try to use it. In the Rust CI, we
|
||||
// don't always build clang (due to compile times), but instead use a slightly older external clang.
|
||||
// LLVM tries to remove this build dependency of offload/openmp on Clang for LLVM-22, so in the
|
||||
// future we might be able to integrate this step into the LLVM step. For now, we instead introduce
|
||||
// a Clang_DIR bootstrap option, which allows us tell CMake to use an external clang for these two
|
||||
// runtimes. This external clang will try to use it's own (older) include dirs when building our
|
||||
// in-tree LLVM submodule, which will cause build failures. To prevent those, we now also
|
||||
// explicitly set our include dirs.
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct OmpOffload {
|
||||
pub target: TargetSelection,
|
||||
}
|
||||
|
||||
impl Step for OmpOffload {
|
||||
type Output = BuiltOmpOffload;
|
||||
const IS_HOST: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
run.path("src/llvm-project/offload")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
run.builder.ensure(OmpOffload { target: run.target });
|
||||
}
|
||||
|
||||
/// Compile OpenMP offload runtimes for `target`.
|
||||
#[allow(unused)]
|
||||
fn run(self, builder: &Builder<'_>) -> Self::Output {
|
||||
if builder.config.dry_run() {
|
||||
return BuiltOmpOffload {
|
||||
offload: vec![builder.config.tempdir().join("llvm-offload-dry-run")],
|
||||
};
|
||||
}
|
||||
let target = self.target;
|
||||
|
||||
let LlvmResult { host_llvm_config, llvm_cmake_dir } =
|
||||
builder.ensure(Llvm { target: self.target });
|
||||
|
||||
// Running cmake twice in the same folder is known to cause issues, like deleting existing
|
||||
// binaries. We therefore write our offload artifacts into it's own folder, instead of
|
||||
// using the llvm build dir.
|
||||
let out_dir = builder.offload_out(target);
|
||||
|
||||
let mut files = vec![];
|
||||
let lib_ext = std::env::consts::DLL_EXTENSION;
|
||||
files.push(out_dir.join("lib").join("libLLVMOffload").with_extension(lib_ext));
|
||||
files.push(out_dir.join("lib").join("libomp").with_extension(lib_ext));
|
||||
files.push(out_dir.join("lib").join("libomptarget").with_extension(lib_ext));
|
||||
|
||||
// Offload/OpenMP are just subfolders of LLVM, so we can use the LLVM sha.
|
||||
static STAMP_HASH_MEMO: OnceLock<String> = OnceLock::new();
|
||||
let smart_stamp_hash = STAMP_HASH_MEMO.get_or_init(|| {
|
||||
generate_smart_stamp_hash(
|
||||
builder,
|
||||
&builder.config.src.join("src/llvm-project/offload"),
|
||||
builder.in_tree_llvm_info.sha().unwrap_or_default(),
|
||||
)
|
||||
});
|
||||
let stamp = BuildStamp::new(&out_dir).with_prefix("offload").add_stamp(smart_stamp_hash);
|
||||
|
||||
trace!("checking build stamp to see if we need to rebuild offload/openmp artifacts");
|
||||
if stamp.is_up_to_date() {
|
||||
trace!(?out_dir, "offload/openmp build artifacts are up to date");
|
||||
if stamp.stamp().is_empty() {
|
||||
builder.info(
|
||||
"Could not determine the Offload submodule commit hash. \
|
||||
Assuming that an Offload rebuild is not necessary.",
|
||||
);
|
||||
builder.info(&format!(
|
||||
"To force Offload/OpenMP to rebuild, remove the file `{}`",
|
||||
stamp.path().display()
|
||||
));
|
||||
}
|
||||
return BuiltOmpOffload { offload: files };
|
||||
}
|
||||
|
||||
trace!(?target, "(re)building offload/openmp artifacts");
|
||||
builder.info(&format!("Building OpenMP/Offload for {target}"));
|
||||
t!(stamp.remove());
|
||||
let _time = helpers::timeit(builder);
|
||||
t!(fs::create_dir_all(&out_dir));
|
||||
|
||||
builder.config.update_submodule("src/llvm-project");
|
||||
let mut cfg = cmake::Config::new(builder.src.join("src/llvm-project/runtimes/"));
|
||||
|
||||
// If we use an external clang as opposed to building our own llvm_clang, than that clang will
|
||||
// come with it's own set of default include directories, which are based on a potentially older
|
||||
// LLVM. This can cause issues, so we overwrite it to include headers based on our
|
||||
// `src/llvm-project` submodule instead.
|
||||
// FIXME(offload): With LLVM-22 we hopefully won't need an external clang anymore.
|
||||
let mut cflags = CcFlags::default();
|
||||
if !builder.config.llvm_clang {
|
||||
let base = builder.llvm_out(target).join("include");
|
||||
let inc_dir = base.display();
|
||||
cflags.push_all(format!(" -I {inc_dir}"));
|
||||
}
|
||||
|
||||
configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), cflags, &[]);
|
||||
|
||||
// Re-use the same flags as llvm to control the level of debug information
|
||||
// generated for offload.
|
||||
let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) {
|
||||
(false, _) => "Debug",
|
||||
(true, false) => "Release",
|
||||
(true, true) => "RelWithDebInfo",
|
||||
};
|
||||
trace!(?profile);
|
||||
|
||||
// OpenMP/Offload builds currently (LLVM-21) still depend on Clang, although there are
|
||||
// intentions to loosen this requirement for LLVM-22. If we were to
|
||||
let clang_dir = if !builder.config.llvm_clang {
|
||||
// We must have an external clang to use.
|
||||
assert!(&builder.build.config.llvm_clang_dir.is_some());
|
||||
builder.build.config.llvm_clang_dir.clone()
|
||||
} else {
|
||||
// No need to specify it, since we use the in-tree clang
|
||||
None
|
||||
};
|
||||
|
||||
// FIXME(offload): Once we move from OMP to Offload (Ol) APIs, we should drop the openmp
|
||||
// runtime to simplify our build. We should also re-evaluate the LLVM_Root and try to get
|
||||
// rid of the Clang_DIR, once we upgrade to LLVM-22.
|
||||
cfg.out_dir(&out_dir)
|
||||
.profile(profile)
|
||||
.env("LLVM_CONFIG_REAL", &host_llvm_config)
|
||||
.define("LLVM_ENABLE_ASSERTIONS", "ON")
|
||||
.define("LLVM_ENABLE_RUNTIMES", "openmp;offload")
|
||||
.define("LLVM_INCLUDE_TESTS", "OFF")
|
||||
.define("OFFLOAD_INCLUDE_TESTS", "OFF")
|
||||
.define("OPENMP_STANDALONE_BUILD", "ON")
|
||||
.define("LLVM_ROOT", builder.llvm_out(target).join("build"))
|
||||
.define("LLVM_DIR", llvm_cmake_dir);
|
||||
if let Some(p) = clang_dir {
|
||||
cfg.define("Clang_DIR", p);
|
||||
}
|
||||
cfg.build();
|
||||
|
||||
t!(stamp.write());
|
||||
|
||||
for p in &files {
|
||||
// At this point, `out_dir` should contain the built <offload-filename>.<dylib-ext>
|
||||
// files.
|
||||
if !p.exists() {
|
||||
eprintln!(
|
||||
"`{p:?}` not found in `{}`. Either the build has failed or Offload was built with a wrong version of LLVM",
|
||||
out_dir.display()
|
||||
);
|
||||
exit!(1);
|
||||
}
|
||||
}
|
||||
BuiltOmpOffload { offload: files }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Enzyme {
|
||||
pub target: TargetSelection,
|
||||
|
|
@ -970,7 +1151,12 @@ impl Step for Enzyme {
|
|||
|
||||
builder.config.update_submodule("src/tools/enzyme");
|
||||
let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/"));
|
||||
configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), &[]);
|
||||
// Enzyme devs maintain upstream compatibility, but only fix deprecations when they are about
|
||||
// to turn into a hard error. As such, Enzyme generates various warnings which could make it
|
||||
// hard to spot more relevant issues.
|
||||
let mut cflags = CcFlags::default();
|
||||
cflags.push_all("-Wno-deprecated");
|
||||
configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), cflags, &[]);
|
||||
|
||||
// Re-use the same flags as llvm to control the level of debug information
|
||||
// generated by Enzyme.
|
||||
|
|
@ -1090,7 +1276,7 @@ impl Step for Lld {
|
|||
ldflags.push_all("-Wl,-rpath,'$ORIGIN/../../../'");
|
||||
}
|
||||
|
||||
configure_cmake(builder, target, &mut cfg, true, ldflags, &[]);
|
||||
configure_cmake(builder, target, &mut cfg, true, ldflags, CcFlags::default(), &[]);
|
||||
configure_llvm(builder, target, &mut cfg);
|
||||
|
||||
// Re-use the same flags as llvm to control the level of debug information
|
||||
|
|
@ -1213,6 +1399,7 @@ impl Step for Sanitizers {
|
|||
&mut cfg,
|
||||
use_compiler_launcher,
|
||||
LdFlags::default(),
|
||||
CcFlags::default(),
|
||||
suppressed_compiler_flag_prefixes,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -2064,6 +2064,10 @@ Please disable assertions with `rust.debug-assertions = false`.
|
|||
cmd.arg("--has-enzyme");
|
||||
}
|
||||
|
||||
if builder.build.config.llvm_offload {
|
||||
cmd.arg("--has-offload");
|
||||
}
|
||||
|
||||
if builder.config.cmd.bless() {
|
||||
cmd.arg("--bless");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ pub struct Config {
|
|||
pub llvm_link_jobs: Option<u32>,
|
||||
pub llvm_version_suffix: Option<String>,
|
||||
pub llvm_use_linker: Option<String>,
|
||||
pub llvm_clang_dir: Option<PathBuf>,
|
||||
pub llvm_allow_old_toolchain: bool,
|
||||
pub llvm_polly: bool,
|
||||
pub llvm_clang: bool,
|
||||
|
|
@ -604,6 +605,7 @@ impl Config {
|
|||
use_linker: llvm_use_linker,
|
||||
allow_old_toolchain: llvm_allow_old_toolchain,
|
||||
offload: llvm_offload,
|
||||
offload_clang_dir: llvm_clang_dir,
|
||||
polly: llvm_polly,
|
||||
clang: llvm_clang,
|
||||
enable_warnings: llvm_enable_warnings,
|
||||
|
|
@ -1361,6 +1363,7 @@ impl Config {
|
|||
llvm_cflags,
|
||||
llvm_clang: llvm_clang.unwrap_or(false),
|
||||
llvm_clang_cl,
|
||||
llvm_clang_dir: llvm_clang_dir.map(PathBuf::from),
|
||||
llvm_cxxflags,
|
||||
llvm_enable_warnings: llvm_enable_warnings.unwrap_or(false),
|
||||
llvm_enzyme: llvm_enzyme.unwrap_or(false),
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ define_config! {
|
|||
allow_old_toolchain: Option<bool> = "allow-old-toolchain",
|
||||
offload: Option<bool> = "offload",
|
||||
polly: Option<bool> = "polly",
|
||||
offload_clang_dir: Option<String> = "offload-clang-dir",
|
||||
clang: Option<bool> = "clang",
|
||||
enable_warnings: Option<bool> = "enable-warnings",
|
||||
download_ci_llvm: Option<StringOrBool> = "download-ci-llvm",
|
||||
|
|
@ -112,6 +113,7 @@ pub fn check_incompatible_options_for_ci_llvm(
|
|||
use_linker,
|
||||
allow_old_toolchain,
|
||||
offload,
|
||||
offload_clang_dir: _,
|
||||
polly,
|
||||
clang,
|
||||
enable_warnings,
|
||||
|
|
|
|||
|
|
@ -975,6 +975,10 @@ impl Build {
|
|||
self.out.join(&*target.triple).join("enzyme")
|
||||
}
|
||||
|
||||
fn offload_out(&self, target: TargetSelection) -> PathBuf {
|
||||
self.out.join(&*target.triple).join("offload")
|
||||
}
|
||||
|
||||
fn lld_out(&self, target: TargetSelection) -> PathBuf {
|
||||
self.out.join(target).join("lld")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -606,4 +606,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
|
|||
severity: ChangeSeverity::Info,
|
||||
summary: "New option `gcc.libgccjit-libs-dir` to specify which libgccjit.so to use per target.",
|
||||
},
|
||||
ChangeInfo {
|
||||
change_id: 148671,
|
||||
severity: ChangeSeverity::Info,
|
||||
summary: "New option `llvm.offload-clang-dir` to allow building an in-tree llvm offload and openmp runtime with an external clang.",
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -213,6 +213,8 @@ settings:
|
|||
that this directive can be overriden with the `--bypass-ignore-backends=[BACKEND]` command line
|
||||
flag.
|
||||
- `needs-backends` — only runs the test if current codegen backend is listed.
|
||||
- `needs-offload` — ignores if our LLVM backend was not built with offload support.
|
||||
- `needs-enzyme` — ignores if our Enzyme submodule was not built.
|
||||
|
||||
The following directives will check LLVM support:
|
||||
|
||||
|
|
|
|||
|
|
@ -625,6 +625,9 @@ pub struct Config {
|
|||
/// Whether to run `enzyme` autodiff tests.
|
||||
pub has_enzyme: bool,
|
||||
|
||||
/// Whether to run `offload` autodiff tests.
|
||||
pub has_offload: bool,
|
||||
|
||||
/// The current Rust channel info.
|
||||
///
|
||||
/// FIXME: treat this more carefully; "stable", "beta" and "nightly" are definitely valid, but
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ pub(crate) fn prepare_conditions(config: &Config) -> PreparedConditions {
|
|||
// FIXME(Zalathar): Support all known binary formats, not just ELF?
|
||||
builder.cond("elf", current.binary_format == "elf", "when the target binary format is ELF");
|
||||
builder.cond("enzyme", config.has_enzyme, "when rustc is built with LLVM Enzyme");
|
||||
builder.cond("offload", config.has_offload, "when rustc is built with LLVM Offload");
|
||||
|
||||
// Technically the locally built compiler uses the "dev" channel rather than the "nightly"
|
||||
// channel, even though most people don't know or won't care about it. To avoid confusion, we
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
|||
"needs-git-hash",
|
||||
"needs-llvm-components",
|
||||
"needs-llvm-zstd",
|
||||
"needs-offload",
|
||||
"needs-profiler-runtime",
|
||||
"needs-relocation-model-pic",
|
||||
"needs-run-enabled",
|
||||
|
|
|
|||
|
|
@ -91,6 +91,11 @@ pub(super) fn handle_needs(
|
|||
condition: config.has_enzyme && config.default_codegen_backend.is_llvm(),
|
||||
ignore_reason: "ignored when LLVM Enzyme is disabled or LLVM is not the default codegen backend",
|
||||
},
|
||||
Need {
|
||||
name: "needs-offload",
|
||||
condition: config.has_offload && config.default_codegen_backend.is_llvm(),
|
||||
ignore_reason: "ignored when LLVM Offload is disabled or LLVM is not the default codegen backend",
|
||||
},
|
||||
Need {
|
||||
name: "needs-run-enabled",
|
||||
condition: config.run_enabled(),
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ fn parse_config(args: Vec<String>) -> Config {
|
|||
.optopt("", "run", "whether to execute run-* tests", "auto | always | never")
|
||||
.optflag("", "ignored", "run tests marked as ignored")
|
||||
.optflag("", "has-enzyme", "run tests that require enzyme")
|
||||
.optflag("", "has-offload", "run tests that require offload")
|
||||
.optflag("", "with-rustc-debug-assertions", "whether rustc was built with debug assertions")
|
||||
.optflag("", "with-std-debug-assertions", "whether std was built with debug assertions")
|
||||
.optflag("", "with-std-remap-debuginfo", "whether std was built with remapping")
|
||||
|
|
@ -299,6 +300,7 @@ fn parse_config(args: Vec<String>) -> Config {
|
|||
let with_std_remap_debuginfo = matches.opt_present("with-std-remap-debuginfo");
|
||||
let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode");
|
||||
let has_enzyme = matches.opt_present("has-enzyme");
|
||||
let has_offload = matches.opt_present("has-offload");
|
||||
let filters = if mode == TestMode::RunMake {
|
||||
matches
|
||||
.free
|
||||
|
|
@ -444,6 +446,7 @@ fn parse_config(args: Vec<String>) -> Config {
|
|||
compare_mode,
|
||||
rustfix_coverage: matches.opt_present("rustfix-coverage"),
|
||||
has_enzyme,
|
||||
has_offload,
|
||||
channel: matches.opt_str("channel").unwrap(),
|
||||
git_hash: matches.opt_present("git-hash"),
|
||||
edition: matches.opt_str("edition").as_deref().map(parse_edition),
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
|
|||
compare_mode: Default::default(),
|
||||
rustfix_coverage: Default::default(),
|
||||
has_enzyme: Default::default(),
|
||||
has_offload: Default::default(),
|
||||
channel: Default::default(),
|
||||
git_hash: Default::default(),
|
||||
cc: Default::default(),
|
||||
|
|
|
|||
|
|
@ -16,3 +16,26 @@ fn main() {
|
|||
Shape::Circl; //~ ERROR no variant
|
||||
Shape::Rombus; //~ ERROR no variant
|
||||
}
|
||||
|
||||
enum Color {
|
||||
Red,
|
||||
Green(()),
|
||||
Blue,
|
||||
Alpha{ a: u8 },
|
||||
}
|
||||
|
||||
fn red() -> Result<Color, ()> {
|
||||
Ok(Color::Redd) //~ ERROR no variant
|
||||
}
|
||||
|
||||
fn green() -> Result<Color, ()> {
|
||||
Ok(Color::Greenn(())) //~ ERROR no variant
|
||||
}
|
||||
|
||||
fn blue() -> Result<Color, ()> {
|
||||
Ok(Color::Blu) //~ ERROR no variant
|
||||
}
|
||||
|
||||
fn alpha() -> Result<Color, ()> {
|
||||
Ok(Color::Alph{ a: 255 }) //~ ERROR no variant
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,64 @@ LL | enum Shape {
|
|||
LL | Shape::Rombus;
|
||||
| ^^^^^^ variant or associated item not found in `Shape`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error[E0599]: no variant or associated item named `Redd` found for enum `Color` in the current scope
|
||||
--> $DIR/suggest-variants.rs:28:13
|
||||
|
|
||||
LL | enum Color {
|
||||
| ---------- variant or associated item `Redd` not found for this enum
|
||||
...
|
||||
LL | Ok(Color::Redd)
|
||||
| ^^^^ variant or associated item not found in `Color`
|
||||
|
|
||||
help: there is a variant with a similar name
|
||||
|
|
||||
LL - Ok(Color::Redd)
|
||||
LL + Ok(Color::Red)
|
||||
|
|
||||
|
||||
error[E0599]: no variant or associated item named `Greenn` found for enum `Color` in the current scope
|
||||
--> $DIR/suggest-variants.rs:32:13
|
||||
|
|
||||
LL | enum Color {
|
||||
| ---------- variant or associated item `Greenn` not found for this enum
|
||||
...
|
||||
LL | Ok(Color::Greenn(()))
|
||||
| ^^^^^^ variant or associated item not found in `Color`
|
||||
|
|
||||
help: there is a variant with a similar name
|
||||
|
|
||||
LL - Ok(Color::Greenn(()))
|
||||
LL + Ok(Color::Green(()))
|
||||
|
|
||||
|
||||
error[E0599]: no variant or associated item named `Blu` found for enum `Color` in the current scope
|
||||
--> $DIR/suggest-variants.rs:36:13
|
||||
|
|
||||
LL | enum Color {
|
||||
| ---------- variant or associated item `Blu` not found for this enum
|
||||
...
|
||||
LL | Ok(Color::Blu)
|
||||
| ^^^ variant or associated item not found in `Color`
|
||||
|
|
||||
help: there is a variant with a similar name
|
||||
|
|
||||
LL | Ok(Color::Blue)
|
||||
| +
|
||||
|
||||
error[E0599]: no variant named `Alph` found for enum `Color`
|
||||
--> $DIR/suggest-variants.rs:40:13
|
||||
|
|
||||
LL | enum Color {
|
||||
| ---------- variant `Alph` not found here
|
||||
...
|
||||
LL | Ok(Color::Alph{ a: 255 })
|
||||
| ^^^^
|
||||
|
|
||||
help: there is a variant with a similar name
|
||||
|
|
||||
LL | Ok(Color::Alpha{ a: 255 })
|
||||
| +
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue