@@ -376,32 +376,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
376
376
}
377
377
378
378
// 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_" ) => {
381
381
use crate :: common:: AtomicOrdering :: * ;
382
382
use crate :: common:: { AtomicRmwBinOp , SynchronizationScope } ;
383
383
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" ) ,
405
396
} ;
406
397
407
398
let invalid_monomorphization = |ty| {
@@ -416,11 +407,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
416
407
) ;
417
408
} ;
418
409
419
- match split [ 1 ] {
410
+ match instruction {
420
411
"cxchg" | "cxchgweak" => {
412
+ let Some ( ( success, failure) ) = ordering. split_once ( '_' ) else {
413
+ bx. sess ( ) . fatal ( "Atomic compare-exchange intrinsic missing failure memory ordering" ) ;
414
+ } ;
421
415
let ty = substs. type_at ( 0 ) ;
422
416
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" ;
424
418
let mut dst = args[ 0 ] . immediate ( ) ;
425
419
let mut cmp = args[ 1 ] . immediate ( ) ;
426
420
let mut src = args[ 2 ] . immediate ( ) ;
@@ -432,7 +426,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
432
426
cmp = bx. ptrtoint ( cmp, bx. type_isize ( ) ) ;
433
427
src = bx. ptrtoint ( src, bx. type_isize ( ) ) ;
434
428
}
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) ;
436
430
let val = bx. extract_value ( pair, 0 ) ;
437
431
let success = bx. extract_value ( pair, 1 ) ;
438
432
let val = bx. from_immediate ( val) ;
@@ -460,11 +454,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
460
454
let llty = bx. type_isize ( ) ;
461
455
let ptr_llty = bx. type_ptr_to ( llty) ;
462
456
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) ;
464
458
// ... and then cast the result back to a pointer
465
459
bx. inttoptr ( result, bx. backend_type ( layout) )
466
460
} 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)
468
462
}
469
463
} else {
470
464
return invalid_monomorphization ( ty) ;
@@ -484,20 +478,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
484
478
ptr = bx. pointercast ( ptr, ptr_llty) ;
485
479
val = bx. ptrtoint ( val, bx. type_isize ( ) ) ;
486
480
}
487
- bx. atomic_store ( val, ptr, order , size) ;
481
+ bx. atomic_store ( val, ptr, parse_ordering ( bx , ordering ) , size) ;
488
482
return ;
489
483
} else {
490
484
return invalid_monomorphization ( ty) ;
491
485
}
492
486
}
493
487
494
488
"fence" => {
495
- bx. atomic_fence ( order , SynchronizationScope :: CrossThread ) ;
489
+ bx. atomic_fence ( parse_ordering ( bx , ordering ) , SynchronizationScope :: CrossThread ) ;
496
490
return ;
497
491
}
498
492
499
493
"singlethreadfence" => {
500
- bx. atomic_fence ( order , SynchronizationScope :: SingleThread ) ;
494
+ bx. atomic_fence ( parse_ordering ( bx , ordering ) , SynchronizationScope :: SingleThread ) ;
501
495
return ;
502
496
}
503
497
@@ -531,7 +525,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
531
525
ptr = bx. pointercast ( ptr, ptr_llty) ;
532
526
val = bx. ptrtoint ( val, bx. type_isize ( ) ) ;
533
527
}
534
- bx. atomic_rmw ( atom_op, ptr, val, order )
528
+ bx. atomic_rmw ( atom_op, ptr, val, parse_ordering ( bx , ordering ) )
535
529
} else {
536
530
return invalid_monomorphization ( ty) ;
537
531
}
0 commit comments