Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #138791

Merged
merged 29 commits into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c261426
add `naked_functions_target_feature` unstable feature
folkertdev Mar 16, 2025
03ece26
update tests
ZuseZ4 Mar 17, 2025
b77590c
Use llvm_runtimes for compiler-rt
daltenty Mar 17, 2025
f5c37c3
[NFC] split up gen_body_helper
ZuseZ4 Mar 17, 2025
f9d0a14
resolve repeated attribute fixme
ZuseZ4 Mar 17, 2025
5f7ff88
[NFC] use outer_normal_attr helper
ZuseZ4 Mar 17, 2025
f4c2978
[NFC] extract autodiff call lowering in cg_llvm into own function
ZuseZ4 Mar 17, 2025
47c07ed
[NFC] simplify matching
ZuseZ4 Mar 17, 2025
81b2d55
addressing feedback, removing unused arg
ZuseZ4 Mar 18, 2025
a3669b8
updated compiler tests for rustc_intrinsic'
BLANKatGITHUB Mar 12, 2025
599dc82
Simplify `get_git_modified_files`
Kobzol Mar 16, 2025
2139a78
Fix bug in `get_git_modified_files`
Kobzol Mar 16, 2025
b24dc75
Respect `--src` bootstrap flag
Kobzol Mar 19, 2025
9b88fd0
Update GCC submodule
Kobzol Mar 19, 2025
7c085f7
add rustc_macro_edition_2021
jdonszelmann Mar 19, 2025
93d5ca8
Pin tests.
m-ou-se Mar 19, 2025
25896cc
Add cfg(not(bootstrap)) for new test.
m-ou-se Mar 19, 2025
20432c9
Use explicit cpu in some asm and codegen tests.
Mar 19, 2025
0577300
Address review comments.
m-ou-se Mar 19, 2025
cafd238
tests: accept some noise from LLVM 21 in symbols-all-mangled
durin42 Mar 18, 2025
f7f2870
Rollup merge of #138364 - BLANKatGITHUB:compiler, r=RalfJung
matthiaskrgr Mar 21, 2025
c354a97
Rollup merge of #138570 - folkertdev:naked-function-target-feature-ga…
matthiaskrgr Mar 21, 2025
a8f0c6b
Rollup merge of #138623 - daltenty:daltenty/fix-compiler-rt, r=Kobzol
matthiaskrgr Mar 21, 2025
0c594da
Rollup merge of #138627 - EnzymeAD:autodiff-cleanups, r=oli-obk
matthiaskrgr Mar 21, 2025
015df66
Rollup merge of #138669 - durin42:llvm-21-anon-func-unmangled, r=bjorn3
matthiaskrgr Mar 21, 2025
ed3a39d
Rollup merge of #138706 - Kobzol:bootstrap-git-refactor-1, r=onur-ozkan
matthiaskrgr Mar 21, 2025
a27b21e
Rollup merge of #138709 - Kobzol:update-gcc, r=GuillaumeGomez
matthiaskrgr Mar 21, 2025
7c2475e
Rollup merge of #138717 - jdonszelmann:pin-macro, r=WaffleLapkin
matthiaskrgr Mar 21, 2025
bc46c98
Rollup merge of #138721 - jchecahi:tests-explicit-cpus, r=tgross35
matthiaskrgr Mar 21, 2025
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: 1 addition & 0 deletions compiler/rustc_attr_data_structures/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ pub enum AttributeKind {
},
MacroTransparency(Transparency),
Repr(ThinVec<(ReprAttr, Span)>),
RustcMacroEdition2021,
Stability {
stability: Stability,
/// Span of the `#[stable(...)]` or `#[unstable(...)]` attribute
Expand Down
11 changes: 4 additions & 7 deletions compiler/rustc_attr_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,21 +182,18 @@ macro_rules! find_attr {
}};

($attributes_list: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
fn check_attribute_iterator<'a>(_: &'_ impl IntoIterator<Item = &'a rustc_hir::Attribute>) {}
check_attribute_iterator(&$attributes_list);

let find_attribute = |iter| {
'done: {
for i in $attributes_list {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed($pattern) $(if $guard)? => {
return Some($e);
break 'done Some($e);
}
_ => {}
}
}

None
};
find_attribute($attributes_list)
}
}};
}
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/src/attributes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub(crate) mod cfg;
pub(crate) mod confusables;
pub(crate) mod deprecation;
pub(crate) mod repr;
pub(crate) mod rustc;
pub(crate) mod stability;
pub(crate) mod transparency;
pub(crate) mod util;
Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/rustc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_span::sym;

use super::{AcceptContext, SingleAttributeParser};
use crate::parser::ArgParser;

pub(crate) struct RustcMacroEdition2021Parser;

