Skip to content

Commit 54ab131

Browse files
committed
Clean up the validation code and add tests for it
1 parent f2f0096 commit 54ab131

File tree

5 files changed

+260
-28
lines changed

5 files changed

+260
-28
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,10 +1502,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15021502
// The memory addresses corresponding to the “off” lanes are not accessed.
15031503

15041504
// The first argument is a passthrough vector providing values for disabled lanes
1505-
let (_, element_ty0) = require_simd!(in_ty, SimdFirst);
15061505

1507-
// The element type of the second argument must be a signed integer type of any width:
1508-
let (mask_len, element_ty2) = require_simd!(arg_tys[2], SimdSecond);
1506+
// The element type of the "mask" argument must be a signed integer type of any width
1507+
let (mask_len, mask_elem) = require_simd!(arg_tys[2], SimdThird);
15091508
require_simd!(ret_ty, SimdReturn);
15101509

15111510
// Of the same length:
@@ -1527,11 +1526,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15271526
InvalidMonomorphization::ExpectedReturnType { span, name, in_ty, ret_ty }
15281527
);
15291528

1530-
// Pointer type must match the element type
1529+
// The second argument must be a pointer matching the element type
15311530
require!(
15321531
matches!(
15331532
arg_tys[1].kind(),
1534-
ty::RawPtr(p) if p.ty == in_elem && p.ty.kind() == element_ty0.kind()
1533+
ty::RawPtr(p) if p.ty == in_elem && p.ty.kind() == in_elem.kind()
15351534
),
15361535
InvalidMonomorphization::ExpectedElementType {
15371536
span,
@@ -1545,13 +1544,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15451544
);
15461545

15471546
// Mask needs to be an integer type
1548-
match element_ty2.kind() {
1547+
match mask_elem.kind() {
15491548
ty::Int(_) => (),
15501549
_ => {
15511550
return_error!(InvalidMonomorphization::ThirdArgElementType {
15521551
span,
15531552
name,
1554-
expected_element: element_ty2,
1553+
expected_element: mask_elem,
15551554
third_arg: arg_tys[2]
15561555
});
15571556
}
@@ -1600,24 +1599,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
16001599
// The memory addresses corresponding to the “off” lanes are not accessed.
16011600

16021601
// The first argument is a passthrough vector providing values for disabled lanes
1603-
let (element_len1, element_ty0) = require_simd!(in_ty, SimdFirst);
16041602

1605-
// The second argument must be a simd vector with an element type that's a pointer
1606-
// to the element type of the first argument
1607-
let (mask_len, element_ty2) = require_simd!(arg_tys[2], SimdSecond);
1603+
// The element type of the "mask" argument must be a signed integer type of any width
1604+
let (mask_len, mask_elem) = require_simd!(arg_tys[2], SimdThird);
16081605

16091606
// Of the same length:
1610-
require!(
1611-
in_len == element_len1,
1612-
InvalidMonomorphization::SecondArgumentLength {
1613-
span,
1614-
name,
1615-
in_len,
1616-
in_ty,
1617-
arg_ty: arg_tys[1],
1618-
out_len: element_len1
1619-
}
1620-
);
16211607
require!(
16221608
in_len == mask_len,
16231609
InvalidMonomorphization::ThirdArgumentLength {
@@ -1630,11 +1616,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
16301616
}
16311617
);
16321618

1633-
// Pointer type must match the element type
1619+
// The second argument must be a mutable pointer type matching the element type
16341620
require!(
16351621
matches!(
16361622
arg_tys[1].kind(),
1637-
ty::RawPtr(p) if p.ty == in_elem && p.ty.kind() == element_ty0.kind() && p.mutbl.is_mut()
1623+
ty::RawPtr(p) if p.ty == in_elem && p.ty.kind() == in_elem.kind() && p.mutbl.is_mut()
16381624
),
16391625
InvalidMonomorphization::ExpectedElementType {
16401626
span,
@@ -1647,14 +1633,14 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
16471633
}
16481634
);
16491635

1650-
// The element type of the third argument must be a signed integer type of any width:
1651-
match element_ty2.kind() {
1636+
// Mask needs to be an integer type
1637+
match mask_elem.kind() {
16521638
ty::Int(_) => (),
16531639
_ => {
16541640
return_error!(InvalidMonomorphization::ThirdArgElementType {
16551641
span,
16561642
name,
1657-
expected_element: element_ty2,
1643+
expected_element: mask_elem,
16581644
third_arg: arg_tys[2]
16591645
});
16601646
}
@@ -1676,7 +1662,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
16761662
let llvm_pointer = bx.type_ptr();
16771663

16781664
// Type of the vector of elements:
1679-
let llvm_elem_vec_ty = llvm_vector_ty(bx, element_ty0, in_len);
1665+
let llvm_elem_vec_ty = llvm_vector_ty(bx, in_elem, in_len);
16801666
let llvm_elem_vec_str = llvm_vector_str(bx, in_elem, in_len);
16811667

16821668
let llvm_intrinsic = format!("llvm.masked.store.{llvm_elem_vec_str}.p0");
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// build-fail
2+
#![feature(repr_simd, platform_intrinsics)]
3+
4+
extern "platform-intrinsic" {
5+
fn simd_masked_load<T, P, M>(values: T, pointer: P, mask: M) -> T;
6+
fn simd_masked_store<T, P, M>(values: T, pointer: P, mask: M) -> ();
7+
}
8+
9+
#[derive(Copy, Clone)]
10+
#[repr(simd)]
11+
struct Simd<T, const N: usize>([T; N]);
12+
13+
fn main() {
14+
unsafe {
15+
let mut arr = [4u8, 5, 6, 7];
16+
let default = Simd::<u8, 4>([9; 4]);
17+
18+
simd_masked_load(
19+
default,
20+
arr.as_ptr(),
21+
Simd::<i8, 8>([-1, 0, -1, -1, 0, 0, 0, 0])
22+
);
23+
//~^^^^^ ERROR expected third argument with length 4 (same as input type `Simd<u8, 4>`), found `Simd<i8, 8>` with length 8
24+
25+
simd_masked_load(
26+
default,
27+
arr.as_ptr() as *const i8,
28+
Simd::<i8, 4>([-1, 0, -1, -1])
29+
);
30+
//~^^^^^ ERROR expected element type `u8` of second argument `*const i8` to be a pointer to the element type `u8` of the first argument `Simd<u8, 4>`, found `u8` != `*_ u8`
31+
32+
simd_masked_load(
33+
Simd::<u32, 4>([9; 4]),
34+
arr.as_ptr(),
35+
Simd::<i8, 4>([-1, 0, -1, -1])
36+
);
37+
//~^^^^^ ERROR expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd<u32, 4>`, found `u32` != `*_ u32`
38+
39+
simd_masked_load(
40+
default,
41+
arr.as_ptr(),
42+
Simd::<u8, 4>([1, 0, 1, 1])
43+
);
44+
//~^^^^^ ERROR expected element type `u8` of third argument `Simd<u8, 4>` to be a signed integer type
45+
46+
simd_masked_store(
47+
Simd([5u32; 4]),
48+
arr.as_ptr(),
49+
Simd([-1i8; 4])
50+
);
51+
//~^^^^^ ERROR expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd<u32, 4>`, found `u32` != `*mut u32`
52+
53+
simd_masked_store(
54+
Simd([5u8; 4]),
55+
arr.as_ptr(),
56+
Simd([-1i8; 4])
57+
);
58+
//~^^^^^ ERROR expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd<u8, 4>`, found `u8` != `*mut u8`
59+
60+
simd_masked_store(
61+
Simd([5u8; 2]),
62+
arr.as_mut_ptr(),
63+
Simd([-1i8; 4])
64+
);
65+
//~^^^^^ ERROR expected third argument with length 2 (same as input type `Simd<u8, 2>`), found `Simd<i8, 4>` with length 4
66+
67+
simd_masked_store(
68+
Simd([5u8; 4]),
69+
arr.as_mut_ptr(),
70+
Simd([1u32; 4])
71+
);
72+
//~^^^^^ ERROR expected element type `u32` of third argument `Simd<u32, 4>` to be a signed integer type
73+
}
74+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected third argument with length 4 (same as input type `Simd<u8, 4>`), found `Simd<i8, 8>` with length 8
2+
--> $DIR/masked-load-store-build-fail.rs:18:9
3+
|
4+
LL | / simd_masked_load(
5+
LL | | default,
6+
LL | | arr.as_ptr(),
7+
LL | | Simd::<i8, 8>([-1, 0, -1, -1, 0, 0, 0, 0])
8+
LL | | );
9+
| |_________^
10+
11+
error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u8` of second argument `*const i8` to be a pointer to the element type `u8` of the first argument `Simd<u8, 4>`, found `u8` != `*_ u8`
12+
--> $DIR/masked-load-store-build-fail.rs:25:9
13+
|
14+
LL | / simd_masked_load(
15+
LL | | default,
16+
LL | | arr.as_ptr() as *const i8,
17+
LL | | Simd::<i8, 4>([-1, 0, -1, -1])
18+
LL | | );
19+
| |_________^
20+
21+
error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd<u32, 4>`, found `u32` != `*_ u32`
22+
--> $DIR/masked-load-store-build-fail.rs:32:9
23+
|
24+
LL | / simd_masked_load(
25+
LL | | Simd::<u32, 4>([9; 4]),
26+
LL | | arr.as_ptr(),
27+
LL | | Simd::<i8, 4>([-1, 0, -1, -1])
28+
LL | | );
29+
| |_________^
30+
31+
error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u8` of third argument `Simd<u8, 4>` to be a signed integer type
32+
--> $DIR/masked-load-store-build-fail.rs:39:9
33+
|
34+
LL | / simd_masked_load(
35+
LL | | default,
36+
LL | | arr.as_ptr(),
37+
LL | | Simd::<u8, 4>([1, 0, 1, 1])
38+
LL | | );
39+
| |_________^
40+
41+
error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd<u32, 4>`, found `u32` != `*mut u32`
42+
--> $DIR/masked-load-store-build-fail.rs:46:9
43+
|
44+
LL | / simd_masked_store(
45+
LL | | Simd([5u32; 4]),
46+
LL | | arr.as_ptr(),
47+
LL | | Simd([-1i8; 4])
48+
LL | | );
49+
| |_________^
50+
51+
error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd<u8, 4>`, found `u8` != `*mut u8`
52+
--> $DIR/masked-load-store-build-fail.rs:53:9
53+
|
54+
LL | / simd_masked_store(
55+
LL | | Simd([5u8; 4]),
56+
LL | | arr.as_ptr(),
57+
LL | | Simd([-1i8; 4])
58+
LL | | );
59+
| |_________^
60+
61+
error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected third argument with length 2 (same as input type `Simd<u8, 2>`), found `Simd<i8, 4>` with length 4
62+
--> $DIR/masked-load-store-build-fail.rs:60:9
63+
|
64+
LL | / simd_masked_store(
65+
LL | | Simd([5u8; 2]),
66+
LL | | arr.as_mut_ptr(),
67+
LL | | Simd([-1i8; 4])
68+
LL | | );
69+
| |_________^
70+
71+
error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u32` of third argument `Simd<u32, 4>` to be a signed integer type
72+
--> $DIR/masked-load-store-build-fail.rs:67:9
73+
|
74+
LL | / simd_masked_store(
75+
LL | | Simd([5u8; 4]),
76+
LL | | arr.as_mut_ptr(),
77+
LL | | Simd([1u32; 4])
78+
LL | | );
79+
| |_________^
80+
81+
error: aborting due to 8 previous errors
82+
83+
For more information about this error, try `rustc --explain E0511`.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// check-fail
2+
#![feature(repr_simd, platform_intrinsics)]
3+
4+
extern "platform-intrinsic" {
5+
fn simd_masked_load<T, P, M>(values: T, pointer: P, mask: M) -> T;
6+
fn simd_masked_store<T, P, M>(values: T, pointer: P, mask: M) -> ();
7+
}
8+
9+
#[derive(Copy, Clone)]
10+
#[repr(simd)]
11+
struct Simd<T, const N: usize>([T; N]);
12+
13+
fn main() {
14+
unsafe {
15+
let mut arr = [4u8, 5, 6, 7];
16+
let default = Simd::<u8, 4>([9; 4]);
17+
18+
let _x: Simd<u8, 2> = simd_masked_load(
19+
Simd::<u8, 4>([9; 4]),
20+
arr.as_ptr(),
21+
Simd::<i8, 4>([-1, 0, -1, -1])
22+
);
23+
//~^^^^ ERROR mismatched types
24+
25+
let _x: Simd<u32, 4> = simd_masked_load(
26+
default,
27+
arr.as_ptr(),
28+
Simd::<u8, 4>([1, 0, 1, 1])
29+
);
30+
//~^^^^ ERROR mismatched types
31+
}
32+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/masked-load-store-check-fail.rs:19:13
3+
|
4+
LL | let _x: Simd<u8, 2> = simd_masked_load(
5+
| ---------------- arguments to this function are incorrect
6+
LL | Simd::<u8, 4>([9; 4]),
7+
| ^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4`
8+
|
9+
= note: expected struct `Simd<_, 2>`
10+
found struct `Simd<_, 4>`
11+
help: the return type of this call is `Simd<u8, 4>` due to the type of the argument passed
12+
--> $DIR/masked-load-store-check-fail.rs:18:31
13+
|
14+
LL | let _x: Simd<u8, 2> = simd_masked_load(
15+
| _______________________________^
16+
LL | | Simd::<u8, 4>([9; 4]),
17+
| | --------------------- this argument influences the return type of `simd_masked_load`
18+
LL | | arr.as_ptr(),
19+
LL | | Simd::<i8, 4>([-1, 0, -1, -1])
20+
LL | | );
21+
| |_________^
22+
note: function defined here
23+
--> $DIR/masked-load-store-check-fail.rs:5:8
24+
|
25+
LL | fn simd_masked_load<T, P, M>(values: T, pointer: P, mask: M) -> T;
26+
| ^^^^^^^^^^^^^^^^
27+
28+
error[E0308]: mismatched types
29+
--> $DIR/masked-load-store-check-fail.rs:26:13
30+
|
31+
LL | let _x: Simd<u32, 4> = simd_masked_load(
32+
| ---------------- arguments to this function are incorrect
33+
LL | default,
34+
| ^^^^^^^ expected `Simd<u32, 4>`, found `Simd<u8, 4>`
35+
|
36+
= note: expected struct `Simd<u32, _>`
37+
found struct `Simd<u8, _>`
38+
help: the return type of this call is `Simd<u8, 4>` due to the type of the argument passed
39+
--> $DIR/masked-load-store-check-fail.rs:25:32
40+
|
41+
LL | let _x: Simd<u32, 4> = simd_masked_load(
42+
| ________________________________^
43+
LL | | default,
44+
| | ------- this argument influences the return type of `simd_masked_load`
45+
LL | | arr.as_ptr(),
46+
LL | | Simd::<u8, 4>([1, 0, 1, 1])
47+
LL | | );
48+
| |_________^
49+
note: function defined here
50+
--> $DIR/masked-load-store-check-fail.rs:5:8
51+
|
52+
LL | fn simd_masked_load<T, P, M>(values: T, pointer: P, mask: M) -> T;
53+
| ^^^^^^^^^^^^^^^^
54+
55+
error: aborting due to 2 previous errors
56+
57+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)