@@ -99,6 +99,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
9999
100100 let llret_ty = bx. backend_type ( bx. layout_of ( ret_ty) ) ;
101101
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+
102113 let llval = match name {
103114 sym:: abort => {
104115 bx. abort ( ) ;
@@ -337,6 +348,53 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
337348 use crate :: common:: AtomicOrdering :: * ;
338349 use crate :: common:: { AtomicRmwBinOp , SynchronizationScope } ;
339350
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+
340398 let Some ( ( instruction, ordering) ) = atomic. split_once ( '_' ) else {
341399 bx. sess ( ) . dcx ( ) . emit_fatal ( errors:: MissingMemoryOrdering ) ;
342400 } ;
@@ -350,14 +408,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
350408 _ => bx. sess ( ) . dcx ( ) . emit_fatal ( errors:: UnknownAtomicOrdering ) ,
351409 } ;
352410
353- let invalid_monomorphization = |ty| {
354- bx. tcx ( ) . dcx ( ) . emit_err ( InvalidMonomorphization :: BasicIntegerType {
355- span,
356- name,
357- ty,
358- } ) ;
359- } ;
360-
361411 match instruction {
362412 "cxchg" | "cxchgweak" => {
363413 let Some ( ( success, failure) ) = ordering. split_once ( '_' ) else {
@@ -390,24 +440,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
390440 return Ok ( ( ) ) ;
391441 }
392442
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-
411443 "store" => {
412444 let ty = fn_args. type_at ( 0 ) ;
413445 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> {
538570 }
539571 } ;
540572
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)
549574 }
550575}
551576
0 commit comments