@@ -99,6 +99,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
99
99
let llret_ty = bx. backend_type ( bx. layout_of ( ret_ty) ) ;
100
100
let result = PlaceRef :: new_sized ( llresult, fn_abi. ret . layout ) ;
101
101
102
+ let ret_llval = |bx : & mut Bx , llval| {
103
+ if !fn_abi. ret . is_ignore ( ) {
104
+ if let PassMode :: Cast { .. } = & fn_abi. ret . mode {
105
+ bx. store_to_place ( llval, result. val ) ;
106
+ } else {
107
+ OperandRef :: from_immediate_or_packed_pair ( bx, llval, result. layout )
108
+ . val
109
+ . store ( bx, result) ;
110
+ }
111
+ }
112
+ Ok ( ( ) )
113
+ } ;
114
+
102
115
let llval = match name {
103
116
sym:: abort => {
104
117
bx. abort ( ) ;
@@ -331,6 +344,53 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
331
344
use crate :: common:: AtomicOrdering :: * ;
332
345
use crate :: common:: { AtomicRmwBinOp , SynchronizationScope } ;
333
346
347
+ let invalid_monomorphization = |ty| {
348
+ bx. tcx ( ) . dcx ( ) . emit_err ( InvalidMonomorphization :: BasicIntegerType {
349
+ span,
350
+ name,
351
+ ty,
352
+ } ) ;
353
+ } ;
354
+
355
+ let parse_const_generic_ordering = |ord : ty:: Value < ' tcx > | {
356
+ let discr = ord. valtree . unwrap_branch ( ) [ 0 ] . unwrap_leaf ( ) ;
357
+ let ord = discr. to_atomic_ordering ( ) ;
358
+ // We have to translate from the intrinsic ordering to the backend ordering.
359
+ use std:: intrinsics:: AtomicOrdering ;
360
+ match ord {
361
+ AtomicOrdering :: Relaxed => Relaxed ,
362
+ AtomicOrdering :: Release => Release ,
363
+ AtomicOrdering :: Acquire => Acquire ,
364
+ AtomicOrdering :: AcqRel => AcquireRelease ,
365
+ AtomicOrdering :: SeqCst => SequentiallyConsistent ,
366
+ }
367
+ } ;
368
+
369
+ // Some intrinsics have the ordering already converted to a const generic parameter, we handle those first.
370
+ match name {
371
+ sym:: atomic_load => {
372
+ let ty = fn_args. type_at ( 0 ) ;
373
+ let ordering = fn_args. const_at ( 1 ) . to_value ( ) ;
374
+ if !int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) {
375
+ invalid_monomorphization ( ty) ;
376
+ return Ok ( ( ) ) ;
377
+ }
378
+ let layout = bx. layout_of ( ty) ;
379
+ let source = args[ 0 ] . immediate ( ) ;
380
+ let llval = bx. atomic_load (
381
+ bx. backend_type ( layout) ,
382
+ source,
383
+ parse_const_generic_ordering ( ordering) ,
384
+ layout. size ,
385
+ ) ;
386
+
387
+ return ret_llval ( bx, llval) ;
388
+ }
389
+
390
+ // The rest falls back to below.
391
+ _ => { }
392
+ }
393
+
334
394
let Some ( ( instruction, ordering) ) = atomic. split_once ( '_' ) else {
335
395
bx. sess ( ) . dcx ( ) . emit_fatal ( errors:: MissingMemoryOrdering ) ;
336
396
} ;
@@ -344,14 +404,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
344
404
_ => bx. sess ( ) . dcx ( ) . emit_fatal ( errors:: UnknownAtomicOrdering ) ,
345
405
} ;
346
406
347
- let invalid_monomorphization = |ty| {
348
- bx. tcx ( ) . dcx ( ) . emit_err ( InvalidMonomorphization :: BasicIntegerType {
349
- span,
350
- name,
351
- ty,
352
- } ) ;
353
- } ;
354
-
355
407
match instruction {
356
408
"cxchg" | "cxchgweak" => {
357
409
let Some ( ( success, failure) ) = ordering. split_once ( '_' ) else {
@@ -384,24 +436,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
384
436
return Ok ( ( ) ) ;
385
437
}
386
438
387
- "load" => {
388
- let ty = fn_args. type_at ( 0 ) ;
389
- if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) {
390
- let layout = bx. layout_of ( ty) ;
391
- let size = layout. size ;
392
- let source = args[ 0 ] . immediate ( ) ;
393
- bx. atomic_load (
394
- bx. backend_type ( layout) ,
395
- source,
396
- parse_ordering ( bx, ordering) ,
397
- size,
398
- )
399
- } else {
400
- invalid_monomorphization ( ty) ;
401
- return Ok ( ( ) ) ;
402
- }
403
- }
404
-
405
439
"store" => {
406
440
let ty = fn_args. type_at ( 0 ) ;
407
441
if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) {
@@ -532,16 +566,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
532
566
}
533
567
} ;
534
568
535
- if !fn_abi. ret . is_ignore ( ) {
536
- if let PassMode :: Cast { .. } = & fn_abi. ret . mode {
537
- bx. store_to_place ( llval, result. val ) ;
538
- } else {
539
- OperandRef :: from_immediate_or_packed_pair ( bx, llval, result. layout )
540
- . val
541
- . store ( bx, result) ;
542
- }
543
- }
544
- Ok ( ( ) )
569
+ ret_llval ( bx, llval)
545
570
}
546
571
}
547
572
0 commit comments