@@ -439,14 +439,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
439
439
let ty = substs. type_at ( 0 ) ;
440
440
if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_unsafe_ptr ( ) {
441
441
let weak = split[ 1 ] == "cxchgweak" ;
442
- let pair = bx. atomic_cmpxchg (
443
- args[ 0 ] . immediate ( ) ,
444
- args[ 1 ] . immediate ( ) ,
445
- args[ 2 ] . immediate ( ) ,
446
- order,
447
- failorder,
448
- weak,
449
- ) ;
442
+ let mut dst = args[ 0 ] . immediate ( ) ;
443
+ let mut cmp = args[ 1 ] . immediate ( ) ;
444
+ let mut src = args[ 2 ] . immediate ( ) ;
445
+ if ty. is_unsafe_ptr ( ) {
446
+ // Some platforms do not support atomic operations on pointers,
447
+ // so we cast to integer first.
448
+ let ptr_llty = bx. type_ptr_to ( bx. type_isize ( ) ) ;
449
+ dst = bx. pointercast ( dst, ptr_llty) ;
450
+ cmp = bx. ptrtoint ( cmp, bx. type_isize ( ) ) ;
451
+ src = bx. ptrtoint ( src, bx. type_isize ( ) ) ;
452
+ }
453
+ let pair = bx. atomic_cmpxchg ( dst, cmp, src, order, failorder, weak) ;
450
454
let val = bx. extract_value ( pair, 0 ) ;
451
455
let success = bx. extract_value ( pair, 1 ) ;
452
456
let val = bx. from_immediate ( val) ;
@@ -465,8 +469,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
465
469
"load" => {
466
470
let ty = substs. type_at ( 0 ) ;
467
471
if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_unsafe_ptr ( ) {
468
- let size = bx. layout_of ( ty) . size ;
469
- bx. atomic_load ( args[ 0 ] . immediate ( ) , order, size)
472
+ let layout = bx. layout_of ( ty) ;
473
+ let size = layout. size ;
474
+ let mut source = args[ 0 ] . immediate ( ) ;
475
+ if ty. is_unsafe_ptr ( ) {
476
+ // Some platforms do not support atomic operations on pointers,
477
+ // so we cast to integer first...
478
+ let ptr_llty = bx. type_ptr_to ( bx. type_isize ( ) ) ;
479
+ source = bx. pointercast ( source, ptr_llty) ;
480
+ }
481
+ let result = bx. atomic_load ( source, order, size) ;
482
+ if ty. is_unsafe_ptr ( ) {
483
+ // ... and then cast the result back to a pointer
484
+ bx. inttoptr ( result, bx. backend_type ( layout) )
485
+ } else {
486
+ result
487
+ }
470
488
} else {
471
489
return invalid_monomorphization ( ty) ;
472
490
}
@@ -476,7 +494,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
476
494
let ty = substs. type_at ( 0 ) ;
477
495
if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_unsafe_ptr ( ) {
478
496
let size = bx. layout_of ( ty) . size ;
479
- bx. atomic_store ( args[ 1 ] . immediate ( ) , args[ 0 ] . immediate ( ) , order, size) ;
497
+ let mut val = args[ 1 ] . immediate ( ) ;
498
+ let mut ptr = args[ 0 ] . immediate ( ) ;
499
+ if ty. is_unsafe_ptr ( ) {
500
+ // Some platforms do not support atomic operations on pointers,
501
+ // so we cast to integer first.
502
+ let ptr_llty = bx. type_ptr_to ( bx. type_isize ( ) ) ;
503
+ ptr = bx. pointercast ( ptr, ptr_llty) ;
504
+ val = bx. ptrtoint ( val, bx. type_isize ( ) ) ;
505
+ }
506
+ bx. atomic_store ( val, ptr, order, size) ;
480
507
return ;
481
508
} else {
482
509
return invalid_monomorphization ( ty) ;
0 commit comments