@@ -376,32 +376,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
376376 }
377377
378378 // This requires that atomic intrinsics follow a specific naming pattern:
379- // "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
380- name if name_str. starts_with ( "atomic_" ) => {
379+ // "atomic_<operation>[_<ordering>]"
380+ name if let Some ( atomic ) = name_str. strip_prefix ( "atomic_" ) => {
381381 use crate :: common:: AtomicOrdering :: * ;
382382 use crate :: common:: { AtomicRmwBinOp , SynchronizationScope } ;
383383
384- let split: Vec < _ > = name_str. split ( '_' ) . collect ( ) ;
385-
386- let is_cxchg = split[ 1 ] == "cxchg" || split[ 1 ] == "cxchgweak" ;
387- let ( order, failorder) = match split. len ( ) {
388- 2 => ( SequentiallyConsistent , SequentiallyConsistent ) ,
389- 3 => match split[ 2 ] {
390- "unordered" => ( Unordered , Unordered ) ,
391- "relaxed" => ( Relaxed , Relaxed ) ,
392- "acq" => ( Acquire , Acquire ) ,
393- "rel" => ( Release , Relaxed ) ,
394- "acqrel" => ( AcquireRelease , Acquire ) ,
395- "failrelaxed" if is_cxchg => ( SequentiallyConsistent , Relaxed ) ,
396- "failacq" if is_cxchg => ( SequentiallyConsistent , Acquire ) ,
397- _ => bx. sess ( ) . fatal ( "unknown ordering in atomic intrinsic" ) ,
398- } ,
399- 4 => match ( split[ 2 ] , split[ 3 ] ) {
400- ( "acq" , "failrelaxed" ) if is_cxchg => ( Acquire , Relaxed ) ,
401- ( "acqrel" , "failrelaxed" ) if is_cxchg => ( AcquireRelease , Relaxed ) ,
402- _ => bx. sess ( ) . fatal ( "unknown ordering in atomic intrinsic" ) ,
403- } ,
404- _ => bx. sess ( ) . fatal ( "Atomic intrinsic not in correct format" ) ,
384+ let Some ( ( instruction, ordering) ) = atomic. split_once ( '_' ) else {
385+ bx. sess ( ) . fatal ( "Atomic intrinsic missing memory ordering" ) ;
386+ } ;
387+
388+ let parse_ordering = |bx : & Bx , s| match s {
389+ "unordered" => Unordered ,
390+ "relaxed" => Relaxed ,
391+ "acquire" => Acquire ,
392+ "release" => Release ,
393+ "acqrel" => AcquireRelease ,
394+ "seqcst" => SequentiallyConsistent ,
395+ _ => bx. sess ( ) . fatal ( "unknown ordering in atomic intrinsic" ) ,
405396 } ;
406397
407398 let invalid_monomorphization = |ty| {
@@ -416,11 +407,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
416407 ) ;
417408 } ;
418409
419- match split [ 1 ] {
410+ match instruction {
420411 "cxchg" | "cxchgweak" => {
412+ let Some ( ( success, failure) ) = ordering. split_once ( '_' ) else {
413+ bx. sess ( ) . fatal ( "Atomic compare-exchange intrinsic missing failure memory ordering" ) ;
414+ } ;
421415 let ty = substs. type_at ( 0 ) ;
422416 if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_unsafe_ptr ( ) {
423- let weak = split [ 1 ] == "cxchgweak" ;
417+ let weak = instruction == "cxchgweak" ;
424418 let mut dst = args[ 0 ] . immediate ( ) ;
425419 let mut cmp = args[ 1 ] . immediate ( ) ;
426420 let mut src = args[ 2 ] . immediate ( ) ;
@@ -432,7 +426,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
432426 cmp = bx. ptrtoint ( cmp, bx. type_isize ( ) ) ;
433427 src = bx. ptrtoint ( src, bx. type_isize ( ) ) ;
434428 }
435- let pair = bx. atomic_cmpxchg ( dst, cmp, src, order , failorder , weak) ;
429+ let pair = bx. atomic_cmpxchg ( dst, cmp, src, parse_ordering ( bx , success ) , parse_ordering ( bx , failure ) , weak) ;
436430 let val = bx. extract_value ( pair, 0 ) ;
437431 let success = bx. extract_value ( pair, 1 ) ;
438432 let val = bx. from_immediate ( val) ;
@@ -460,11 +454,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
460454 let llty = bx. type_isize ( ) ;
461455 let ptr_llty = bx. type_ptr_to ( llty) ;
462456 source = bx. pointercast ( source, ptr_llty) ;
463- let result = bx. atomic_load ( llty, source, order , size) ;
457+ let result = bx. atomic_load ( llty, source, parse_ordering ( bx , ordering ) , size) ;
464458 // ... and then cast the result back to a pointer
465459 bx. inttoptr ( result, bx. backend_type ( layout) )
466460 } else {
467- bx. atomic_load ( bx. backend_type ( layout) , source, order , size)
461+ bx. atomic_load ( bx. backend_type ( layout) , source, parse_ordering ( bx , ordering ) , size)
468462 }
469463 } else {
470464 return invalid_monomorphization ( ty) ;
@@ -484,20 +478,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
484478 ptr = bx. pointercast ( ptr, ptr_llty) ;
485479 val = bx. ptrtoint ( val, bx. type_isize ( ) ) ;
486480 }
487- bx. atomic_store ( val, ptr, order , size) ;
481+ bx. atomic_store ( val, ptr, parse_ordering ( bx , ordering ) , size) ;
488482 return ;
489483 } else {
490484 return invalid_monomorphization ( ty) ;
491485 }
492486 }
493487
494488 "fence" => {
495- bx. atomic_fence ( order , SynchronizationScope :: CrossThread ) ;
489+ bx. atomic_fence ( parse_ordering ( bx , ordering ) , SynchronizationScope :: CrossThread ) ;
496490 return ;
497491 }
498492
499493 "singlethreadfence" => {
500- bx. atomic_fence ( order , SynchronizationScope :: SingleThread ) ;
494+ bx. atomic_fence ( parse_ordering ( bx , ordering ) , SynchronizationScope :: SingleThread ) ;
501495 return ;
502496 }
503497
@@ -531,7 +525,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
531525 ptr = bx. pointercast ( ptr, ptr_llty) ;
532526 val = bx. ptrtoint ( val, bx. type_isize ( ) ) ;
533527 }
534- bx. atomic_rmw ( atom_op, ptr, val, order )
528+ bx. atomic_rmw ( atom_op, ptr, val, parse_ordering ( bx , ordering ) )
535529 } else {
536530 return invalid_monomorphization ( ty) ;
537531 }
0 commit comments