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

Miri subtree update #118281

Closed
wants to merge 32 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
abdfe4a
miri script: fix RUSTC_GIT error message
RalfJung Nov 18, 2023
b7b919c
Auto merge of #3174 - RalfJung:rustc-git, r=RalfJung
bors Nov 18, 2023
eba8d29
cargo-miri: when verbose, print where the sysroot is being built
RalfJung Nov 18, 2023
9ad93b3
Auto merge of #3175 - RalfJung:sysroot-verbose, r=RalfJung
bors Nov 18, 2023
cee4c57
Improve wording of `intrinsics-x86-*.rs` header
eduardosm Nov 19, 2023
991e53a
libc-misc test freebsd fixes attempt
devnexen Nov 18, 2023
6730f22
Auto merge of #3177 - devnexen:fix_pthread_misc_fbsd, r=RalfJung
bors Nov 20, 2023
81303e7
Implement all 16 AVX compare operators
eduardosm Nov 18, 2023
607208c
Auto merge of #3176 - eduardosm:cmp, r=RalfJung
bors Nov 20, 2023
9007cc4
Preparing for merge from rustc
RalfJung Nov 21, 2023
a982129
Merge from rustc
RalfJung Nov 21, 2023
1ec378d
fmt
RalfJung Nov 21, 2023
4606a23
Auto merge of #3182 - RalfJung:rustup, r=RalfJung
bors Nov 21, 2023
09358a0
Check that target features required by LLVM intrinsics are enabled
eduardosm Nov 20, 2023
faed7c5
Auto merge of #3180 - eduardosm:check-intrinsics-target-feature, r=Ra…
bors Nov 22, 2023
b65cbd4
Preparing for merge from rustc
Nov 23, 2023
54a5fdd
Merge from rustc
Nov 23, 2023
c6279e4
Auto merge of #3183 - rust-lang:rustup-2023-11-23, r=RalfJung
bors Nov 23, 2023
6eb3159
detect and test for data races between setenv and getenv
RalfJung Nov 23, 2023
c1ad8b1
remove stub android files that don't do anything
RalfJung Nov 23, 2023
377fbb9
Auto merge of #3184 - RalfJung:getenv, r=RalfJung
bors Nov 23, 2023
fb5b24a
Refactor `float_to_int_checked` to remove its generic parameter and r…
eduardosm Nov 23, 2023
5e8767b
Auto merge of #3185 - eduardosm:float_to_int_checked-generic, r=RalfJung
bors Nov 24, 2023
358741a
Preparing for merge from rustc
RalfJung Nov 25, 2023
627dcc8
Merge from rustc
RalfJung Nov 25, 2023
39046a2
fmt
RalfJung Nov 25, 2023
0a32962
bless
RalfJung Nov 25, 2023
807ba04
Auto merge of #3187 - RalfJung:rustup, r=RalfJung
bors Nov 25, 2023
9f6fa38
make tests/utils work with edition 2015
RalfJung Nov 25, 2023
a553e73
read off_t at the right size for the current target
RalfJung Nov 25, 2023
6246b75
run tests on 32bit freebsd
RalfJung Nov 25, 2023
5d44492
Auto merge of #3190 - RalfJung:freebsd32, r=RalfJung
bors Nov 25, 2023
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
Prev Previous commit
Next Next commit
Check that target features required by LLVM intrinsics are enabled
eduardosm committed Nov 22, 2023
commit 09358a05c37abd9a9a6b31a9c53d2378f8ab9d6b
18 changes: 18 additions & 0 deletions src/tools/miri/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1063,6 +1063,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
_ => span_bug!(this.cur_span(), "unexpected type: {ty:?}"),
}
}

/// Checks that target feature `target_feature` is enabled.
///
/// If not enabled, emits an UB error that states that the feature is
/// required by `intrinsic`.
fn expect_target_feature_for_intrinsic(
&self,
intrinsic: Symbol,
target_feature: &str,
) -> InterpResult<'tcx, ()> {
let this = self.eval_context_ref();
if !this.tcx.sess.unstable_target_features.contains(&Symbol::intern(target_feature)) {
throw_ub_format!(
"attempted to call intrinsic `{intrinsic}` that requires missing target feature {target_feature}"
);
}
Ok(())
}
}

impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
2 changes: 2 additions & 0 deletions src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -1008,9 +1008,11 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => {
let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
let arg = this.read_scalar(arg)?.to_i32()?;
// Note that different arguments might have different target feature requirements.
match arg {
// YIELD
1 => {
this.expect_target_feature_for_intrinsic(link_name, "v6")?;
this.yield_active_thread();
}
_ => {
1 change: 1 addition & 0 deletions src/tools/miri/src/shims/x86/aesni.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
this.expect_target_feature_for_intrinsic(link_name, "aes")?;
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.aesni.").unwrap();

13 changes: 10 additions & 3 deletions src/tools/miri/src/shims/x86/mod.rs
Original file line number Diff line number Diff line change
@@ -164,7 +164,11 @@ enum FloatBinOp {
impl FloatBinOp {
/// Convert from the `imm` argument used to specify the comparison
/// operation in intrinsics such as `llvm.x86.sse.cmp.ss`.
fn cmp_from_imm(imm: i8, intrinsic: &str) -> InterpResult<'_, Self> {
fn cmp_from_imm<'tcx>(
this: &crate::MiriInterpCx<'_, 'tcx>,
imm: i8,
intrinsic: Symbol,
) -> InterpResult<'tcx, Self> {
// Only bits 0..=4 are used, remaining should be zero.
if imm & !0b1_1111 != 0 {
throw_unsup_format!("invalid `imm` parameter of {intrinsic}: 0x{imm:x}");
@@ -174,7 +178,7 @@ impl FloatBinOp {
// Bits 0..=2 specifies the operation.
// `gt` indicates the result to be returned when the LHS is strictly
// greater than the RHS, and so on.
let (gt, lt, eq, unord) = match imm & 0b111 {
let (gt, lt, eq, mut unord) = match imm & 0b111 {
// Equal
0x0 => (false, false, true, false),
// Less-than
@@ -194,7 +198,10 @@ impl FloatBinOp {
_ => unreachable!(),
};
// When bit 3 is 1 (only possible in AVX), unord is toggled.
let unord = unord ^ (imm & 0b1000 != 0);
if imm & 0b1000 != 0 {
this.expect_target_feature_for_intrinsic(intrinsic, "avx")?;
unord = !unord;
}
Ok(Self::Cmp { gt, lt, eq, unord })
}
}
13 changes: 5 additions & 8 deletions src/tools/miri/src/shims/x86/sse.rs
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
this.expect_target_feature_for_intrinsic(link_name, "sse")?;
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse.").unwrap();
// All these intrinsics operate on 128-bit (f32x4) SIMD vectors unless stated otherwise.
@@ -107,10 +108,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
let [left, right, imm] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;

let which = FloatBinOp::cmp_from_imm(
this.read_scalar(imm)?.to_i8()?,
"llvm.x86.sse.cmp.ss",
)?;
let which =
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;

bin_op_simd_float_first::<Single>(this, which, left, right, dest)?;
}
@@ -126,10 +125,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
let [left, right, imm] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;

let which = FloatBinOp::cmp_from_imm(
this.read_scalar(imm)?.to_i8()?,
"llvm.x86.sse.cmp.ps",
)?;
let which =
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;

bin_op_simd_float_all::<Single>(this, which, left, right, dest)?;
}
13 changes: 5 additions & 8 deletions src/tools/miri/src/shims/x86/sse2.rs
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
this.expect_target_feature_for_intrinsic(link_name, "sse2")?;
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse2.").unwrap();

@@ -473,10 +474,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
let [left, right, imm] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;

let which = FloatBinOp::cmp_from_imm(
this.read_scalar(imm)?.to_i8()?,
"llvm.x86.sse2.cmp.sd",
)?;
let which =
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;

bin_op_simd_float_first::<Double>(this, which, left, right, dest)?;
}
@@ -492,10 +491,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
let [left, right, imm] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;

let which = FloatBinOp::cmp_from_imm(
this.read_scalar(imm)?.to_i8()?,
"llvm.x86.sse2.cmp.pd",
)?;
let which =
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;

bin_op_simd_float_all::<Double>(this, which, left, right, dest)?;
}
1 change: 1 addition & 0 deletions src/tools/miri/src/shims/x86/sse3.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
this.expect_target_feature_for_intrinsic(link_name, "sse3")?;
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse3.").unwrap();

1 change: 1 addition & 0 deletions src/tools/miri/src/shims/x86/sse41.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
this.expect_target_feature_for_intrinsic(link_name, "sse4.1")?;
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse41.").unwrap();

1 change: 1 addition & 0 deletions src/tools/miri/src/shims/x86/ssse3.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
this.expect_target_feature_for_intrinsic(link_name, "ssse3")?;
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.ssse3.").unwrap();

42 changes: 42 additions & 0 deletions src/tools/miri/tests/fail/shims/intrinsic_target_feature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Ignore everything except x86 and x86_64
// Any new targets that are added to CI should be ignored here.
// We cannot use `cfg`-based tricks here since the output would be
// different for non-x86 targets.
//@ignore-target-aarch64
//@ignore-target-arm
//@ignore-target-avr
//@ignore-target-s390x
//@ignore-target-thumbv7em
//@ignore-target-wasm32
// Explicitly disable SSE4.1 because it is enabled by default on macOS
//@compile-flags: -C target-feature=-sse4.1

#![feature(link_llvm_intrinsics, simd_ffi)]

#[cfg(target_arch = "x86")]
use std::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;

fn main() {
assert!(is_x86_feature_detected!("sse"));
assert!(!is_x86_feature_detected!("sse4.1"));

unsafe {
// Pass, since SSE is enabled
addss(_mm_setzero_ps(), _mm_setzero_ps());

// Fail, since SSE4.1 is not enabled
dpps(_mm_setzero_ps(), _mm_setzero_ps(), 0);
//~^ ERROR: Undefined Behavior: attempted to call intrinsic `llvm.x86.sse41.dpps` that requires missing target feature sse4.1
}
}

#[allow(improper_ctypes)]
extern "C" {
#[link_name = "llvm.x86.sse.add.ss"]
fn addss(a: __m128, b: __m128) -> __m128;

#[link_name = "llvm.x86.sse41.dpps"]
fn dpps(a: __m128, b: __m128, imm8: u8) -> __m128;
}
15 changes: 15 additions & 0 deletions src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: Undefined Behavior: attempted to call intrinsic `llvm.x86.sse41.dpps` that requires missing target feature sse4.1
--> $DIR/intrinsic_target_feature.rs:LL:CC
|
LL | dpps(_mm_setzero_ps(), _mm_setzero_ps(), 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to call intrinsic `llvm.x86.sse41.dpps` that requires missing target feature sse4.1
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `main` at $DIR/intrinsic_target_feature.rs:LL:CC

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error