Skip to content

Commit 8f7b890

Browse files
authored
Rollup merge of rust-lang#113529 - oli-obk:simd_shuffle_evaluated, r=wesleywiser
Permit pre-evaluated constants in simd_shuffle fixes rust-lang#113500
2 parents 0959d5a + c7428d5 commit 8f7b890

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

compiler/rustc_codegen_ssa/src/mir/constant.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
6565
&self,
6666
constant: &mir::Constant<'tcx>,
6767
) -> Result<Option<ty::ValTree<'tcx>>, ErrorHandled> {
68-
let uv = match constant.literal {
68+
let uv = match self.monomorphize(constant.literal) {
6969
mir::ConstantKind::Unevaluated(uv, _) => uv.shrink(),
70+
mir::ConstantKind::Ty(c) => match c.kind() {
71+
// A constant that came from a const generic but was then used as an argument to old-style
72+
// simd_shuffle (passing as argument instead of as a generic param).
73+
rustc_type_ir::ConstKind::Value(valtree) => return Ok(Some(valtree)),
74+
other => span_bug!(constant.span, "{other:#?}"),
75+
},
76+
// We should never encounter `ConstantKind::Val` unless MIR opts (like const prop) evaluate
77+
// a constant and write that value back into `Operand`s. This could happen, but is unlikely.
78+
// Also: all users of `simd_shuffle` are on unstable and already need to take a lot of care
79+
// around intrinsics. For an issue to happen here, it would require a macro expanding to a
80+
// `simd_shuffle` call without wrapping the constant argument in a `const {}` block, but
81+
// the user pass through arbitrary expressions.
82+
// FIXME(oli-obk): replace the magic const generic argument of `simd_shuffle` with a real
83+
// const generic.
7084
other => span_bug!(constant.span, "{other:#?}"),
7185
};
7286
let uv = self.monomorphize(uv);

tests/ui/simd/shuffle.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
1-
//run-pass
1+
// run-pass
2+
// revisions: opt noopt
3+
//[noopt] compile-flags: -Copt-level=0
4+
//[opt] compile-flags: -O
25
#![feature(repr_simd, platform_intrinsics)]
6+
#![allow(incomplete_features)]
7+
#![feature(adt_const_params)]
38

49
extern "platform-intrinsic" {
510
fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
11+
fn simd_shuffle16<T, U>(x: T, y: T, idx: [u32; 16]) -> U;
612
}
713

814
#[derive(Copy, Clone)]
915
#[repr(simd)]
1016
struct Simd<T, const N: usize>([T; N]);
1117

18+
pub unsafe fn __shuffle_vector16<const IDX: [u32; 16], T, U>(x: T, y: T) -> U {
19+
simd_shuffle16(x, y, IDX)
20+
}
21+
1222
fn main() {
1323
const I1: [u32; 4] = [0, 2, 4, 6];
1424
const I2: [u32; 2] = [1, 5];
@@ -21,4 +31,16 @@ fn main() {
2131
let y: Simd<u8, 2> = simd_shuffle(a, b, I2);
2232
assert_eq!(y.0, [1, 5]);
2333
}
34+
// Test that an indirection (via an unnamed constant)
35+
// through a const generic parameter also works.
36+
// See https://github.com/rust-lang/rust/issues/113500 for details.
37+
let a = Simd::<u8, 16>([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
38+
let b = Simd::<u8, 16>([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]);
39+
unsafe {
40+
__shuffle_vector16::<
41+
{ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] },
42+
Simd<u8, 16>,
43+
Simd<u8, 16>,
44+
>(a, b);
45+
}
2446
}

0 commit comments

Comments
 (0)