diff options
| author | Oliver Middleton <olliemail27@gmail.com> | 2018-09-08 12:50:19 +0100 |
|---|---|---|
| committer | Simonas Kazlauskas <git@kazlauskas.me> | 2018-10-27 13:47:11 +0300 |
| commit | 01674fbe06aa2d05f8dafbb8a27ba6bd23fa09e1 (patch) | |
| tree | 625649f40505a0bb90e034efb257f129b7980ec6 /src/librustc_codegen_llvm | |
| parent | 10f42cbde015c44a019e8b6dceca472a1532f36a (diff) | |
| download | rust-01674fbe06aa2d05f8dafbb8a27ba6bd23fa09e1.tar.gz rust-01674fbe06aa2d05f8dafbb8a27ba6bd23fa09e1.zip | |
Correct alignment of atomic types and (re)add Atomic{I,U}128
LLVM requires that atomic loads and stores be aligned to at least the size of the type.
Diffstat (limited to 'src/librustc_codegen_llvm')
| -rw-r--r-- | src/librustc_codegen_llvm/builder.rs | 15 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/intrinsic.rs | 8 |
2 files changed, 10 insertions, 13 deletions
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 2fe6a0377f8..f70a68c7248 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -482,14 +482,12 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, align: Align) -> &'ll Value { + pub fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, size: Size) -> &'ll Value { self.count_insn("load.atomic"); unsafe { let load = llvm::LLVMRustBuildAtomicLoad(self.llbuilder, ptr, noname(), order); - // FIXME(eddyb) Isn't it UB to use `pref` instead of `abi` here? - // However, 64-bit atomic loads on `i686-apple-darwin` appear to - // require `___atomic_load` with ABI-alignment, so it's staying. - llvm::LLVMSetAlignment(load, align.pref() as c_uint); + // LLVM requires the alignment of atomic loads to be at least the size of the type. + llvm::LLVMSetAlignment(load, size.bytes() as c_uint); load } } @@ -564,15 +562,14 @@ impl Builder<'a, 'll, 'tcx> { } pub fn atomic_store(&self, val: &'ll Value, ptr: &'ll Value, - order: AtomicOrdering, align: Align) { + order: AtomicOrdering, size: Size) { debug!("Store {:?} -> {:?}", val, ptr); self.count_insn("store.atomic"); let ptr = self.check_store(val, ptr); unsafe { let store = llvm::LLVMRustBuildAtomicStore(self.llbuilder, val, ptr, order); - // FIXME(eddyb) Isn't it UB to use `pref` instead of `abi` here? - // Also see `atomic_load` for more context. - llvm::LLVMSetAlignment(store, align.pref() as c_uint); + // LLVM requires the alignment of atomic stores to be at least the size of the type. + llvm::LLVMSetAlignment(store, size.bytes() as c_uint); } } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 272196afa6f..596a1d5e8a5 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -477,8 +477,8 @@ pub fn codegen_intrinsic_call( "load" => { let ty = substs.type_at(0); if int_type_width_signed(ty, cx).is_some() { - let align = cx.align_of(ty); - bx.atomic_load(args[0].immediate(), order, align) + let size = cx.size_of(ty); + bx.atomic_load(args[0].immediate(), order, size) } else { return invalid_monomorphization(ty); } @@ -487,8 +487,8 @@ pub fn codegen_intrinsic_call( "store" => { let ty = substs.type_at(0); if int_type_width_signed(ty, cx).is_some() { - let align = cx.align_of(ty); - bx.atomic_store(args[1].immediate(), args[0].immediate(), order, align); + let size = cx.size_of(ty); + bx.atomic_store(args[1].immediate(), args[0].immediate(), order, size); return; } else { return invalid_monomorphization(ty); |
