Skip to content

Commit 708742f

Browse files
authored
Rollup merge of #144192 - RalfJung:atomicrmw-ptr, r=nikic
atomicrmw on pointers: move integer-pointer cast hacks into backend Conceptually, we want to have atomic operations on pointers of the form `fn atomic_add(ptr: *mut T, offset: usize, ...)`. However, LLVM does not directly support such operations (llvm/llvm-project#120837), so we have to cast the `offset` to a pointer somewhere. This PR moves that hack into the LLVM backend, so that the standard library, intrinsic, and Miri all work with the conceptual operation we actually want. Hopefully, one day LLVM will gain a way to represent these operations without integer-pointer casts, and then the hack will disappear entirely. Cc ```@nikic``` -- this is the best we can do right now, right? Fixes rust-lang/rust#134617
2 parents 098d06b + 84f834b commit 708742f

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

src/builder.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1671,6 +1671,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
16711671
dst: RValue<'gcc>,
16721672
src: RValue<'gcc>,
16731673
order: AtomicOrdering,
1674+
ret_ptr: bool,
16741675
) -> RValue<'gcc> {
16751676
let size = get_maybe_pointer_size(src);
16761677
let name = match op {
@@ -1698,14 +1699,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
16981699
let atomic_function = self.context.get_builtin_function(name);
16991700
let order = self.context.new_rvalue_from_int(self.i32_type, order.to_gcc());
17001701

1702+
// FIXME: If `ret_ptr` is true and `src` is an integer, we should really tell GCC
1703+
// that this is a pointer operation that needs to preserve provenance -- but like LLVM,
1704+
// GCC does not currently seems to support that.
17011705
let void_ptr_type = self.context.new_type::<*mut ()>();
17021706
let volatile_void_ptr_type = void_ptr_type.make_volatile();
17031707
let dst = self.context.new_cast(self.location, dst, volatile_void_ptr_type);
17041708
// FIXME(antoyo): not sure why, but we have the wrong type here.
17051709
let new_src_type = atomic_function.get_param(1).to_rvalue().get_type();
17061710
let src = self.context.new_bitcast(self.location, src, new_src_type);
17071711
let res = self.context.new_call(self.location, atomic_function, &[dst, src, order]);
1708-
self.context.new_cast(self.location, res, src.get_type())
1712+
let res_type = if ret_ptr { void_ptr_type } else { src.get_type() };
1713+
self.context.new_cast(self.location, res, res_type)
17091714
}
17101715

17111716
fn atomic_fence(&mut self, order: AtomicOrdering, scope: SynchronizationScope) {

0 commit comments

Comments
 (0)