Skip to content

Commit 45b9d13

Browse files
committed
Auto merge of #146192 - jhpratt:rollup-mam0bss, r=jhpratt
Rollup of 5 pull requests Successful merges: - #145682 (Promote aarch64-pc-windows-msvc to Tier 1) - #145690 (Implement Integer funnel shifts) - #146119 (compiletest: Implement an experimental `--new-output-capture` mode) - #146168 (Update bootstrap's dependencies to remove winapi and old windows-sys) - #146182 (Don't require next-solver `ProbeRef` to be `Copy`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 79bdc62 + b4f76b3 commit 45b9d13

File tree

39 files changed

+734
-133
lines changed

39 files changed

+734
-133
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,9 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
383383
| sym::rotate_left
384384
| sym::rotate_right
385385
| sym::saturating_add
386-
| sym::saturating_sub => {
386+
| sym::saturating_sub
387+
| sym::unchecked_funnel_shl
388+
| sym::unchecked_funnel_shr => {
387389
let ty = args[0].layout.ty;
388390
if !ty.is_integral() {
389391
tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType {
@@ -424,18 +426,26 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
424426
sym::bitreverse => {
425427
self.call_intrinsic("llvm.bitreverse", &[llty], &[args[0].immediate()])
426428
}
427-
sym::rotate_left | sym::rotate_right => {
428-
let is_left = name == sym::rotate_left;
429-
let val = args[0].immediate();
430-
let raw_shift = args[1].immediate();
431-
// rotate = funnel shift with first two args the same
429+
sym::rotate_left
430+
| sym::rotate_right
431+
| sym::unchecked_funnel_shl
432+
| sym::unchecked_funnel_shr => {
433+
let is_left = name == sym::rotate_left || name == sym::unchecked_funnel_shl;
434+
let lhs = args[0].immediate();
435+
let (rhs, raw_shift) =
436+
if name == sym::rotate_left || name == sym::rotate_right {
437+
// rotate = funnel shift with first two args the same
438+
(lhs, args[1].immediate())
439+
} else {
440+
(args[1].immediate(), args[2].immediate())
441+
};
432442
let llvm_name = format!("llvm.fsh{}", if is_left { 'l' } else { 'r' });
433443

434444
// llvm expects shift to be the same type as the values, but rust
435445
// always uses `u32`.
436-
let raw_shift = self.intcast(raw_shift, self.val_ty(val), false);
446+
let raw_shift = self.intcast(raw_shift, self.val_ty(lhs), false);
437447

438-
self.call_intrinsic(llvm_name, &[llty], &[val, val, raw_shift])
448+
self.call_intrinsic(llvm_name, &[llty], &[lhs, rhs, raw_shift])
439449
}
440450
sym::saturating_add | sym::saturating_sub => {
441451
let is_add = name == sym::saturating_add;

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,9 @@ pub(crate) fn check_intrinsic_type(
449449
}
450450
sym::unchecked_shl | sym::unchecked_shr => (2, 0, vec![param(0), param(1)], param(0)),
451451
sym::rotate_left | sym::rotate_right => (1, 0, vec![param(0), tcx.types.u32], param(0)),
452+
sym::unchecked_funnel_shl | sym::unchecked_funnel_shr => {
453+
(1, 0, vec![param(0), param(0), tcx.types.u32], param(0))
454+
}
452455
sym::unchecked_add | sym::unchecked_sub | sym::unchecked_mul => {
453456
(1, 0, vec![param(0), param(0)], param(0))
454457
}

compiler/rustc_middle/src/ty/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -738,8 +738,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
738738
)
739739
}
740740

741-
type ProbeRef = &'tcx inspect::Probe<TyCtxt<'tcx>>;
742-
fn mk_probe_ref(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
741+
type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
742+
fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
743743
self.arena.alloc(probe)
744744
}
745745
fn evaluate_root_goal_for_proof_tree_raw(

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,7 @@ pub fn evaluate_root_goal_for_proof_tree_raw_provider<
12751275
>(
12761276
cx: I,
12771277
canonical_goal: CanonicalInput<I>,
1278-
) -> (QueryResult<I>, I::ProbeRef) {
1278+
) -> (QueryResult<I>, I::Probe) {
12791279
let mut inspect = inspect::ProofTreeBuilder::new();
12801280
let canonical_result = SearchGraph::<D>::evaluate_root_goal_for_proof_tree(
12811281
cx,
@@ -1284,7 +1284,7 @@ pub fn evaluate_root_goal_for_proof_tree_raw_provider<
12841284
&mut inspect,
12851285
);
12861286
let final_revision = inspect.unwrap();
1287-
(canonical_result, cx.mk_probe_ref(final_revision))
1287+
(canonical_result, cx.mk_probe(final_revision))
12881288
}
12891289

12901290
/// Evaluate a goal to build a proof tree.

compiler/rustc_span/src/symbol.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2281,6 +2281,8 @@ symbols! {
22812281
unboxed_closures,
22822282
unchecked_add,
22832283
unchecked_div,
2284+
unchecked_funnel_shl,
2285+
unchecked_funnel_shr,
22842286
unchecked_mul,
22852287
unchecked_rem,
22862288
unchecked_shl,

compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
1515
llvm_target: "aarch64-pc-windows-msvc".into(),
1616
metadata: TargetMetadata {
1717
description: Some("ARM64 Windows MSVC".into()),
18-
tier: Some(2),
18+
tier: Some(1),
1919
host_tools: Some(true),
2020
std: Some(true),
2121
},

compiler/rustc_type_ir/src/interner.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::borrow::Borrow;
12
use std::fmt::Debug;
23
use std::hash::Hash;
34
use std::ops::Deref;
@@ -383,12 +384,12 @@ pub trait Interner:
383384
defining_anchor: Self::LocalDefId,
384385
) -> Self::LocalDefIds;
385386

386-
type ProbeRef: Copy + Debug + Hash + Eq + Deref<Target = inspect::Probe<Self>>;
387-
fn mk_probe_ref(self, probe: inspect::Probe<Self>) -> Self::ProbeRef;
387+
type Probe: Debug + Hash + Eq + Borrow<inspect::Probe<Self>>;
388+
fn mk_probe(self, probe: inspect::Probe<Self>) -> Self::Probe;
388389
fn evaluate_root_goal_for_proof_tree_raw(
389390
self,
390391
canonical_goal: CanonicalInput<Self>,
391-
) -> (QueryResult<Self>, Self::ProbeRef);
392+
) -> (QueryResult<Self>, Self::Probe);
392393
}
393394

394395
/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`

compiler/rustc_type_ir/src/solve/inspect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub type CanonicalState<I, T> = Canonical<I, State<I, T>>;
4949
pub struct GoalEvaluation<I: Interner> {
5050
pub uncanonicalized_goal: Goal<I, I::Predicate>,
5151
pub orig_values: Vec<I::GenericArg>,
52-
pub final_revision: I::ProbeRef,
52+
pub final_revision: I::Probe,
5353
pub result: QueryResult<I>,
5454
}
5555

library/core/src/intrinsics/fallback.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,76 @@ impl_disjoint_bitor! {
148148
u8, u16, u32, u64, u128, usize,
149149
i8, i16, i32, i64, i128, isize,
150150
}
151+
152+
#[const_trait]
153+
#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
154+
pub trait FunnelShift: Copy + 'static {
155+
/// See [`super::unchecked_funnel_shl`]; we just need the trait indirection to handle
156+
/// different types since calling intrinsics with generics doesn't work.
157+
unsafe fn unchecked_funnel_shl(self, rhs: Self, shift: u32) -> Self;
158+
159+
/// See [`super::unchecked_funnel_shr`]; we just need the trait indirection to handle
160+
/// different types since calling intrinsics with generics doesn't work.
161+
unsafe fn unchecked_funnel_shr(self, rhs: Self, shift: u32) -> Self;
162+
}
163+
164+
macro_rules! impl_funnel_shifts {
165+
($($type:ident),*) => {$(
166+
#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
167+
impl const FunnelShift for $type {
168+
#[cfg_attr(miri, track_caller)]
169+
#[inline]
170+
unsafe fn unchecked_funnel_shl(self, rhs: Self, shift: u32) -> Self {
171+
// This implementation is also used by Miri so we have to check the precondition.
172+
// SAFETY: this is guaranteed by the caller
173+
unsafe { super::assume(shift < $type::BITS) };
174+
if shift == 0 {
175+
self
176+
} else {
177+
// SAFETY:
178+
// - `shift < T::BITS`, which satisfies `unchecked_shl`
179+
// - this also ensures that `T::BITS - shift < T::BITS` (shift = 0 is checked
180+
// above), which satisfies `unchecked_shr`
181+
// - because the types are unsigned, the combination are disjoint bits (this is
182+
// not true if they're signed, since SHR will fill in the empty space with a
183+
// sign bit, not zero)
184+
unsafe {
185+
super::disjoint_bitor(
186+
super::unchecked_shl(self, shift),
187+
super::unchecked_shr(rhs, $type::BITS - shift),
188+
)
189+
}
190+
}
191+
}
192+
193+
#[cfg_attr(miri, track_caller)]
194+
#[inline]
195+
unsafe fn unchecked_funnel_shr(self, rhs: Self, shift: u32) -> Self {
196+
// This implementation is also used by Miri so we have to check the precondition.
197+
// SAFETY: this is guaranteed by the caller
198+
unsafe { super::assume(shift < $type::BITS) };
199+
if shift == 0 {
200+
rhs
201+
} else {
202+
// SAFETY:
203+
// - `shift < T::BITS`, which satisfies `unchecked_shr`
204+
// - this also ensures that `T::BITS - shift < T::BITS` (shift = 0 is checked
205+
// above), which satisfies `unchecked_shl`
206+
// - because the types are unsigned, the combination are disjoint bits (this is
207+
// not true if they're signed, since SHR will fill in the empty space with a
208+
// sign bit, not zero)
209+
unsafe {
210+
super::disjoint_bitor(
211+
super::unchecked_shl(self, $type::BITS - shift),
212+
super::unchecked_shr(rhs, shift),
213+
)
214+
}
215+
}
216+
}
217+
}
218+
)*};
219+
}
220+
221+
impl_funnel_shifts! {
222+
u8, u16, u32, u64, u128, usize
223+
}

library/core/src/intrinsics/mod.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,6 +2102,61 @@ pub const fn saturating_add<T: Copy>(a: T, b: T) -> T;
21022102
#[rustc_intrinsic]
21032103
pub const fn saturating_sub<T: Copy>(a: T, b: T) -> T;
21042104

2105+
/// Funnel Shift left.
2106+
///
2107+
/// Concatenates `a` and `b` (with `a` in the most significant half),
2108+
/// creating an integer twice as wide. Then shift this integer left
2109+
/// by `shift`), and extract the most significant half. If `a` and `b`
2110+
/// are the same, this is equivalent to a rotate left operation.
2111+
///
2112+
/// It is undefined behavior if `shift` is greater than or equal to the
2113+
/// bit size of `T`.
2114+
///
2115+
/// Safe versions of this intrinsic are available on the integer primitives
2116+
/// via the `funnel_shl` method. For example, [`u32::funnel_shl`].
2117+
#[rustc_intrinsic]
2118+
#[rustc_nounwind]
2119+
#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
2120+
#[unstable(feature = "funnel_shifts", issue = "145686")]
2121+
#[track_caller]
2122+
#[miri::intrinsic_fallback_is_spec]
2123+
pub const unsafe fn unchecked_funnel_shl<T: [const] fallback::FunnelShift>(
2124+
a: T,
2125+
b: T,
2126+
shift: u32,
2127+
) -> T {
2128+
// SAFETY: caller ensures that `shift` is in-range
2129+
unsafe { a.unchecked_funnel_shl(b, shift) }
2130+
}
2131+
2132+
/// Funnel Shift right.
2133+
///
2134+
/// Concatenates `a` and `b` (with `a` in the most significant half),
2135+
/// creating an integer twice as wide. Then shift this integer right
2136+
/// by `shift` (taken modulo the bit size of `T`), and extract the
2137+
/// least significant half. If `a` and `b` are the same, this is equivalent
2138+
/// to a rotate right operation.
2139+
///
2140+
/// It is undefined behavior if `shift` is greater than or equal to the
2141+
/// bit size of `T`.
2142+
///
2143+
/// Safer versions of this intrinsic are available on the integer primitives
2144+
/// via the `funnel_shr` method. For example, [`u32::funnel_shr`]
2145+
#[rustc_intrinsic]
2146+
#[rustc_nounwind]
2147+
#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
2148+
#[unstable(feature = "funnel_shifts", issue = "145686")]
2149+
#[track_caller]
2150+
#[miri::intrinsic_fallback_is_spec]
2151+
pub const unsafe fn unchecked_funnel_shr<T: [const] fallback::FunnelShift>(
2152+
a: T,
2153+
b: T,
2154+
shift: u32,
2155+
) -> T {
2156+
// SAFETY: caller ensures that `shift` is in-range
2157+
unsafe { a.unchecked_funnel_shr(b, shift) }
2158+
}
2159+
21052160
/// This is an implementation detail of [`crate::ptr::read`] and should
21062161
/// not be used anywhere else. See its comments for why this exists.
21072162
///

0 commit comments

Comments
 (0)