@@ -17,6 +17,7 @@ use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv};
17
17
use rustc_middle:: { bug, span_bug} ;
18
18
use rustc_span:: { Span , Symbol , sym} ;
19
19
use rustc_symbol_mangling:: { mangle_internal_symbol, symbol_name_for_instance_in_crate} ;
20
+ use rustc_target:: callconv:: PassMode ;
20
21
use rustc_target:: spec:: PanicStrategy ;
21
22
use tracing:: debug;
22
23
@@ -1136,8 +1137,6 @@ fn codegen_enzyme_autodiff<'ll, 'tcx>(
1136
1137
let ret_ty = sig. output ( ) ;
1137
1138
let llret_ty = bx. layout_of ( ret_ty) . llvm_type ( bx) ;
1138
1139
1139
- let val_arr: Vec < & ' ll Value > = get_args_from_tuple ( bx, args[ 2 ] ) ;
1140
-
1141
1140
// Get source, diff, and attrs
1142
1141
let ( source_id, source_args) = match fn_args. into_type_list ( tcx) [ 0 ] . kind ( ) {
1143
1142
ty:: FnDef ( def_id, source_params) => ( def_id, source_params) ,
@@ -1155,6 +1154,7 @@ fn codegen_enzyme_autodiff<'ll, 'tcx>(
1155
1154
} ;
1156
1155
let fn_diff =
1157
1156
Instance :: try_resolve ( tcx, bx. cx . typing_env ( ) , * diff_id, diff_args) . unwrap ( ) . unwrap ( ) ;
1157
+ let val_arr: Vec < & ' ll Value > = get_args_from_tuple ( bx, args[ 2 ] , fn_diff) ;
1158
1158
let diff_symbol = symbol_name_for_instance_in_crate ( tcx, fn_diff. clone ( ) , LOCAL_CRATE ) ;
1159
1159
1160
1160
let diff_attrs = autodiff_attrs ( tcx, fn_diff. def_id ( ) ) ;
@@ -1181,39 +1181,51 @@ fn codegen_enzyme_autodiff<'ll, 'tcx>(
1181
1181
1182
1182
fn get_args_from_tuple < ' ll , ' tcx > (
1183
1183
bx : & mut Builder < ' _ , ' ll , ' tcx > ,
1184
- op : OperandRef < ' tcx , & ' ll Value > ,
1184
+ tuple_op : OperandRef < ' tcx , & ' ll Value > ,
1185
+ fn_instance : Instance < ' tcx > ,
1185
1186
) -> Vec < & ' ll Value > {
1186
- match op. val {
1187
- OperandValue :: Ref ( ref place_value) => {
1188
- let mut ret_arr = vec ! [ ] ;
1189
- let tuple_place = PlaceRef { val : * place_value, layout : op. layout } ;
1190
-
1191
- for i in 0 ..tuple_place. layout . layout . 0 . fields . count ( ) {
1192
- let field_place = tuple_place. project_field ( bx, i) ;
1193
- let field_layout = tuple_place. layout . field ( bx, i) ;
1194
- let field_ty = field_layout. ty ;
1195
- let llvm_ty = field_layout. llvm_type ( bx. cx ) ;
1196
-
1197
- let field_val = bx. load ( llvm_ty, field_place. val . llval , field_place. val . align ) ;
1198
-
1199
- match field_ty. kind ( ) {
1200
- ty:: Ref ( _, inner_ty, _) if matches ! ( inner_ty. kind( ) , ty:: Slice ( _) ) => {
1201
- let ptr = bx. extract_value ( field_val, 0 ) ;
1202
- let len = bx. extract_value ( field_val, 1 ) ;
1203
- ret_arr. push ( ptr) ;
1204
- ret_arr. push ( len) ;
1187
+ let cx = bx. cx ;
1188
+ let fn_abi = cx. fn_abi_of_instance ( fn_instance, ty:: List :: empty ( ) ) ;
1189
+
1190
+ match tuple_op. val {
1191
+ OperandValue :: Immediate ( val) => vec ! [ val] ,
1192
+ OperandValue :: Pair ( v1, v2) => vec ! [ v1, v2] ,
1193
+ OperandValue :: Ref ( ptr) => {
1194
+ let tuple_place = PlaceRef { val : ptr, layout : tuple_op. layout } ;
1195
+
1196
+ let mut result = Vec :: with_capacity ( fn_abi. args . len ( ) ) ;
1197
+ let mut tuple_index = 0 ;
1198
+
1199
+ for arg in & fn_abi. args {
1200
+ match arg. mode {
1201
+ PassMode :: Ignore => { }
1202
+ PassMode :: Direct ( _) | PassMode :: Cast { .. } => {
1203
+ let field = tuple_place. project_field ( bx, tuple_index) ;
1204
+ let llvm_ty = field. layout . llvm_type ( bx. cx ) ;
1205
+ let val = bx. load ( llvm_ty, field. val . llval , field. val . align ) ;
1206
+ result. push ( val) ;
1207
+ tuple_index += 1 ;
1205
1208
}
1206
- _ => {
1207
- ret_arr. push ( field_val) ;
1209
+ PassMode :: Pair ( _, _) => {
1210
+ let field = tuple_place. project_field ( bx, tuple_index) ;
1211
+ let llvm_ty = field. layout . llvm_type ( bx. cx ) ;
1212
+ let pair_val = bx. load ( llvm_ty, field. val . llval , field. val . align ) ;
1213
+ result. push ( bx. extract_value ( pair_val, 0 ) ) ;
1214
+ result. push ( bx. extract_value ( pair_val, 1 ) ) ;
1215
+ tuple_index += 1 ;
1216
+ }
1217
+ PassMode :: Indirect { .. } => {
1218
+ let field = tuple_place. project_field ( bx, tuple_index) ;
1219
+ result. push ( field. val . llval ) ;
1220
+ tuple_index += 1 ;
1208
1221
}
1209
1222
}
1210
1223
}
1211
1224
1212
- ret_arr
1225
+ result
1213
1226
}
1214
- OperandValue :: Pair ( v1, v2) => vec ! [ v1, v2] ,
1215
- OperandValue :: Immediate ( v) => vec ! [ v] ,
1216
- OperandValue :: ZeroSized => bug ! ( "unexpected `ZeroSized` arg" ) ,
1227
+
1228
+ OperandValue :: ZeroSized => bug ! ( "unexpected ZeroSized argument in get_args_from_tuple" ) ,
1217
1229
}
1218
1230
}
1219
1231
0 commit comments