Skip to content

Commit 8b4d22c

Browse files
committed
Auto merge of #67598 - jumbatm:issue67557_simd_shuffle, r=oli-obk
Fix ICE / miscompilation when inlining simd shuffle intrinsic in MIR. Closes #67557. r? @oli-obk
2 parents 3a087ad + dca0a33 commit 8b4d22c

File tree

3 files changed

+71
-3
lines changed

3 files changed

+71
-3
lines changed

src/librustc_codegen_ssa/mir/block.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -618,14 +618,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
618618
if let mir::PlaceRef {
619619
base:
620620
&PlaceBase::Static(box Static {
621-
kind: StaticKind::Promoted(promoted, _),
621+
kind: StaticKind::Promoted(promoted, substs),
622622
ty,
623-
def_id: _,
623+
def_id,
624624
}),
625625
projection: &[],
626626
} = place.as_ref()
627627
{
628-
let c = bx.tcx().const_eval_promoted(self.instance, promoted);
628+
let c = bx.tcx().const_eval_promoted(
629+
Instance::new(def_id, self.monomorphize(&substs)),
630+
promoted,
631+
);
629632
let (llval, ty) = self.simd_shuffle_indices(
630633
&bx,
631634
terminator.source_info.span,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// This used to cause an ICE for an internal index out of range due to simd_shuffle_indices being
2+
// passed the wrong Instance, causing issues with inlining. See #67557.
3+
//
4+
// run-pass
5+
// compile-flags: -Zmir-opt-level=3
6+
#![feature(platform_intrinsics, repr_simd)]
7+
8+
extern "platform-intrinsic" {
9+
fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
10+
}
11+
12+
#[repr(simd)]
13+
#[derive(Debug, PartialEq)]
14+
struct Simd2(u8, u8);
15+
16+
fn main() {
17+
unsafe {
18+
let _: Simd2 = inline_me();
19+
}
20+
}
21+
22+
#[inline(always)]
23+
unsafe fn inline_me() -> Simd2 {
24+
simd_shuffle2(Simd2(10, 11), Simd2(12, 13), [0, 3])
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// This used to cause assert_10_13 to unexpectingly fail, due to simd_shuffle_indices being passed
2+
// the wrong Instance, causing issues with inlining. See #67557.
3+
//
4+
// run-pass
5+
// compile-flags: -Zmir-opt-level=3
6+
#![feature(platform_intrinsics, repr_simd)]
7+
8+
extern "platform-intrinsic" {
9+
fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
10+
}
11+
12+
#[repr(simd)]
13+
#[derive(Debug, PartialEq)]
14+
struct Simd2(u8, u8);
15+
16+
fn main() {
17+
unsafe {
18+
let p_res: Simd2 = simd_shuffle2(Simd2(10, 11), Simd2(12, 13), [0, 1]);
19+
let a_res: Simd2 = inline_me();
20+
21+
assert_10_11(p_res);
22+
assert_10_13(a_res);
23+
}
24+
}
25+
26+
#[inline(never)]
27+
fn assert_10_11(x: Simd2) {
28+
assert_eq!(x, Simd2(10, 11));
29+
}
30+
31+
#[inline(never)]
32+
fn assert_10_13(x: Simd2) {
33+
assert_eq!(x, Simd2(10, 13));
34+
}
35+
36+
37+
#[inline(always)]
38+
unsafe fn inline_me() -> Simd2 {
39+
simd_shuffle2(Simd2(10, 11), Simd2(12, 13), [0, 3])
40+
}

0 commit comments

Comments
 (0)