@@ -439,14 +439,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
439439 let ty = substs. type_at ( 0 ) ;
440440 if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_unsafe_ptr ( ) {
441441 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) ;
450454 let val = bx. extract_value ( pair, 0 ) ;
451455 let success = bx. extract_value ( pair, 1 ) ;
452456 let val = bx. from_immediate ( val) ;
@@ -465,8 +469,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
465469 "load" => {
466470 let ty = substs. type_at ( 0 ) ;
467471 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+ }
470488 } else {
471489 return invalid_monomorphization ( ty) ;
472490 }
@@ -476,7 +494,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
476494 let ty = substs. type_at ( 0 ) ;
477495 if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_unsafe_ptr ( ) {
478496 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) ;
480507 return ;
481508 } else {
482509 return invalid_monomorphization ( ty) ;
0 commit comments