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 5 pull requests #128707

Merged
merged 12 commits into from
Aug 6, 2024
Merged
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
6 changes: 6 additions & 0 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2330,10 +2330,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
match (cast_ty_from, cast_ty_to) {
(Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => {
let mut normalize = |t| self.normalize(t, location);

// N.B. `struct_tail_with_normalize` only "structurally resolves"
// the type. It is not fully normalized, so we have to normalize it
// afterwards.
let src_tail =
tcx.struct_tail_with_normalize(src.ty, &mut normalize, || ());
let src_tail = normalize(src_tail);
let dst_tail =
tcx.struct_tail_with_normalize(dst.ty, &mut normalize, || ());
let dst_tail = normalize(dst_tail);

// This checks (lifetime part of) vtable validity for pointer casts,
// which is irrelevant when there are aren't principal traits on both sides (aka only auto traits).
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
_unwind: mir::UnwindAction,
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
// Shared intrinsics.
if ecx.emulate_intrinsic(instance, args, dest, target)? {
if ecx.eval_intrinsic(instance, args, dest, target)? {
return Ok(None);
}
let intrinsic_name = ecx.tcx.item_name(instance.def_id());
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Returns `true` if emulation happened.
/// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
/// intrinsic handling.
pub fn emulate_intrinsic(
pub fn eval_intrinsic(
&mut self,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, M::Provenance>],
Expand Down Expand Up @@ -447,7 +447,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
Ok(true)
}

pub(super) fn emulate_nondiverging_intrinsic(
pub(super) fn eval_nondiverging_intrinsic(
&mut self,
intrinsic: &NonDivergingIntrinsic<'tcx>,
) -> InterpResult<'tcx> {
Expand Down
37 changes: 36 additions & 1 deletion compiler/rustc_const_eval/src/interpret/operator.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use either::Either;
use rustc_apfloat::{Float, FloatConvert};
use rustc_middle::mir::interpret::{InterpResult, Scalar};
use rustc_middle::mir::NullOp;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::{self, FloatTy, ScalarInt};
use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty};
use rustc_middle::{bug, mir, span_bug};
use rustc_span::symbol::sym;
use tracing::trace;
Expand Down Expand Up @@ -480,4 +481,38 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
}
}

pub fn nullary_op(
&self,
null_op: NullOp<'tcx>,
arg_ty: Ty<'tcx>,
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
use rustc_middle::mir::NullOp::*;

let layout = self.layout_of(arg_ty)?;
let usize_layout = || self.layout_of(self.tcx.types.usize).unwrap();

Ok(match null_op {
SizeOf => {
if !layout.abi.is_sized() {
span_bug!(self.cur_span(), "unsized type for `NullaryOp::SizeOf`");
}
let val = layout.size.bytes();
ImmTy::from_uint(val, usize_layout())
}
AlignOf => {
if !layout.abi.is_sized() {
span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`");
}
let val = layout.align.abi.bytes();
ImmTy::from_uint(val, usize_layout())
}
OffsetOf(fields) => {
let val =
self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes();
ImmTy::from_uint(val, usize_layout())
}
UbChecks => ImmTy::from_bool(self.tcx.sess.ub_checks(), *self.tcx),
})
}
}
43 changes: 8 additions & 35 deletions compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

use either::Either;
use rustc_index::IndexSlice;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::{bug, mir, span_bug};
use rustc_middle::{bug, mir};
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
use tracing::{info, instrument, trace};

Expand Down Expand Up @@ -94,7 +93,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
M::retag_place_contents(self, *kind, &dest)?;
}

Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
Intrinsic(box intrinsic) => self.eval_nondiverging_intrinsic(intrinsic)?,

// Evaluate the place expression, without reading from it.
PlaceMention(box place) => {
Expand Down Expand Up @@ -179,6 +178,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_immediate(*result, &dest)?;
}

NullaryOp(null_op, ty) => {
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
let val = self.nullary_op(null_op, ty)?;
self.write_immediate(*val, &dest)?;
}

Aggregate(box ref kind, ref operands) => {
self.write_aggregate(kind, operands, &dest)?;
}
Expand Down Expand Up @@ -230,38 +235,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_immediate(*val, &dest)?;
}

NullaryOp(ref null_op, ty) => {
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
let layout = self.layout_of(ty)?;
if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op
&& layout.is_unsized()
{
span_bug!(
self.frame().current_span(),
"{null_op:?} MIR operator called for unsized type {ty}",
);
}
let val = match null_op {
mir::NullOp::SizeOf => {
let val = layout.size.bytes();
Scalar::from_target_usize(val, self)
}
mir::NullOp::AlignOf => {
let val = layout.align.abi.bytes();
Scalar::from_target_usize(val, self)
}
mir::NullOp::OffsetOf(fields) => {
let val = self
.tcx
.offset_of_subfield(self.param_env, layout, fields.iter())
.bytes();
Scalar::from_target_usize(val, self)
}
mir::NullOp::UbChecks => Scalar::from_bool(self.tcx.sess.ub_checks()),
};
self.write_scalar(val, &dest)?;
}

ShallowInitBox(ref operand, _) => {
let src = self.eval_operand(operand, None)?;
let v = self.read_immediate(&src)?;
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
@call(mir_call, args) => {
self.parse_call(args)
},
@call(mir_tail_call, args) => {
self.parse_tail_call(args)
},
ExprKind::Match { scrutinee, arms, .. } => {
let discr = self.parse_operand(*scrutinee)?;
self.parse_match(arms, expr.span).map(|t| TerminatorKind::SwitchInt { discr, targets: t })
Expand Down Expand Up @@ -187,6 +190,25 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
)
}

fn parse_tail_call(&self, args: &[ExprId]) -> PResult<TerminatorKind<'tcx>> {
parse_by_kind!(self, args[0], _, "tail call",
ExprKind::Call { fun, args, fn_span, .. } => {
let fun = self.parse_operand(*fun)?;
let args = args
.iter()
.map(|arg|
Ok(Spanned { node: self.parse_operand(*arg)?, span: self.thir.exprs[*arg].span } )
)
.collect::<PResult<Box<[_]>>>()?;
Ok(TerminatorKind::TailCall {
func: fun,
args,
fn_span: *fn_span,
})
},
)
}

fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
parse_by_kind!(self, expr_id, expr, "rvalue",
@call(mir_discriminant, args) => self.parse_place(args[0]).map(Rvalue::Discriminant),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use rustc_data_structures::fx::FxHashMap;
use rustc_middle::bug;
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_target::abi::call::{Conv, FnAbi, PassMode};
use tracing::instrument;

Expand Down Expand Up @@ -112,11 +112,12 @@ pub fn typeid_for_instance<'tcx>(
instance: Instance<'tcx>,
options: TypeIdOptions,
) -> String {
assert!(!instance.has_non_region_param(), "{instance:#?} must be fully monomorphic");
let transform_ty_options = TransformTyOptions::from_bits(options.bits())
.unwrap_or_else(|| bug!("typeid_for_instance: invalid option(s) `{:?}`", options.bits()));
let instance = transform_instance(tcx, instance, transform_ty_options);
let fn_abi = tcx
.fn_abi_of_instance(tcx.param_env(instance.def_id()).and((instance, ty::List::empty())))
.fn_abi_of_instance(ty::ParamEnv::reveal_all().and((instance, ty::List::empty())))
.unwrap_or_else(|error| {
bug!("typeid_for_instance: couldn't get fn_abi of instance {instance:?}: {error:?}")
});
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,7 @@ symbols! {
mir_static_mut,
mir_storage_dead,
mir_storage_live,
mir_tail_call,
mir_unreachable,
mir_unwind_cleanup,
mir_unwind_continue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub fn target() -> Target {
llvm_abiname: "lp64d".into(),
max_atomic_width: Some(64),
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
crt_static_default: false,
..base::linux_musl::opts()
},
}
Expand Down
8 changes: 8 additions & 0 deletions library/core/src/intrinsics/mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@
//! otherwise branch.
//! - [`Call`] has an associated function as well, with special syntax:
//! `Call(ret_val = function(arg1, arg2, ...), ReturnTo(next_block), UnwindContinue())`.
//! - [`TailCall`] does not have a return destination or next block, so its syntax is just
//! `TailCall(function(arg1, arg2, ...))`.

#![unstable(
feature = "custom_mir",
Expand Down Expand Up @@ -350,6 +352,12 @@ define!("mir_call",
/// - [`UnwindCleanup`]
fn Call(call: (), goto: ReturnToArg, unwind_action: UnwindActionArg)
);
define!("mir_tail_call",
/// Call a function.
///
/// The argument must be of the form `fun(arg1, arg2, ...)`.
fn TailCall<T>(call: T)
);
define!("mir_unwind_resume",
/// A terminator that resumes the unwinding.
fn UnwindResume()
Expand Down
14 changes: 12 additions & 2 deletions src/ci/docker/host-x86_64/dist-various-2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no
# Needed for apt-key to work:
dirmngr \
gpg-agent \
g++-9-arm-linux-gnueabi
g++-9-arm-linux-gnueabi \
g++-11-riscv64-linux-gnu

RUN apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys 74DA7924C5513486
RUN add-apt-repository -y 'deb https://apt.dilos.org/dilos dilos2 main'
Expand Down Expand Up @@ -73,6 +74,10 @@ RUN env \
CC=arm-linux-gnueabi-gcc-9 CFLAGS="-march=armv7-a" \
CXX=arm-linux-gnueabi-g++-9 CXXFLAGS="-march=armv7-a" \
bash musl.sh armv7 && \
env \
CC=riscv64-linux-gnu-gcc-11 \
CXX=riscv64-linux-gnu-g++-11 \
bash musl.sh riscv64gc && \
rm -rf /build/*

WORKDIR /tmp
Expand Down Expand Up @@ -125,14 +130,19 @@ ENV TARGETS=$TARGETS,x86_64-unknown-none
ENV TARGETS=$TARGETS,aarch64-unknown-uefi
ENV TARGETS=$TARGETS,i686-unknown-uefi
ENV TARGETS=$TARGETS,x86_64-unknown-uefi
ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-musl

# As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211
# we need asm in the search path for gcc-9 (for gnux32) but not in the search path of the
# cross compilers.
# Luckily one of the folders is /usr/local/include so symlink /usr/include/x86_64-linux-gnu/asm there
RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/include/asm

# musl-gcc can't find libgcc_s.so.1 since it doesn't use the standard search paths.
RUN ln -s /usr/riscv64-linux-gnu/lib/libgcc_s.so.1 /usr/lib/gcc-cross/riscv64-linux-gnu/11/

ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \
--musl-root-armv7=/musl-armv7
--musl-root-armv7=/musl-armv7 \
--musl-root-riscv64gc=/musl-riscv64gc

ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
- [riscv32*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
- [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md)
- [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md)
- [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)
Expand Down
2 changes: 1 addition & 1 deletion src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ target | notes
`powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17)
`powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17)
[`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29)
[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3)
`s390x-unknown-linux-gnu` | S390x Linux (kernel 3.2, glibc 2.17)
`x86_64-unknown-freebsd` | 64-bit FreeBSD
`x86_64-unknown-illumos` | illumos
Expand Down Expand Up @@ -354,7 +355,6 @@ target | std | host | notes
[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit
`riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD
`riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia
`riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.3)
[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD
[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
[`riscv64-linux-android`](platform-support/android.md) | | | RISC-V 64-bit Android
Expand Down
47 changes: 47 additions & 0 deletions src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# riscv64gc-unknown-linux-musl

**Tier: 2**

Target for RISC-V Linux programs using musl libc.

## Target maintainers

- [@Amanieu](https://github.com/Amanieu)
- [@kraj](https://github.com/kraj)

## Requirements

Building the target itself requires a RISC-V compiler that is supported by `cc-rs`.

## Building the target

The target can be built by enabling it for a `rustc` build.

```toml
[build]
target = ["riscv64gc-unknown-linux-musl"]
```

Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`:

```toml
[target.riscv64gc-unknown-linux-musl]
cc = "riscv64-linux-gnu-gcc"
cxx = "riscv64-linux-gnu-g++"
ar = "riscv64-linux-gnu-ar"
linker = "riscv64-linux-gnu-gcc"
```

## Building Rust programs

This target are distributed through `rustup`, and otherwise require no
special configuration.

## Cross-compilation

This target can be cross-compiled from any host.

## Testing

This target can be tested as normal with `x.py` on a RISC-V host or via QEMU
emulation.
1 change: 1 addition & 0 deletions src/tools/build-manifest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ static TARGETS: &[&str] = &[
"riscv64gc-unknown-hermit",
"riscv64gc-unknown-none-elf",
"riscv64gc-unknown-linux-gnu",
"riscv64gc-unknown-linux-musl",
"s390x-unknown-linux-gnu",
"sparc64-unknown-linux-gnu",
"sparcv9-sun-solaris",
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let this = self.eval_context_mut();

// See if the core engine can handle this intrinsic.
if this.emulate_intrinsic(instance, args, dest, ret)? {
if this.eval_intrinsic(instance, args, dest, ret)? {
return Ok(None);
}
let intrinsic_name = this.tcx.item_name(instance.def_id());
Expand Down
Loading
Loading