// FIXME(jdonszelmann): make these proper diagnostics
impl SingleAttributeParser for RustcMacroEdition2021Parser {
const PATH: &'static [rustc_span::Symbol] = &[sym::rustc_macro_edition_2021];

fn on_duplicate(_cx: &crate::context::AcceptContext<'_>, _first_span: rustc_span::Span) {}

fn convert(_cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind> {
assert!(args.no_args());
Some(AttributeKind::RustcMacroEdition2021)
}
}
2 changes: 2 additions & 0 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInterna
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::repr::ReprParser;
use crate::attributes::rustc::RustcMacroEdition2021Parser;
use crate::attributes::stability::{
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
};
Expand Down Expand Up @@ -76,6 +77,7 @@ attribute_groups!(
// tidy-alphabetical-start
Single<ConstStabilityIndirectParser>,
Single<DeprecationParser>,
Single<RustcMacroEdition2021Parser>,
Single<TransparencyParser>,
// tidy-alphabetical-end
];
Expand Down
153 changes: 95 additions & 58 deletions compiler/rustc_builtin_macros/src/autodiff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ mod llvm_enzyme {

use crate::errors;

pub(crate) fn outer_normal_attr(
kind: &P<rustc_ast::NormalAttr>,
id: rustc_ast::AttrId,
span: Span,
) -> rustc_ast::Attribute {
let style = rustc_ast::AttrStyle::Outer;
let kind = rustc_ast::AttrKind::Normal(kind.clone());
rustc_ast::Attribute { kind, id, style, span }
}

// If we have a default `()` return type or explicitley `()` return type,
// then we often can skip doing some work.
fn has_ret(ty: &FnRetTy) -> bool {
Expand Down Expand Up @@ -224,20 +234,8 @@ mod llvm_enzyme {
.filter(|a| **a == DiffActivity::Active || **a == DiffActivity::ActiveOnly)
.count() as u32;
let (d_sig, new_args, idents, errored) = gen_enzyme_decl(ecx, &sig, &x, span);
let new_decl_span = d_sig.span;
let d_body = gen_enzyme_body(
ecx,
&x,
n_active,
&sig,
&d_sig,
primal,
&new_args,
span,
sig_span,
new_decl_span,
idents,
errored,
ecx, &x, n_active, &sig, &d_sig, primal, &new_args, span, sig_span, idents, errored,
);
let d_ident = first_ident(&meta_item_vec[0]);

Expand Down Expand Up @@ -270,36 +268,39 @@ mod llvm_enzyme {
};
let inline_never_attr = P(ast::NormalAttr { item: inline_item, tokens: None });
let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id();
let attr: ast::Attribute = ast::Attribute {
kind: ast::AttrKind::Normal(rustc_ad_attr.clone()),
id: new_id,
style: ast::AttrStyle::Outer,
span,
};
let attr = outer_normal_attr(&rustc_ad_attr, new_id, span);
let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id();
let inline_never: ast::Attribute = ast::Attribute {
kind: ast::AttrKind::Normal(inline_never_attr),
id: new_id,
style: ast::AttrStyle::Outer,
span,
};
let inline_never = outer_normal_attr(&inline_never_attr, new_id, span);

// We're avoid duplicating the attributes `#[rustc_autodiff]` and `#[inline(never)]`.
fn same_attribute(attr: &ast::AttrKind, item: &ast::AttrKind) -> bool {
match (attr, item) {
(ast::AttrKind::Normal(a), ast::AttrKind::Normal(b)) => {
let a = &a.item.path;
let b = &b.item.path;
a.segments.len() == b.segments.len()
&& a.segments.iter().zip(b.segments.iter()).all(|(a, b)| a.ident == b.ident)
}
_ => false,
}
}

// Don't add it multiple times:
let orig_annotatable: Annotatable = match item {
Annotatable::Item(ref mut iitem) => {
if !iitem.attrs.iter().any(|a| a.id == attr.id) {
if !iitem.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
iitem.attrs.push(attr);
}
if !iitem.attrs.iter().any(|a| a.id == inline_never.id) {
if !iitem.attrs.iter().any(|a| same_attribute(&a.kind, &inline_never.kind)) {
iitem.attrs.push(inline_never.clone());
}
Annotatable::Item(iitem.clone())
}
Annotatable::AssocItem(ref mut assoc_item, i @ Impl) => {
if !assoc_item.attrs.iter().any(|a| a.id == attr.id) {
if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
assoc_item.attrs.push(attr);
}
if !assoc_item.attrs.iter().any(|a| a.id == inline_never.id) {
if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &inline_never.kind)) {
assoc_item.attrs.push(inline_never.clone());
}
Annotatable::AssocItem(assoc_item.clone(), i)
Expand All @@ -314,13 +315,7 @@ mod llvm_enzyme {
delim: rustc_ast::token::Delimiter::Parenthesis,
tokens: ts,
});
let d_attr: ast::Attribute = ast::Attribute {
kind: ast::AttrKind::Normal(rustc_ad_attr.clone()),
id: new_id,
style: ast::AttrStyle::Outer,
span,
};

let d_attr = outer_normal_attr(&rustc_ad_attr, new_id, span);
let d_annotatable = if is_impl {
let assoc_item: AssocItemKind = ast::AssocItemKind::Fn(asdf);
let d_fn = P(ast::AssocItem {
Expand Down Expand Up @@ -361,30 +356,27 @@ mod llvm_enzyme {
ty
}

/// We only want this function to type-check, since we will replace the body
/// later on llvm level. Using `loop {}` does not cover all return types anymore,
/// so instead we build something that should pass. We also add a inline_asm
/// line, as one more barrier for rustc to prevent inlining of this function.
/// FIXME(ZuseZ4): We still have cases of incorrect inlining across modules, see
/// <https://github.com/EnzymeAD/rust/issues/173>, so this isn't sufficient.
/// It also triggers an Enzyme crash if we due to a bug ever try to differentiate
/// this function (which should never happen, since it is only a placeholder).
/// Finally, we also add back_box usages of all input arguments, to prevent rustc
/// from optimizing any arguments away.
fn gen_enzyme_body(
// Will generate a body of the type:
// ```
// {
// unsafe {
// asm!("NOP");
// }
// ::core::hint::black_box(primal(args));
// ::core::hint::black_box((args, ret));
// <This part remains to be done by following function>
// }
// ```
fn init_body_helper(
ecx: &ExtCtxt<'_>,
x: &AutoDiffAttrs,
n_active: u32,
sig: &ast::FnSig,
d_sig: &ast::FnSig,
span: Span,
primal: Ident,
new_names: &[String],
span: Span,
sig_span: Span,
new_decl_span: Span,
idents: Vec<Ident>,
idents: &[Ident],
errored: bool,
) -> P<ast::Block> {
) -> (P<ast::Block>, P<ast::Expr>, P<ast::Expr>, P<ast::Expr>) {
let blackbox_path = ecx.std_path(&[sym::hint, sym::black_box]);
let noop = ast::InlineAsm {
asm_macro: ast::AsmMacro::Asm,
Expand Down Expand Up @@ -433,6 +425,51 @@ mod llvm_enzyme {
}
body.stmts.push(ecx.stmt_semi(black_box_remaining_args));

(body, primal_call, black_box_primal_call, blackbox_call_expr)
}

/// We only want this function to type-check, since we will replace the body
/// later on llvm level. Using `loop {}` does not cover all return types anymore,
/// so instead we manually build something that should pass the type checker.
/// We also add a inline_asm line, as one more barrier for rustc to prevent inlining
/// or const propagation. inline_asm will also triggers an Enzyme crash if due to another
/// bug would ever try to accidentially differentiate this placeholder function body.
/// Finally, we also add back_box usages of all input arguments, to prevent rustc
/// from optimizing any arguments away.
fn gen_enzyme_body(
ecx: &ExtCtxt<'_>,
x: &AutoDiffAttrs,
n_active: u32,
sig: &ast::FnSig,
d_sig: &ast::FnSig,
primal: Ident,
new_names: &[String],
span: Span,
sig_span: Span,
idents: Vec<Ident>,
errored: bool,
) -> P<ast::Block> {
let new_decl_span = d_sig.span;

// Just adding some default inline-asm and black_box usages to prevent early inlining
// and optimizations which alter the function signature.
//
// The bb_primal_call is the black_box call of the primal function. We keep it around,
// since it has the convenient property of returning the type of the primal function,
// Remember, we only care to match types here.
// No matter which return we pick, we always wrap it into a std::hint::black_box call,
// to prevent rustc from propagating it into the caller.
let (mut body, primal_call, bb_primal_call, bb_call_expr) = init_body_helper(
ecx,
span,
primal,
new_names,
sig_span,
new_decl_span,
&idents,
errored,
);

if !has_ret(&d_sig.decl.output) {
// there is no return type that we have to match, () works fine.
return body;
Expand All @@ -444,7 +481,7 @@ mod llvm_enzyme {

if primal_ret && n_active == 0 && x.mode.is_rev() {
// We only have the primal ret.
body.stmts.push(ecx.stmt_expr(black_box_primal_call));
body.stmts.push(ecx.stmt_expr(bb_primal_call));
return body;
}

Expand Down Expand Up @@ -536,11 +573,11 @@ mod llvm_enzyme {
return body;
}
[arg] => {
ret = ecx.expr_call(new_decl_span, blackbox_call_expr, thin_vec![arg.clone()]);
ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![arg.clone()]);
}
args => {
let ret_tuple: P<ast::Expr> = ecx.expr_tuple(span, args.into());
ret = ecx.expr_call(new_decl_span, blackbox_call_expr, thin_vec![ret_tuple]);
ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![ret_tuple]);
}
}
assert!(has_ret(&d_sig.decl.output));
Expand All @@ -553,7 +590,7 @@ mod llvm_enzyme {
ecx: &ExtCtxt<'_>,
span: Span,
primal: Ident,
idents: Vec<Ident>,
idents: &[Ident],
) -> P<ast::Expr> {
let has_self = idents.len() > 0 && idents[0].name == kw::SelfLower;
if has_self {
Expand Down
Loading
Loading