Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1461,15 +1461,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let cause = ObligationCause::misc(expr.span, self.mir_def_id());
ocx.register_bound(cause, self.infcx.param_env, ty, clone_trait);
let errors = ocx.evaluate_obligations_error_on_ambiguity();
if errors.iter().all(|error| {
match error.obligation.predicate.as_clause().and_then(|c| c.as_trait_clause()) {
Some(clause) => match clause.self_ty().skip_binder().kind() {
ty::Adt(def, _) => def.did().is_local() && clause.def_id() == clone_trait,
_ => false,
},
None => false,
}
}) {
if !errors.is_empty()
&& errors.iter().all(|error| {
match error.obligation.predicate.as_clause().and_then(|c| c.as_trait_clause()) {
Some(clause) => match clause.self_ty().skip_binder().kind() {
ty::Adt(def, _) => {
def.did().is_local() && clause.def_id() == clone_trait
}
_ => false,
},
None => false,
}
})
{
let mut type_spans = vec![];
let mut types = FxIndexSet::default();
for clause in errors
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
loaded_value.to_rvalue()
}

fn volatile_load(&mut self, ty: Type<'gcc>, ptr: RValue<'gcc>) -> RValue<'gcc> {
fn volatile_load(&mut self, ty: Type<'gcc>, ptr: RValue<'gcc>, _: Align) -> RValue<'gcc> {
// FIXME(antoyo): set alignment.
let ptr = self.context.new_cast(self.location, ptr, ty.make_volatile().make_pointer());
// (FractalFir): We insert a local here, to ensure this volatile load can't move across
// blocks.
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod simd;
use std::iter;

use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, Type, UnaryOp};
use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange};
use rustc_abi::{Align, BackendRepr, HasDataLayout, WrappingRange};
use rustc_codegen_ssa::base::wants_msvc_seh;
use rustc_codegen_ssa::common::IntPredicate;
use rustc_codegen_ssa::errors::InvalidMonomorphization;
Expand Down Expand Up @@ -368,8 +368,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc

sym::volatile_load | sym::unaligned_volatile_load => {
let ptr = args[0].immediate();
let load = self.volatile_load(result.layout.gcc_type(self), ptr);
// FIXME(antoyo): set alignment.
let abi_align = result_layout.align.abi;
let ptr_align = if name == sym::volatile_load { abi_align } else { Align::ONE };
let load = self.volatile_load(result.layout.gcc_type(self), ptr, ptr_align);
if let BackendRepr::Scalar(scalar) = result.layout.backend_repr {
self.to_immediate_scalar(load, scalar)
} else {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}

fn volatile_load(&mut self, ty: &'ll Type, ptr: &'ll Value) -> &'ll Value {
fn volatile_load(&mut self, ty: &'ll Type, ptr: &'ll Value, align: Align) -> &'ll Value {
unsafe {
let load = llvm::LLVMBuildLoad2(self.llbuilder, ty, ptr, UNNAMED);
let load = self.load(ty, ptr, align);
llvm::LLVMSetVolatile(load, llvm::TRUE);
load
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}

fn intrinsic_call_expects_place_always(&self, name: Symbol) -> bool {
matches!(name, sym::volatile_load | sym::unaligned_volatile_load | sym::black_box)
matches!(name, sym::black_box)
}
}

Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// .debug_gdb_scripts binary section.

use rustc_abi::Align;
use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
use rustc_codegen_ssa::traits::*;
use rustc_hir::attrs::DebuggerVisualizerType;
Expand All @@ -18,10 +19,7 @@ pub(crate) fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Buil
let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx);
// Load just the first byte as that's all that's necessary to force
// LLVM to keep around the reference to the global.
let volatile_load_instruction = bx.volatile_load(bx.type_i8(), gdb_debug_scripts_section);
unsafe {
llvm::LLVMSetAlignment(volatile_load_instruction, 1);
}
bx.volatile_load(bx.type_i8(), gdb_debug_scripts_section, Align::ONE);
}
}

Expand Down
46 changes: 30 additions & 16 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,25 +354,39 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}

sym::volatile_load | sym::unaligned_volatile_load => {
let result = PlaceRef {
val: result_place.unwrap(),
layout: result_layout,
};

// Note that we cannot just load the `llvm_type` because we should never load non-scalars.
// Trying to do so blows up horribly in some cases -- for example loading a
// `MaybeUninint<&dyn Trait>` would load as `{ [i64x2] }` which gives assertions later
// (if we're lucky) from things not being pointers that ought to be.
let ptr = args[0].immediate();
let load = self.volatile_load(result_layout.llvm_type(self), ptr);
let align = if name == sym::unaligned_volatile_load {
1
let abi_align = result_layout.align.abi;
let ptr_align = if name == sym::volatile_load { abi_align } else { Align::ONE };
if result_layout.is_zst() {
return IntrinsicResult::Operand(OperandValue::ZeroSized);
} else if let BackendRepr::Scalar(scalar) = result_layout.backend_repr {
let load = self.volatile_load(self.type_from_scalar(scalar), ptr, ptr_align);
self.to_immediate_scalar(load, scalar)
} else {
result_layout.align.bytes() as u32
};
unsafe {
llvm::LLVMSetAlignment(load, align);
}
if !result_layout.is_zst() {
self.store_to_place(load, result.val);
// One day Rust will probably want to define how we split up a volatile load
// of something that's *not* just an ordinary scalar, but for now we can just
// use an LLVM integer type of the correct width and let it split it however.
let llty = self.type_ix(result_layout.size.bits());
let temp = if let Some(result_place) = result_place {
PlaceRef {
val: result_place,
layout: result_layout,
}
} else {
PlaceRef::alloca(self, result_layout)
};
let llval = self.volatile_load(llty, ptr, ptr_align);
self.store(llval, temp.val.llval, abi_align);
return if result_place.is_none() {
IntrinsicResult::Operand(self.load_operand(temp).val)
} else {
IntrinsicResult::WroteIntoPlace
};
}
return IntrinsicResult::WroteIntoPlace;
}
sym::volatile_store => {
let dst = args[0].deref(self.cx());
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/traits/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ pub trait BuilderMethods<'a, 'tcx>:
fn alloca_with_ty(&mut self, layout: TyAndLayout<'tcx>) -> Self::Value;

fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value;
fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value;
fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value;
fn atomic_load(
&mut self,
ty: Self::Type,
Expand Down
Loading
Loading