Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 4 pull requests #132586

Merged
merged 9 commits into from
Nov 4, 2024
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {

// Wasm statics with custom link sections get special treatment as they
// go into custom sections of the wasm executable.
if self.tcx.sess.opts.target_triple.tuple().starts_with("wasm32") {
if self.tcx.sess.target.is_like_wasm {
if let Some(_section) = attrs.link_section {
unimplemented!();
}
Expand Down
29 changes: 9 additions & 20 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,23 +945,10 @@ fn create_section_with_flags_asm(section_name: &str, section_flags: &str, data:
asm
}

fn target_is_apple(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
let triple = cgcx.opts.target_triple.tuple();
triple.contains("-ios")
|| triple.contains("-darwin")
|| triple.contains("-tvos")
|| triple.contains("-watchos")
|| triple.contains("-visionos")
}

fn target_is_aix(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
cgcx.opts.target_triple.tuple().contains("-aix")
}

pub(crate) fn bitcode_section_name(cgcx: &CodegenContext<LlvmCodegenBackend>) -> &'static CStr {
if target_is_apple(cgcx) {
if cgcx.target_is_like_osx {
c"__LLVM,__bitcode"
} else if target_is_aix(cgcx) {
} else if cgcx.target_is_like_aix {
c".ipa"
} else {
c".llvmbc"
Expand Down Expand Up @@ -1028,10 +1015,12 @@ unsafe fn embed_bitcode(
// Unfortunately, LLVM provides no way to set custom section flags. For ELF
// and COFF we emit the sections using module level inline assembly for that
// reason (see issue #90326 for historical background).
let is_aix = target_is_aix(cgcx);
let is_apple = target_is_apple(cgcx);
unsafe {
if is_apple || is_aix || cgcx.opts.target_triple.tuple().starts_with("wasm") {
if cgcx.target_is_like_osx
|| cgcx.target_is_like_aix
|| cgcx.target_arch == "wasm32"
|| cgcx.target_arch == "wasm64"
{
// We don't need custom section flags, create LLVM globals.
let llconst = common::bytes_in_context(llcx, bitcode);
let llglobal = llvm::LLVMAddGlobal(
Expand All @@ -1052,9 +1041,9 @@ unsafe fn embed_bitcode(
c"rustc.embedded.cmdline".as_ptr(),
);
llvm::LLVMSetInitializer(llglobal, llconst);
let section = if is_apple {
let section = if cgcx.target_is_like_osx {
c"__LLVM,__cmdline"
} else if is_aix {
} else if cgcx.target_is_like_aix {
c".info"
} else {
c".llvmcmd"
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,7 @@ pub fn link_binary(
}

if invalid_output_for_target(sess, crate_type) {
bug!(
"invalid output type `{:?}` for target os `{}`",
crate_type,
sess.opts.target_triple
);
bug!("invalid output type `{:?}` for target `{}`", crate_type, sess.opts.target_triple);
}

sess.time("link_binary_check_files_are_writeable", || {
Expand Down Expand Up @@ -996,6 +992,7 @@ fn link_natively(
&& (code < 1000 || code > 9999)
{
let is_vs_installed = windows_registry::find_vs_version().is_ok();
// FIXME(cc-rs#1265) pass only target arch to find_tool()
let has_linker = windows_registry::find_tool(
sess.opts.target_triple.tuple(),
"link.exe",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub(crate) fn get_linker<'a>(
self_contained: bool,
target_cpu: &'a str,
) -> Box<dyn Linker + 'a> {
// FIXME(cc-rs#1265) pass only target arch to find_tool()
let msvc_tool = windows_registry::find_tool(sess.opts.target_triple.tuple(), "link.exe");

// If our linker looks like a batch script on Windows then to execute this
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,15 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
"powerpc64" => (Architecture::PowerPc64, None),
"riscv32" => (Architecture::Riscv32, None),
"riscv64" => (Architecture::Riscv64, None),
"sparc" => (Architecture::Sparc32Plus, None),
"sparc" => {
if sess.target.options.cpu == "v9" {
// Target uses V8+, aka EM_SPARC32PLUS, aka 64-bit V9 but in 32-bit mode
(Architecture::Sparc32Plus, None)
} else {
// Target uses V7 or V8, aka EM_SPARC
(Architecture::Sparc, None)
}
}
"sparc64" => (Architecture::Sparc64, None),
"avr" => (Architecture::Avr, None),
"msp430" => (Architecture::Msp430, None),
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ pub struct CodegenContext<B: WriteBackendMethods> {
pub is_pe_coff: bool,
pub target_can_use_split_dwarf: bool,
pub target_arch: String,
pub target_is_like_osx: bool,
pub target_is_like_aix: bool,
pub split_debuginfo: rustc_target::spec::SplitDebuginfo,
pub split_dwarf_kind: rustc_session::config::SplitDwarfKind,

Expand Down Expand Up @@ -1195,6 +1197,8 @@ fn start_executing_work<B: ExtraBackendMethods>(
is_pe_coff: tcx.sess.target.is_like_windows,
target_can_use_split_dwarf: tcx.sess.target_can_use_split_dwarf(),
target_arch: tcx.sess.target.arch.to_string(),
target_is_like_osx: tcx.sess.target.is_like_osx,
target_is_like_aix: tcx.sess.target.is_like_aix,
split_debuginfo: tcx.sess.split_debuginfo(),
split_dwarf_kind: tcx.sess.opts.unstable_opts.split_dwarf_kind,
parallel: backend.supports_parallel() && !sess.opts.unstable_opts.no_parallel_backend,
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
const_eval_address_space_full =
there are no more free addresses in the address space
const_eval_align_offset_invalid_align =
`align_offset` called with non-power-of-two align: {$target_align}
const_eval_alignment_check_failed =
{$msg ->
[AccessedPtr] accessing memory
Expand Down
88 changes: 6 additions & 82 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::borrow::{Borrow, Cow};
use std::fmt;
use std::hash::Hash;
use std::ops::ControlFlow;

use rustc_abi::{Align, ExternAbi, Size};
use rustc_ast::Mutability;
Expand All @@ -10,7 +9,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem};
use rustc_middle::mir::AssertMessage;
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout};
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, mir};
use rustc_span::Span;
Expand All @@ -22,9 +21,9 @@ use crate::errors::{LongRunning, LongRunningWarn};
use crate::fluent_generated as fluent;
use crate::interpret::{
self, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame, GlobalAlloc, ImmTy,
InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, RangeSet, Scalar,
StackPopCleanup, compile_time_machine, interp_ok, throw_exhaust, throw_inval, throw_ub,
throw_ub_custom, throw_unsup, throw_unsup_format,
InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, RangeSet, Scalar, compile_time_machine,
interp_ok, throw_exhaust, throw_inval, throw_ub, throw_ub_custom, throw_unsup,
throw_unsup_format,
};

/// When hitting this many interpreted terminators we emit a deny by default lint
Expand Down Expand Up @@ -226,8 +225,8 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
&mut self,
instance: ty::Instance<'tcx>,
args: &[FnArg<'tcx>],
dest: &MPlaceTy<'tcx>,
ret: Option<mir::BasicBlock>,
_dest: &MPlaceTy<'tcx>,
_ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
let def_id = instance.def_id();

Expand Down Expand Up @@ -259,85 +258,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
);

return interp_ok(Some(new_instance));
} else if self.tcx.is_lang_item(def_id, LangItem::AlignOffset) {
let args = self.copy_fn_args(args);
// For align_offset, we replace the function call if the pointer has no address.
match self.align_offset(instance, &args, dest, ret)? {
ControlFlow::Continue(()) => return interp_ok(Some(instance)),
ControlFlow::Break(()) => return interp_ok(None),
}
}
interp_ok(Some(instance))
}

/// `align_offset(ptr, target_align)` needs special handling in const eval, because the pointer
/// may not have an address.
///
/// If `ptr` does have a known address, then we return `Continue(())` and the function call should
/// proceed as normal.
///
/// If `ptr` doesn't have an address, but its underlying allocation's alignment is at most
/// `target_align`, then we call the function again with an dummy address relative to the
/// allocation.
///
/// If `ptr` doesn't have an address and `target_align` is stricter than the underlying
/// allocation's alignment, then we return `usize::MAX` immediately.
fn align_offset(
&mut self,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx, ControlFlow<()>> {
assert_eq!(args.len(), 2);

let ptr = self.read_pointer(&args[0])?;
let target_align = self.read_scalar(&args[1])?.to_target_usize(self)?;

if !target_align.is_power_of_two() {
throw_ub_custom!(
fluent::const_eval_align_offset_invalid_align,
target_align = target_align,
);
}

match self.ptr_try_get_alloc_id(ptr, 0) {
Ok((alloc_id, offset, _extra)) => {
let (_size, alloc_align, _kind) = self.get_alloc_info(alloc_id);

if target_align <= alloc_align.bytes() {
// Extract the address relative to the allocation base that is definitely
// sufficiently aligned and call `align_offset` again.
let addr = ImmTy::from_uint(offset.bytes(), args[0].layout).into();
let align = ImmTy::from_uint(target_align, args[1].layout).into();
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?;

// Push the stack frame with our own adjusted arguments.
self.init_stack_frame(
instance,
self.load_mir(instance.def, None)?,
fn_abi,
&[FnArg::Copy(addr), FnArg::Copy(align)],
/* with_caller_location = */ false,
dest,
StackPopCleanup::Goto { ret, unwind: mir::UnwindAction::Unreachable },
)?;
interp_ok(ControlFlow::Break(()))
} else {
// Not alignable in const, return `usize::MAX`.
let usize_max = Scalar::from_target_usize(self.target_usize_max(), self);
self.write_scalar(usize_max, dest)?;
self.return_to_block(ret)?;
interp_ok(ControlFlow::Break(()))
}
}
Err(_addr) => {
// The pointer has an address, continue with function call.
interp_ok(ControlFlow::Continue(()))
}
}
}

/// See documentation on the `ptr_guaranteed_cmp` intrinsic.
fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> {
interp_ok(match (a, b) {
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,6 @@ language_item_table! {

MaybeUninit, sym::maybe_uninit, maybe_uninit, Target::Union, GenericRequirement::None;

/// Align offset for stride != 1; must not panic.
AlignOffset, sym::align_offset, align_offset_fn, Target::Fn, GenericRequirement::None;

Termination, sym::termination, termination, Target::Trait, GenericRequirement::None;

Try, sym::Try, try_trait, Target::Trait, GenericRequirement::None;
Expand Down
Loading
Loading