Skip to content

Commit e95f632

Browse files
Rollup merge of rust-lang#157181 - scottmcm:no-autodiff-alloca, r=ZuseZ4
autodiff: stop always needing an alloca There will still be one for things that aren't just scalars or scalar pairs. r? @ZuseZ4 cc rust-lang#153250 (the tracking issue for removing intrinsic allocas)
2 parents 0df87b3 + 2f10fd2 commit e95f632

3 files changed

Lines changed: 26 additions & 21 deletions

File tree

compiler/rustc_codegen_llvm/src/builder/autodiff.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ use std::ptr;
33
use rustc_ast::expand::autodiff_attrs::{DiffActivity, DiffMode};
44
use rustc_ast::expand::typetree::FncTree;
55
use rustc_codegen_ssa::common::TypeKind;
6+
use rustc_codegen_ssa::mir::IntrinsicResult;
7+
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
8+
use rustc_codegen_ssa::mir::place::PlaceValue;
69
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods};
710
use rustc_data_structures::thin_vec::ThinVec;
811
use rustc_hir::attrs::RustcAutodiff;
@@ -11,7 +14,7 @@ use rustc_middle::{bug, ty};
1114
use rustc_target::callconv::PassMode;
1215
use tracing::debug;
1316

14-
use crate::builder::{Builder, PlaceRef, UNNAMED};
17+
use crate::builder::{Builder, UNNAMED};
1518
use crate::context::SimpleCx;
1619
use crate::declare::declare_simple_fn;
1720
use crate::llvm::{self, TRUE, Type, Value};
@@ -296,9 +299,10 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>(
296299
ret_ty: &'ll Type,
297300
fn_args: &[&'ll Value],
298301
attrs: &RustcAutodiff,
299-
dest: PlaceRef<'tcx, &'ll Value>,
302+
dest_layout: ty::layout::TyAndLayout<'tcx>,
303+
dest_place: Option<PlaceValue<&'ll Value>>,
300304
fnc_tree: FncTree,
301-
) {
305+
) -> IntrinsicResult<'tcx, &'ll Value> {
302306
// We have to pick the name depending on whether we want forward or reverse mode autodiff.
303307
let mut ad_name: String = match attrs.mode {
304308
DiffMode::Forward => "__enzyme_fwddiff",
@@ -381,11 +385,18 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>(
381385
let call = builder.call(enzyme_ty, None, None, ad_fn, &args, None, None);
382386

383387
let fn_ret_ty = builder.cx.val_ty(call);
384-
if fn_ret_ty != builder.cx.type_void() && fn_ret_ty != builder.cx.type_struct(&[], false) {
388+
if fn_ret_ty == builder.cx.type_void() || fn_ret_ty == builder.cx.type_struct(&[], false) {
385389
// If we return void or an empty struct, then our caller (due to how we generated it)
386390
// does not expect a return value. As such, we have no pointer (or place) into which
387391
// we could store our value, and would store into an undef, which would cause UB.
388392
// As such, we just ignore the return value in those cases.
389-
builder.store_to_place(call, dest.val);
393+
IntrinsicResult::Operand(OperandValue::ZeroSized)
394+
} else if let Some(dest_place) = dest_place {
395+
builder.store_to_place(call, dest_place);
396+
IntrinsicResult::WroteIntoPlace
397+
} else {
398+
IntrinsicResult::Operand(
399+
OperandRef::from_immediate_or_packed_pair(builder, call, dest_layout).val,
400+
)
390401
}
391402
}

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -978,10 +978,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
978978
}
979979

980980
fn intrinsic_call_expects_place_always(&self, name: Symbol) -> bool {
981-
matches!(
982-
name,
983-
sym::autodiff | sym::volatile_load | sym::unaligned_volatile_load | sym::black_box
984-
)
981+
matches!(name, sym::volatile_load | sym::unaligned_volatile_load | sym::black_box)
985982
}
986983
}
987984

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
223223
)
224224
}
225225
sym::autodiff => {
226-
let result = PlaceRef {
227-
val: result_place.unwrap(),
228-
layout: result_layout,
229-
};
230-
codegen_autodiff(self, tcx, instance, args, result);
231-
return IntrinsicResult::WroteIntoPlace;
226+
return codegen_autodiff(self, tcx, instance, args, result_layout, result_place);
232227
}
233228
sym::offload => {
234229
if tcx.sess.opts.unstable_opts.offload.is_empty() {
@@ -1728,8 +1723,9 @@ fn codegen_autodiff<'ll, 'tcx>(
17281723
tcx: TyCtxt<'tcx>,
17291724
instance: ty::Instance<'tcx>,
17301725
args: &[OperandRef<'tcx, &'ll Value>],
1731-
result: PlaceRef<'tcx, &'ll Value>,
1732-
) {
1726+
result_layout: ty::layout::TyAndLayout<'tcx>,
1727+
result_place: Option<PlaceValue<&'ll Value>>,
1728+
) -> IntrinsicResult<'tcx, &'ll Value> {
17331729
if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) {
17341730
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutEnable);
17351731
}
@@ -1769,9 +1765,9 @@ fn codegen_autodiff<'ll, 'tcx>(
17691765
diff_id,
17701766
diff_args
17711767
),
1772-
Err(_) => {
1768+
Err(err) => {
17731769
// An error has already been emitted
1774-
return;
1770+
return IntrinsicResult::Err(err);
17751771
}
17761772
};
17771773

@@ -1802,9 +1798,10 @@ fn codegen_autodiff<'ll, 'tcx>(
18021798
llret_ty,
18031799
&val_arr,
18041800
&diff_attrs,
1805-
result,
1801+
result_layout,
1802+
result_place,
18061803
fnc_tree,
1807-
);
1804+
)
18081805
}
18091806

18101807
// Generates the LLVM code to offload a Rust function to a target device (e.g., GPU).

0 commit comments

Comments
 (0)