diff options
| author | Anthony Ramine <n.oxyde@gmail.com> | 2018-05-11 11:26:51 +0200 |
|---|---|---|
| committer | Anthony Ramine <n.oxyde@gmail.com> | 2018-05-13 10:36:28 +0200 |
| commit | b638f11b4230ad2e098a75474c36a10de1653d0d (patch) | |
| tree | 6e38d198fde8c8f42253ce659e386d5af2a188c5 | |
| parent | 6fc409ed0938cd2f501642abcaa675977fa5035a (diff) | |
| download | rust-b638f11b4230ad2e098a75474c36a10de1653d0d.tar.gz rust-b638f11b4230ad2e098a75474c36a10de1653d0d.zip | |
Introduce OperandValue::volatile_store and use it in the intrinsics
Fixes #50371.
| -rw-r--r-- | src/librustc_trans/abi.rs | 3 | ||||
| -rw-r--r-- | src/librustc_trans/base.rs | 10 | ||||
| -rw-r--r-- | src/librustc_trans/builder.rs | 3 | ||||
| -rw-r--r-- | src/librustc_trans/intrinsic.rs | 21 | ||||
| -rw-r--r-- | src/librustc_trans/mir/block.rs | 2 | ||||
| -rw-r--r-- | src/librustc_trans/mir/operand.rs | 24 |
6 files changed, 35 insertions, 28 deletions
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 1838dae049a..c80d989e3cb 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -220,7 +220,8 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { bx.pointercast(dst.llval, Type::i8p(cx)), bx.pointercast(llscratch, Type::i8p(cx)), C_usize(cx, self.layout.size.bytes()), - self.layout.align.min(scratch_align)); + self.layout.align.min(scratch_align), + false); bx.lifetime_end(llscratch, scratch_size); } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 0dd1adbff86..65dce5f3ffb 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -320,7 +320,7 @@ pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>, if src_f.layout.ty == dst_f.layout.ty { memcpy_ty(bx, dst_f.llval, src_f.llval, src_f.layout, - src_f.align.min(dst_f.align)); + src_f.align.min(dst_f.align), false); } else { coerce_unsized_into(bx, src_f, dst_f); } @@ -408,7 +408,8 @@ pub fn call_memcpy(bx: &Builder, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, - align: Align) { + align: Align, + volatile: bool) { let cx = bx.cx; let ptr_width = &cx.sess().target.target.target_pointer_width; let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width); @@ -417,7 +418,7 @@ pub fn call_memcpy(bx: &Builder, let dst_ptr = bx.pointercast(dst, Type::i8p(cx)); let size = bx.intcast(n_bytes, cx.isize_ty, false); let align = C_i32(cx, align.abi() as i32); - let volatile = C_bool(cx, false); + let volatile = C_bool(cx, volatile); bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None); } @@ -427,13 +428,14 @@ pub fn memcpy_ty<'a, 'tcx>( src: ValueRef, layout: TyLayout<'tcx>, align: Align, + volatile: bool, ) { let size = layout.size.bytes(); if size == 0 { return; } - call_memcpy(bx, dst, src, C_usize(bx.cx, size), align); + call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, volatile); } pub fn call_memset<'a, 'tcx>(bx: &Builder<'a, 'tcx>, diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index db803ca8209..49bcf9b88a0 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -590,13 +590,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef) -> ValueRef { + pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef, align: Align) -> ValueRef { debug!("Store {:?} -> {:?}", Value(val), Value(ptr)); assert!(!self.llbuilder.is_null()); self.count_insn("store.volatile"); let ptr = self.check_store(val, ptr); unsafe { let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr); + llvm::LLVMSetAlignment(insn, align.abi() as c_uint); llvm::LLVMSetVolatile(insn, llvm::True); insn } diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 49a207a2d8a..65e211ae740 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -247,26 +247,11 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, to_immediate(bx, load, cx.layout_of(tp_ty)) }, "volatile_store" => { - let tp_ty = substs.type_at(0); let dst = args[0].deref(bx.cx); - if let OperandValue::Pair(a, b) = args[1].val { - bx.volatile_store(a, dst.project_field(bx, 0).llval); - bx.volatile_store(b, dst.project_field(bx, 1).llval); - } else { - let val = if let OperandValue::Ref(ptr, align) = args[1].val { - bx.load(ptr, align) - } else { - if dst.layout.is_zst() { - return; - } - from_immediate(bx, args[1].immediate()) - }; - let ptr = bx.pointercast(dst.llval, val_ty(val).ptr_to()); - let store = bx.volatile_store(val, ptr); - unsafe { - llvm::LLVMSetAlignment(store, cx.align_of(tp_ty).abi() as u32); - } + if dst.layout.is_zst() { + return; } + args[1].val.volatile_store(bx, dst); return; }, "prefetch_read_data" | "prefetch_write_data" | diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index b666c2b2115..df8807c318b 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -626,7 +626,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { // have scary latent bugs around. let scratch = PlaceRef::alloca(bx, arg.layout, "arg"); - base::memcpy_ty(bx, scratch.llval, llval, op.layout, align); + base::memcpy_ty(bx, scratch.llval, llval, op.layout, align, false); (scratch.llval, scratch.align, true) } else { (llval, align, true) diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index 432ac44e0a5..f6966178291 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -275,6 +275,14 @@ impl<'a, 'tcx> OperandRef<'tcx> { impl<'a, 'tcx> OperandValue { pub fn store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + self.store_maybe_volatile(bx, dest, false); + } + + pub fn volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + self.store_maybe_volatile(bx, dest, true); + } + + fn store_maybe_volatile(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, volatile: bool) { debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest); // Avoid generating stores of zero-sized values, because the only way to have a zero-sized // value is through `undef`, and store itself is useless. @@ -284,9 +292,14 @@ impl<'a, 'tcx> OperandValue { match self { OperandValue::Ref(r, source_align) => base::memcpy_ty(bx, dest.llval, r, dest.layout, - source_align.min(dest.align)), + source_align.min(dest.align), volatile), OperandValue::Immediate(s) => { - bx.store(base::from_immediate(bx, s), dest.llval, dest.align); + let val = base::from_immediate(bx, s); + if !volatile { + bx.store(val, dest.llval, dest.align); + } else { + bx.volatile_store(val, dest.llval, dest.align); + } } OperandValue::Pair(a, b) => { for (i, &x) in [a, b].iter().enumerate() { @@ -295,7 +308,12 @@ impl<'a, 'tcx> OperandValue { if common::val_ty(x) == Type::i1(bx.cx) { llptr = bx.pointercast(llptr, Type::i8p(bx.cx)); } - bx.store(base::from_immediate(bx, x), llptr, dest.align); + let val = base::from_immediate(bx, x); + if !volatile { + bx.store(val, llptr, dest.align); + } else { + bx.volatile_store(val, llptr, dest.align); + } } } } |
