1
Fork 0

Pass type when creating atomic load

Instead of determining it from the pointer type, explicitly pass
the type to load.
This commit is contained in:
Nikita Popov 2021-07-04 17:49:51 +02:00
parent 619c27a539
commit 33e9a6b565
5 changed files with 17 additions and 10 deletions

View file

@ -428,6 +428,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
fn atomic_load( fn atomic_load(
&mut self, &mut self,
ty: &'ll Type,
ptr: &'ll Value, ptr: &'ll Value,
order: rustc_codegen_ssa::common::AtomicOrdering, order: rustc_codegen_ssa::common::AtomicOrdering,
size: Size, size: Size,
@ -435,6 +436,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
unsafe { unsafe {
let load = llvm::LLVMRustBuildAtomicLoad( let load = llvm::LLVMRustBuildAtomicLoad(
self.llbuilder, self.llbuilder,
ty,
ptr, ptr,
UNNAMED, UNNAMED,
AtomicOrdering::from_generic(order), AtomicOrdering::from_generic(order),

View file

@ -1631,6 +1631,7 @@ extern "C" {
// Atomic Operations // Atomic Operations
pub fn LLVMRustBuildAtomicLoad( pub fn LLVMRustBuildAtomicLoad(
B: &Builder<'a>, B: &Builder<'a>,
ElementType: &'a Type,
PointerVal: &'a Value, PointerVal: &'a Value,
Name: *const c_char, Name: *const c_char,
Order: AtomicOrdering, Order: AtomicOrdering,

View file

@ -448,15 +448,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if ty.is_unsafe_ptr() { if ty.is_unsafe_ptr() {
// Some platforms do not support atomic operations on pointers, // Some platforms do not support atomic operations on pointers,
// so we cast to integer first... // so we cast to integer first...
let ptr_llty = bx.type_ptr_to(bx.type_isize()); let llty = bx.type_isize();
let ptr_llty = bx.type_ptr_to(llty);
source = bx.pointercast(source, ptr_llty); source = bx.pointercast(source, ptr_llty);
} let result = bx.atomic_load(llty, source, order, size);
let result = bx.atomic_load(source, order, size);
if ty.is_unsafe_ptr() {
// ... and then cast the result back to a pointer // ... and then cast the result back to a pointer
bx.inttoptr(result, bx.backend_type(layout)) bx.inttoptr(result, bx.backend_type(layout))
} else { } else {
result bx.atomic_load(bx.backend_type(layout), source, order, size)
} }
} else { } else {
return invalid_monomorphization(ty); return invalid_monomorphization(ty);

View file

@ -139,7 +139,13 @@ pub trait BuilderMethods<'a, 'tcx>:
fn load(&mut self, ptr: Self::Value, align: Align) -> Self::Value; fn load(&mut self, ptr: Self::Value, align: Align) -> Self::Value;
fn volatile_load(&mut self, ptr: Self::Value) -> Self::Value; fn volatile_load(&mut self, ptr: Self::Value) -> Self::Value;
fn atomic_load(&mut self, ptr: Self::Value, order: AtomicOrdering, size: Size) -> Self::Value; fn atomic_load(
&mut self,
ty: Self::Type,
ptr: Self::Value,
order: AtomicOrdering,
size: Size,
) -> Self::Value;
fn load_operand(&mut self, place: PlaceRef<'tcx, Self::Value>) fn load_operand(&mut self, place: PlaceRef<'tcx, Self::Value>)
-> OperandRef<'tcx, Self::Value>; -> OperandRef<'tcx, Self::Value>;

View file

@ -349,11 +349,10 @@ extern "C" void LLVMRustSetFastMath(LLVMValueRef V) {
} }
extern "C" LLVMValueRef extern "C" LLVMValueRef
LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name, LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Source,
LLVMAtomicOrdering Order) { const char *Name, LLVMAtomicOrdering Order) {
Value *Ptr = unwrap(Source); Value *Ptr = unwrap(Source);
Type *Ty = Ptr->getType()->getPointerElementType(); LoadInst *LI = unwrap(B)->CreateLoad(unwrap(Ty), Ptr, Name);
LoadInst *LI = unwrap(B)->CreateLoad(Ty, Ptr, Name);
LI->setAtomic(fromRust(Order)); LI->setAtomic(fromRust(Order));
return wrap(LI); return wrap(LI);
} }