mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-17 22:46:50 +00:00
Issue 89193
This commit is contained in:
parent
197fc8591e
commit
d122a0813a
@ -20,7 +20,7 @@ use rustc_middle::ty::{self, Ty};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{sym, symbol::kw, Span, Symbol};
|
||||
use rustc_target::abi::{self, HasDataLayout, Primitive};
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use rustc_target::spec::{HasTargetSpec, PanicStrategy};
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::iter;
|
||||
@ -1187,11 +1187,28 @@ fn generic_simd_intrinsic(
|
||||
// FIXME: use:
|
||||
// https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Function.h#L182
|
||||
// https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Intrinsics.h#L81
|
||||
fn llvm_vector_str(elem_ty: Ty<'_>, vec_len: u64, no_pointers: usize) -> String {
|
||||
fn llvm_vector_str(
|
||||
elem_ty: Ty<'_>,
|
||||
vec_len: u64,
|
||||
no_pointers: usize,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
) -> String {
|
||||
let p0s: String = "p0".repeat(no_pointers);
|
||||
match *elem_ty.kind() {
|
||||
ty::Int(v) => format!("v{}{}i{}", vec_len, p0s, v.bit_width().unwrap()),
|
||||
ty::Uint(v) => format!("v{}{}i{}", vec_len, p0s, v.bit_width().unwrap()),
|
||||
ty::Int(v) => format!(
|
||||
"v{}{}i{}",
|
||||
vec_len,
|
||||
p0s,
|
||||
// Normalize to prevent crash if v: IntTy::Isize
|
||||
v.normalize(bx.target_spec().pointer_width).bit_width().unwrap()
|
||||
),
|
||||
ty::Uint(v) => format!(
|
||||
"v{}{}i{}",
|
||||
vec_len,
|
||||
p0s,
|
||||
// Normalize to prevent crash if v: UIntTy::Usize
|
||||
v.normalize(bx.target_spec().pointer_width).bit_width().unwrap()
|
||||
),
|
||||
ty::Float(v) => format!("v{}{}f{}", vec_len, p0s, v.bit_width()),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@ -1327,11 +1344,11 @@ fn generic_simd_intrinsic(
|
||||
|
||||
// Type of the vector of pointers:
|
||||
let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count);
|
||||
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count);
|
||||
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count, bx);
|
||||
|
||||
// Type of the vector of elements:
|
||||
let llvm_elem_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count - 1);
|
||||
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1);
|
||||
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1, bx);
|
||||
|
||||
let llvm_intrinsic =
|
||||
format!("llvm.masked.gather.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str);
|
||||
@ -1455,11 +1472,11 @@ fn generic_simd_intrinsic(
|
||||
|
||||
// Type of the vector of pointers:
|
||||
let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count);
|
||||
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count);
|
||||
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count, bx);
|
||||
|
||||
// Type of the vector of elements:
|
||||
let llvm_elem_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count - 1);
|
||||
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1);
|
||||
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1, bx);
|
||||
|
||||
let llvm_intrinsic =
|
||||
format!("llvm.masked.scatter.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str);
|
||||
|
53
src/test/ui/simd/issue-89193.rs
Normal file
53
src/test/ui/simd/issue-89193.rs
Normal file
@ -0,0 +1,53 @@
|
||||
// run-pass
|
||||
|
||||
// Test that simd gather instructions on slice of usize don't cause crash
|
||||
// See issue #89183 - https://github.com/rust-lang/rust/issues/89193
|
||||
|
||||
#![feature(repr_simd, platform_intrinsics)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
struct x4<T>(pub T, pub T, pub T, pub T);
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: [usize; 4] = [10, 11, 12, 13];
|
||||
let default = x4(0_usize, 1, 2, 3);
|
||||
let mask = x4(1_i32, 1, 1, 1);
|
||||
let expected = x4(10_usize, 11, 12, 13);
|
||||
|
||||
unsafe {
|
||||
let pointer = &x[0] as *const usize;
|
||||
let pointers = x4(
|
||||
pointer.offset(0) as *const usize,
|
||||
pointer.offset(1),
|
||||
pointer.offset(2),
|
||||
pointer.offset(3)
|
||||
);
|
||||
let result = simd_gather(default, pointers, mask);
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
|
||||
// and again for isize
|
||||
let x: [isize; 4] = [10, 11, 12, 13];
|
||||
let default = x4(0_isize, 1, 2, 3);
|
||||
let expected = x4(10_isize, 11, 12, 13);
|
||||
|
||||
unsafe {
|
||||
let pointer = &x[0] as *const isize;
|
||||
let pointers = x4(
|
||||
pointer.offset(0) as *const isize,
|
||||
pointer.offset(1),
|
||||
pointer.offset(2),
|
||||
pointer.offset(3)
|
||||
);
|
||||
let result = simd_gather(default, pointers, mask);
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user