From 909a480532d193e3d736d5e5925632adcf73456f Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Mon, 17 Nov 2025 01:50:10 -0500 Subject: [PATCH] rlib handling --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 15 +++++++++++++-- .../src/cross_crate_inline.rs | 4 ++++ tests/ui/autodiff/autodiff_in_rlib.rs | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 tests/ui/autodiff/autodiff_in_rlib.rs diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 84fc6ebbc3172..73d1aed564f49 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -21,6 +21,8 @@ use rustc_target::callconv::PassMode; use rustc_target::spec::Os; use tracing::debug; +use rustc_session::config::CrateType; + use crate::abi::FnAbiLlvmExt; use crate::builder::Builder; use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call}; @@ -1136,8 +1138,17 @@ fn codegen_autodiff<'ll, 'tcx>( if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) { let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutEnable); } - if tcx.sess.lto() != rustc_session::config::Lto::Fat { - let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto); + + let ct = tcx.crate_types(); + let lto = tcx.sess.lto(); + if ct.len() == 1 && ct.contains(&CrateType::Executable) { + if lto != rustc_session::config::Lto::Fat { + let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto); + } + } else { + if lto != rustc_session::config::Lto::Fat && !tcx.sess.opts.cg.linker_plugin_lto.enabled(){ + let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto); + } } let fn_args = instance.args; diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 7fc9fb9cca2d7..d15205dcf3cca 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -34,6 +34,10 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { return true; } + if tcx.has_attr(def_id, sym::autodiff_forward) || tcx.has_attr(def_id, sym::autodiff_reverse) || tcx.has_attr(def_id, sym::rustc_autodiff) { + return true; + } + if tcx.has_attr(def_id, sym::rustc_intrinsic) { // Intrinsic fallback bodies are always cross-crate inlineable. // To ensure that the MIR inliner doesn't cluelessly try to inline fallback diff --git a/tests/ui/autodiff/autodiff_in_rlib.rs b/tests/ui/autodiff/autodiff_in_rlib.rs new file mode 100644 index 0000000000000..1a96a6ff1a77c --- /dev/null +++ b/tests/ui/autodiff/autodiff_in_rlib.rs @@ -0,0 +1,17 @@ +#![feature(autodiff)] +#![crate_type = "rlib"] +//@ needs-enzyme +//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat +//@ build-fail + +// We test that we fail to compile if a user applied an autodiff_ macro in src/lib.rs, +// since autodiff doesn't work in libraries yet. In the past we used to just return zeros in the +// autodiffed functions, which is obviously confusing and wrong, so erroring is an improvement. + +use std::autodiff::autodiff_reverse; +//~? ERROR: using the autodiff feature with library builds is not yet supported + +#[autodiff_reverse(d_square, Duplicated, Active)] +pub fn square(x: &f64) -> f64 { + *x * *x +}