diff options
| author | oli <github35764891676564198441@oli-obk.de> | 2020-11-28 18:12:45 +0000 |
|---|---|---|
| committer | oli <github35764891676564198441@oli-obk.de> | 2020-11-29 12:58:03 +0000 |
| commit | 392ea297573dab95cc819cecd3a7f7e8e820316b (patch) | |
| tree | 5fed81f8fd62fd6feb837a0482dfa95166870637 /compiler/rustc_codegen_ssa/src/mir | |
| parent | 79fb037cc5f34368de069e8958ffc3a21036d091 (diff) | |
| download | rust-392ea297573dab95cc819cecd3a7f7e8e820316b.tar.gz rust-392ea297573dab95cc819cecd3a7f7e8e820316b.zip | |
Cast pointers to usize before passing them to atomic operations as some platforms do not support atomic operations on pointers.
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/mir')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 3026eadefe3..72a64a8c510 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -439,14 +439,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = substs.type_at(0); if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { let weak = split[1] == "cxchgweak"; - let pair = bx.atomic_cmpxchg( - args[0].immediate(), - args[1].immediate(), - args[2].immediate(), - order, - failorder, - weak, - ); + let mut dst = args[0].immediate(); + let mut cmp = args[1].immediate(); + let mut src = args[2].immediate(); + if ty.is_unsafe_ptr() { + // Some platforms do not support atomic operations on pointers, + // so we cast to integer first. + let ptr_llty = bx.type_ptr_to(bx.type_isize()); + dst = bx.pointercast(dst, ptr_llty); + cmp = bx.ptrtoint(cmp, bx.type_isize()); + src = bx.ptrtoint(src, bx.type_isize()); + } + let pair = bx.atomic_cmpxchg(dst, cmp, src, order, failorder, weak); let val = bx.extract_value(pair, 0); let success = bx.extract_value(pair, 1); let val = bx.from_immediate(val); @@ -465,8 +469,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { "load" => { let ty = substs.type_at(0); if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { - let size = bx.layout_of(ty).size; - bx.atomic_load(args[0].immediate(), order, size) + let layout = bx.layout_of(ty); + let size = layout.size; + let mut source = args[0].immediate(); + if ty.is_unsafe_ptr() { + // Some platforms do not support atomic operations on pointers, + // so we cast to integer first... + let ptr_llty = bx.type_ptr_to(bx.type_isize()); + source = bx.pointercast(source, ptr_llty); + } + let result = bx.atomic_load(source, order, size); + if ty.is_unsafe_ptr() { + // ... and then cast the result back to a pointer + bx.inttoptr(result, bx.backend_type(layout)) + } else { + result + } } else { return invalid_monomorphization(ty); } @@ -476,7 +494,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = substs.type_at(0); if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { let size = bx.layout_of(ty).size; - bx.atomic_store(args[1].immediate(), args[0].immediate(), order, size); + let mut val = args[1].immediate(); + let mut ptr = args[0].immediate(); + if ty.is_unsafe_ptr() { + // Some platforms do not support atomic operations on pointers, + // so we cast to integer first. + let ptr_llty = bx.type_ptr_to(bx.type_isize()); + ptr = bx.pointercast(ptr, ptr_llty); + val = bx.ptrtoint(val, bx.type_isize()); + } + bx.atomic_store(val, ptr, order, size); return; } else { return invalid_monomorphization(ty); |
