about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src/mir
diff options
context:
space:
mode:
authoroli <github35764891676564198441@oli-obk.de>2020-11-28 18:12:45 +0000
committeroli <github35764891676564198441@oli-obk.de>2020-11-29 12:58:03 +0000
commit392ea297573dab95cc819cecd3a7f7e8e820316b (patch)
tree5fed81f8fd62fd6feb837a0482dfa95166870637 /compiler/rustc_codegen_ssa/src/mir
parent79fb037cc5f34368de069e8958ffc3a21036d091 (diff)
downloadrust-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.rs49
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);