@@ -99,6 +99,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
99
99
100
100
let llret_ty = bx. backend_type ( bx. layout_of ( ret_ty) ) ;
101
101
102
+ let ret_llval = |bx : & mut Bx , llval| {
103
+ if result. layout . ty . is_bool ( ) {
104
+ OperandRef :: from_immediate_or_packed_pair ( bx, llval, result. layout )
105
+ . val
106
+ . store ( bx, result) ;
107
+ } else if !result. layout . ty . is_unit ( ) {
108
+ bx. store_to_place ( llval, result. val ) ;
109
+ }
110
+ Ok ( ( ) )
111
+ } ;
112
+
102
113
let llval = match name {
103
114
sym:: abort => {
104
115
bx. abort ( ) ;
@@ -337,6 +348,53 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
337
348
use crate :: common:: AtomicOrdering :: * ;
338
349
use crate :: common:: { AtomicRmwBinOp , SynchronizationScope } ;
339
350
351
+ let invalid_monomorphization = |ty| {
352
+ bx. tcx ( ) . dcx ( ) . emit_err ( InvalidMonomorphization :: BasicIntegerType {
353
+ span,
354
+ name,
355
+ ty,
356
+ } ) ;
357
+ } ;
358
+
359
+ let parse_const_generic_ordering = |ord : ty:: Value < ' tcx > | {
360
+ let discr = ord. valtree . unwrap_branch ( ) [ 0 ] . unwrap_leaf ( ) ;
361
+ let ord = discr. to_atomic_ordering ( ) ;
362
+ // We have to translate from the intrinsic ordering to the backend ordering.
363
+ use rustc_middle:: ty:: AtomicOrdering ;
364
+ match ord {
365
+ AtomicOrdering :: Relaxed => Relaxed ,
366
+ AtomicOrdering :: Release => Release ,
367
+ AtomicOrdering :: Acquire => Acquire ,
368
+ AtomicOrdering :: AcqRel => AcquireRelease ,
369
+ AtomicOrdering :: SeqCst => SequentiallyConsistent ,
370
+ }
371
+ } ;
372
+
373
+ // Some intrinsics have the ordering already converted to a const generic parameter, we handle those first.
374
+ match name {
375
+ sym:: atomic_load => {
376
+ let ty = fn_args. type_at ( 0 ) ;
377
+ let ordering = fn_args. const_at ( 1 ) . to_value ( ) ;
378
+ if !( int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) ) {
379
+ invalid_monomorphization ( ty) ;
380
+ return Ok ( ( ) ) ;
381
+ }
382
+ let layout = bx. layout_of ( ty) ;
383
+ let source = args[ 0 ] . immediate ( ) ;
384
+ let llval = bx. atomic_load (
385
+ bx. backend_type ( layout) ,
386
+ source,
387
+ parse_const_generic_ordering ( ordering) ,
388
+ layout. size ,
389
+ ) ;
390
+
391
+ return ret_llval ( bx, llval) ;
392
+ }
393
+
394
+ // The rest falls back to below.
395
+ _ => { }
396
+ }
397
+
340
398
let Some ( ( instruction, ordering) ) = atomic. split_once ( '_' ) else {
341
399
bx. sess ( ) . dcx ( ) . emit_fatal ( errors:: MissingMemoryOrdering ) ;
342
400
} ;
@@ -350,14 +408,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
350
408
_ => bx. sess ( ) . dcx ( ) . emit_fatal ( errors:: UnknownAtomicOrdering ) ,
351
409
} ;
352
410
353
- let invalid_monomorphization = |ty| {
354
- bx. tcx ( ) . dcx ( ) . emit_err ( InvalidMonomorphization :: BasicIntegerType {
355
- span,
356
- name,
357
- ty,
358
- } ) ;
359
- } ;
360
-
361
411
match instruction {
362
412
"cxchg" | "cxchgweak" => {
363
413
let Some ( ( success, failure) ) = ordering. split_once ( '_' ) else {
@@ -390,24 +440,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
390
440
return Ok ( ( ) ) ;
391
441
}
392
442
393
- "load" => {
394
- let ty = fn_args. type_at ( 0 ) ;
395
- if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) {
396
- let layout = bx. layout_of ( ty) ;
397
- let size = layout. size ;
398
- let source = args[ 0 ] . immediate ( ) ;
399
- bx. atomic_load (
400
- bx. backend_type ( layout) ,
401
- source,
402
- parse_ordering ( bx, ordering) ,
403
- size,
404
- )
405
- } else {
406
- invalid_monomorphization ( ty) ;
407
- return Ok ( ( ) ) ;
408
- }
409
- }
410
-
411
443
"store" => {
412
444
let ty = fn_args. type_at ( 0 ) ;
413
445
if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) {
@@ -538,14 +570,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
538
570
}
539
571
} ;
540
572
541
- if result. layout . ty . is_bool ( ) {
542
- OperandRef :: from_immediate_or_packed_pair ( bx, llval, result. layout )
543
- . val
544
- . store ( bx, result) ;
545
- } else if !result. layout . ty . is_unit ( ) {
546
- bx. store_to_place ( llval, result. val ) ;
547
- }
548
- Ok ( ( ) )
573
+ ret_llval ( bx, llval)
549
574
}
550
575
}
551
576
0 commit comments