Skip to content

Commit d122a08

Browse files
committed
Issue 89193
1 parent 197fc85 commit d122a08

File tree

2 files changed

+78
-8
lines changed

2 files changed

+78
-8
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 25 additions & 8 deletions
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;
@@ -1187,11 +1187,28 @@ fn generic_simd_intrinsic(
11871187
// FIXME: use:
11881188
// https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Function.h#L182
11891189
// https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Intrinsics.h#L81
1190-
fn llvm_vector_str(elem_ty: Ty<'_>, vec_len: u64, no_pointers: usize) -> String {
1190+
fn llvm_vector_str(
1191+
elem_ty: Ty<'_>,
1192+
vec_len: u64,
1193+
no_pointers: usize,
1194+
bx: &Builder<'a, 'll, 'tcx>,
1195+
) -> String {
11911196
let p0s: String = "p0".repeat(no_pointers);
11921197
match *elem_ty.kind() {
1193-
ty::Int(v) => format!("v{}{}i{}", vec_len, p0s, v.bit_width().unwrap()),
1194-
ty::Uint(v) => format!("v{}{}i{}", vec_len, p0s, v.bit_width().unwrap()),
1198+
ty::Int(v) => format!(
1199+
"v{}{}i{}",
1200+
vec_len,
1201+
p0s,
1202+
// Normalize to prevent crash if v: IntTy::Isize
1203+
v.normalize(bx.target_spec().pointer_width).bit_width().unwrap()
1204+
),
1205+
ty::Uint(v) => format!(
1206+
"v{}{}i{}",
1207+
vec_len,
1208+
p0s,
1209+
// Normalize to prevent crash if v: UIntTy::Usize
1210+
v.normalize(bx.target_spec().pointer_width).bit_width().unwrap()
1211+
),
11951212
ty::Float(v) => format!("v{}{}f{}", vec_len, p0s, v.bit_width()),
11961213
_ => unreachable!(),
11971214
}
@@ -1327,11 +1344,11 @@ fn generic_simd_intrinsic(
13271344

13281345
// Type of the vector of pointers:
13291346
let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count);
1330-
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count);
1347+
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count, bx);
13311348

13321349
// Type of the vector of elements:
13331350
let llvm_elem_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count - 1);
1334-
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1);
1351+
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1, bx);
13351352

13361353
let llvm_intrinsic =
13371354
format!("llvm.masked.gather.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str);
@@ -1455,11 +1472,11 @@ fn generic_simd_intrinsic(
14551472

14561473
// Type of the vector of pointers:
14571474
let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count);
1458-
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count);
1475+
let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count, bx);
14591476

14601477
// Type of the vector of elements:
14611478
let llvm_elem_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count - 1);
1462-
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1);
1479+
let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1, bx);
14631480

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

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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+
52+
}
53+

0 commit comments

Comments
 (0)