]> git.lizzy.rs Git - rust.git/commitdiff
Issue 89193
authorGeorge O'Hara <georgeohara92@gmail.com>
Mon, 27 Sep 2021 12:18:22 +0000 (13:18 +0100)
committerGeorge O'Hara <georgeohara92@gmail.com>
Mon, 27 Sep 2021 12:18:22 +0000 (13:18 +0100)
compiler/rustc_codegen_llvm/src/intrinsic.rs
src/test/ui/simd/issue-89193.rs [new file with mode: 0644]

index 37b3279fb80966dd3058b49c412e31fe70e9b087..8494baaa56d4c7db8788a9b1f321e09298ecde1c 100644 (file)
@@ -20,7 +20,7 @@
 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 @@ macro_rules! return_error {
     // 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 non_ptr(t: Ty<'_>) -> Ty<'_> {
 
         // 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 non_ptr(t: Ty<'_>) -> Ty<'_> {
 
         // 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);
diff --git a/src/test/ui/simd/issue-89193.rs b/src/test/ui/simd/issue-89193.rs
new file mode 100644 (file)
index 0000000..d6ebea1
--- /dev/null
@@ -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);
+    }
+    
+}
+