Skip to content

Commit

Permalink
Rollup merge of rust-lang#67598 - jumbatm:issue67557_simd_shuffle, r=…
Browse files Browse the repository at this point in the history
…oli-obk

Fix ICE / miscompilation when inlining simd shuffle intrinsic in MIR.

Closes rust-lang#67557.

r? @oli-obk
  • Loading branch information
Mark-Simulacrum authored Dec 26, 2019
2 parents d755d79 + dca0a33 commit aa04474
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
9 changes: 6 additions & 3 deletions src/librustc_codegen_ssa/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,14 +618,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if let mir::PlaceRef {
base:
&PlaceBase::Static(box Static {
kind: StaticKind::Promoted(promoted, _),
kind: StaticKind::Promoted(promoted, substs),
ty,
def_id: _,
def_id,
}),
projection: &[],
} = place.as_ref()
{
let c = bx.tcx().const_eval_promoted(self.instance, promoted);
let c = bx.tcx().const_eval_promoted(
Instance::new(def_id, self.monomorphize(&substs)),
promoted,
);
let (llval, ty) = self.simd_shuffle_indices(
&bx,
terminator.source_info.span,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// This used to cause an ICE for an internal index out of range due to simd_shuffle_indices being
// passed the wrong Instance, causing issues with inlining. See #67557.
//
// run-pass
// compile-flags: -Zmir-opt-level=3
#![feature(platform_intrinsics, repr_simd)]

extern "platform-intrinsic" {
fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
}

#[repr(simd)]
#[derive(Debug, PartialEq)]
struct Simd2(u8, u8);

fn main() {
unsafe {
let _: Simd2 = inline_me();
}
}

#[inline(always)]
unsafe fn inline_me() -> Simd2 {
simd_shuffle2(Simd2(10, 11), Simd2(12, 13), [0, 3])
}
40 changes: 40 additions & 0 deletions src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// This used to cause assert_10_13 to unexpectingly fail, due to simd_shuffle_indices being passed
// the wrong Instance, causing issues with inlining. See #67557.
//
// run-pass
// compile-flags: -Zmir-opt-level=3
#![feature(platform_intrinsics, repr_simd)]

extern "platform-intrinsic" {
fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
}

#[repr(simd)]
#[derive(Debug, PartialEq)]
struct Simd2(u8, u8);

fn main() {
unsafe {
let p_res: Simd2 = simd_shuffle2(Simd2(10, 11), Simd2(12, 13), [0, 1]);
let a_res: Simd2 = inline_me();

assert_10_11(p_res);
assert_10_13(a_res);
}
}

#[inline(never)]
fn assert_10_11(x: Simd2) {
assert_eq!(x, Simd2(10, 11));
}

#[inline(never)]
fn assert_10_13(x: Simd2) {
assert_eq!(x, Simd2(10, 13));
}


#[inline(always)]
unsafe fn inline_me() -> Simd2 {
simd_shuffle2(Simd2(10, 11), Simd2(12, 13), [0, 3])
}

0 comments on commit aa04474

Please sign in to comment.