Skip to content

Commit 1584b6a

Browse files
Rollup merge of #89298 - gcohara:issue89193, r=workingjubilee
Issue 89193 - Fix ICE when using `usize` and `isize` with SIMD gathers closes #89193 r? `@workingjubilee`
2 parents 680ff86 + 88113c5 commit 1584b6a

File tree

2 files changed

+76
-8
lines changed

2 files changed

+76
-8
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

+25-8
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_middle::ty::{self, Ty};
2020
use rustc_middle::{bug, span_bug};
2121
use rustc_span::{sym, symbol::kw, Span, Symbol};
2222
use rustc_target::abi::{self, HasDataLayout, Primitive};
23-
use rustc_target::spec::PanicStrategy;
23+
use rustc_target::spec::{HasTargetSpec, PanicStrategy};
2424

2525
use std::cmp::Ordering;
2626
use std::iter;
@@ -1190,11 +1190,28 @@ fn generic_simd_intrinsic(
11901190
// FIXME: use:
11911191
// https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Function.h#L182
11921192
// https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Intrinsics.h#L81
1193-
fn llvm_vector_str(elem_ty: Ty<'_>, vec_len: u64, no_pointers: usize) -> String {
1193+
fn llvm_vector_str(
1194+
elem_ty: Ty<'_>,
1195+
vec_len: u64,
1196+
no_pointers: usize,
1197+
bx: &Builder<'a, 'll, 'tcx>,
1198+
) -> String {
11941199
let p0s: String = "p0".repeat(no_pointers);
11951200
match *elem_ty.kind() {
1196-
ty::Int(v) => format!("v{}{}i{}", vec_len, p0s, v.bit_width().unwrap()),
1197-
ty::Uint(v) => format!("v{}{}i{}", vec_len, p0s, v.bit_width().unwrap()),
1201+
ty::Int(v) => format!(
1202+
"v{}{}i{}",
1203+
vec_len,
1204+
p0s,
1205+
// Normalize to prevent crash if v: IntTy::Isize
1206+
v.normalize(bx.target_spec().pointer_width).bit_width().unwrap()
1207+
),
1208+
ty::Uint(v) => format!(
1209+
"v{}{}i{}",
1210+
vec_len,
1211+
p0s,
1212+
// Normalize to prevent crash if v: UIntTy::Usize
1213+
v.normalize(bx.target_spec().pointer_width).bit_width().unwrap()
1214+
),
11981215
ty::Float(v) => format!("v{}{}f{}", vec_len, p0s, v.bit_width()),
11991216
_ => unreachable!(),
12001217
}
@@ -1330,11 +1347,11 @@ fn generic_simd_intrinsic(
13301347

13311348
// Type of the vector of pointers:
13321349
let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count);
1333-
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count);
1350+
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count, bx);
13341351

13351352
// Type of the vector of elements:
13361353
let llvm_elem_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count - 1);
1337-
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1);
1354+
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1, bx);
13381355

13391356
let llvm_intrinsic =
13401357
format!("llvm.masked.gather.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str);
@@ -1458,11 +1475,11 @@ fn generic_simd_intrinsic(
14581475

14591476
// Type of the vector of pointers:
14601477
let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count);
1461-
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count);
1478+
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count, bx);
14621479

14631480
// Type of the vector of elements:
14641481
let llvm_elem_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count - 1);
1465-
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1);
1482+
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1, bx);
14661483

14671484
let llvm_intrinsic =
14681485
format!("llvm.masked.scatter.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str);

src/test/ui/simd/issue-89193.rs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// run-pass
2+
3+
// Test that simd gather instructions on slice of usize don't cause crash
4+
// See issue #89183 - https://github.com/rust-lang/rust/issues/89193
5+
6+
#![feature(repr_simd, platform_intrinsics)]
7+
#![allow(non_camel_case_types)]
8+
9+
#[repr(simd)]
10+
#[derive(Copy, Clone, PartialEq, Debug)]
11+
struct x4<T>(pub T, pub T, pub T, pub T);
12+
13+
extern "platform-intrinsic" {
14+
fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
15+
}
16+
17+
fn main() {
18+
let x: [usize; 4] = [10, 11, 12, 13];
19+
let default = x4(0_usize, 1, 2, 3);
20+
let mask = x4(1_i32, 1, 1, 1);
21+
let expected = x4(10_usize, 11, 12, 13);
22+
23+
unsafe {
24+
let pointer = &x[0] as *const usize;
25+
let pointers = x4(
26+
pointer.offset(0) as *const usize,
27+
pointer.offset(1),
28+
pointer.offset(2),
29+
pointer.offset(3)
30+
);
31+
let result = simd_gather(default, pointers, mask);
32+
assert_eq!(result, expected);
33+
}
34+
35+
// and again for isize
36+
let x: [isize; 4] = [10, 11, 12, 13];
37+
let default = x4(0_isize, 1, 2, 3);
38+
let expected = x4(10_isize, 11, 12, 13);
39+
40+
unsafe {
41+
let pointer = &x[0] as *const isize;
42+
let pointers = x4(
43+
pointer.offset(0) as *const isize,
44+
pointer.offset(1),
45+
pointer.offset(2),
46+
pointer.offset(3)
47+
);
48+
let result = simd_gather(default, pointers, mask);
49+
assert_eq!(result, expected);
50+
}
51+
}

0 commit comments

Comments
 (0)