Skip to content

Commit b638f11

Browse files
committed
Introduce OperandValue::volatile_store and use it in the intrinsics
Fixes #50371.
1 parent 6fc409e commit b638f11

File tree

6 files changed

+35
-28
lines changed

6 files changed

+35
-28
lines changed

src/librustc_trans/abi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
220220
bx.pointercast(dst.llval, Type::i8p(cx)),
221221
bx.pointercast(llscratch, Type::i8p(cx)),
222222
C_usize(cx, self.layout.size.bytes()),
223-
self.layout.align.min(scratch_align));
223+
self.layout.align.min(scratch_align),
224+
false);
224225

225226
bx.lifetime_end(llscratch, scratch_size);
226227
}

src/librustc_trans/base.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
320320

321321
if src_f.layout.ty == dst_f.layout.ty {
322322
memcpy_ty(bx, dst_f.llval, src_f.llval, src_f.layout,
323-
src_f.align.min(dst_f.align));
323+
src_f.align.min(dst_f.align), false);
324324
} else {
325325
coerce_unsized_into(bx, src_f, dst_f);
326326
}
@@ -408,7 +408,8 @@ pub fn call_memcpy(bx: &Builder,
408408
dst: ValueRef,
409409
src: ValueRef,
410410
n_bytes: ValueRef,
411-
align: Align) {
411+
align: Align,
412+
volatile: bool) {
412413
let cx = bx.cx;
413414
let ptr_width = &cx.sess().target.target.target_pointer_width;
414415
let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width);
@@ -417,7 +418,7 @@ pub fn call_memcpy(bx: &Builder,
417418
let dst_ptr = bx.pointercast(dst, Type::i8p(cx));
418419
let size = bx.intcast(n_bytes, cx.isize_ty, false);
419420
let align = C_i32(cx, align.abi() as i32);
420-
let volatile = C_bool(cx, false);
421+
let volatile = C_bool(cx, volatile);
421422
bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None);
422423
}
423424

@@ -427,13 +428,14 @@ pub fn memcpy_ty<'a, 'tcx>(
427428
src: ValueRef,
428429
layout: TyLayout<'tcx>,
429430
align: Align,
431+
volatile: bool,
430432
) {
431433
let size = layout.size.bytes();
432434
if size == 0 {
433435
return;
434436
}
435437

436-
call_memcpy(bx, dst, src, C_usize(bx.cx, size), align);
438+
call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, volatile);
437439
}
438440

439441
pub fn call_memset<'a, 'tcx>(bx: &Builder<'a, 'tcx>,

src/librustc_trans/builder.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -590,13 +590,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
590590
}
591591
}
592592

593-
pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef) -> ValueRef {
593+
pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef, align: Align) -> ValueRef {
594594
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
595595
assert!(!self.llbuilder.is_null());
596596
self.count_insn("store.volatile");
597597
let ptr = self.check_store(val, ptr);
598598
unsafe {
599599
let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
600+
llvm::LLVMSetAlignment(insn, align.abi() as c_uint);
600601
llvm::LLVMSetVolatile(insn, llvm::True);
601602
insn
602603
}

src/librustc_trans/intrinsic.rs

+3-18
Original file line numberDiff line numberDiff line change
@@ -247,26 +247,11 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
247247
to_immediate(bx, load, cx.layout_of(tp_ty))
248248
},
249249
"volatile_store" => {
250-
let tp_ty = substs.type_at(0);
251250
let dst = args[0].deref(bx.cx);
252-
if let OperandValue::Pair(a, b) = args[1].val {
253-
bx.volatile_store(a, dst.project_field(bx, 0).llval);
254-
bx.volatile_store(b, dst.project_field(bx, 1).llval);
255-
} else {
256-
let val = if let OperandValue::Ref(ptr, align) = args[1].val {
257-
bx.load(ptr, align)
258-
} else {
259-
if dst.layout.is_zst() {
260-
return;
261-
}
262-
from_immediate(bx, args[1].immediate())
263-
};
264-
let ptr = bx.pointercast(dst.llval, val_ty(val).ptr_to());
265-
let store = bx.volatile_store(val, ptr);
266-
unsafe {
267-
llvm::LLVMSetAlignment(store, cx.align_of(tp_ty).abi() as u32);
268-
}
251+
if dst.layout.is_zst() {
252+
return;
269253
}
254+
args[1].val.volatile_store(bx, dst);
270255
return;
271256
},
272257
"prefetch_read_data" | "prefetch_write_data" |

src/librustc_trans/mir/block.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
626626
// have scary latent bugs around.
627627

628628
let scratch = PlaceRef::alloca(bx, arg.layout, "arg");
629-
base::memcpy_ty(bx, scratch.llval, llval, op.layout, align);
629+
base::memcpy_ty(bx, scratch.llval, llval, op.layout, align, false);
630630
(scratch.llval, scratch.align, true)
631631
} else {
632632
(llval, align, true)

src/librustc_trans/mir/operand.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,14 @@ impl<'a, 'tcx> OperandRef<'tcx> {
275275

276276
impl<'a, 'tcx> OperandValue {
277277
pub fn store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
278+
self.store_maybe_volatile(bx, dest, false);
279+
}
280+
281+
pub fn volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
282+
self.store_maybe_volatile(bx, dest, true);
283+
}
284+
285+
fn store_maybe_volatile(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, volatile: bool) {
278286
debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest);
279287
// Avoid generating stores of zero-sized values, because the only way to have a zero-sized
280288
// value is through `undef`, and store itself is useless.
@@ -284,9 +292,14 @@ impl<'a, 'tcx> OperandValue {
284292
match self {
285293
OperandValue::Ref(r, source_align) =>
286294
base::memcpy_ty(bx, dest.llval, r, dest.layout,
287-
source_align.min(dest.align)),
295+
source_align.min(dest.align), volatile),
288296
OperandValue::Immediate(s) => {
289-
bx.store(base::from_immediate(bx, s), dest.llval, dest.align);
297+
let val = base::from_immediate(bx, s);
298+
if !volatile {
299+
bx.store(val, dest.llval, dest.align);
300+
} else {
301+
bx.volatile_store(val, dest.llval, dest.align);
302+
}
290303
}
291304
OperandValue::Pair(a, b) => {
292305
for (i, &x) in [a, b].iter().enumerate() {
@@ -295,7 +308,12 @@ impl<'a, 'tcx> OperandValue {
295308
if common::val_ty(x) == Type::i1(bx.cx) {
296309
llptr = bx.pointercast(llptr, Type::i8p(bx.cx));
297310
}
298-
bx.store(base::from_immediate(bx, x), llptr, dest.align);
311+
let val = base::from_immediate(bx, x);
312+
if !volatile {
313+
bx.store(val, llptr, dest.align);
314+
} else {
315+
bx.volatile_store(val, llptr, dest.align);
316+
}
299317
}
300318
}
301319
}

0 commit comments

Comments
 (0)