Skip to content

Commit c2fb555

Browse files
committed
Change the order of arguments in simd_masked_store
1 parent 90e95e7 commit c2fb555

File tree

6 files changed

+64
-58
lines changed

6 files changed

+64
-58
lines changed

compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
10591059
}
10601060

10611061
sym::simd_scatter => {
1062-
intrinsic_args!(fx, args => (val, ptr, mask); intrinsic);
1062+
intrinsic_args!(fx, args => (mask, ptr, val); intrinsic);
10631063

10641064
let (val_lane_count, _val_lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx);
10651065
let (ptr_lane_count, _ptr_lane_ty) = ptr.layout().ty.simd_size_and_type(fx.tcx);

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,81 +1596,87 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15961596
}
15971597

15981598
if name == sym::simd_masked_store {
1599-
// simd_masked_store(values: <N x T>, pointer: *mut T,
1600-
// mask: <N x i{M}>) -> ()
1599+
// simd_masked_store(mask: <N x i{M}>, pointer: *mut T, values: <N x T>) -> ()
16011600
// * N: number of elements in the input vectors
16021601
// * T: type of the element to load
16031602
// * M: any integer width is supported, will be truncated to i1
16041603
// Stores contiguous elements to memory behind `pointer`, but only for
16051604
// those lanes whose `mask` bit is enabled.
16061605
// The memory addresses corresponding to the “off” lanes are not accessed.
16071606

1608-
// The first argument is a passthrough vector providing values for disabled lanes
1609-
16101607
// The element type of the "mask" argument must be a signed integer type of any width
1611-
let (mask_len, mask_elem) = require_simd!(arg_tys[2], SimdThird);
1608+
let mask_ty = in_ty;
1609+
let (mask_len, mask_elem) = (in_len, in_elem);
1610+
1611+
// The second argument must be a pointer matching the element type
1612+
let pointer_ty = arg_tys[1];
1613+
1614+
// The last argument specifies the values to store to memory
1615+
let values_ty = arg_tys[2];
1616+
let (values_len, values_elem) = require_simd!(values_ty, SimdThird);
16121617

16131618
// Of the same length:
16141619
require!(
1615-
in_len == mask_len,
1620+
values_len == mask_len,
16161621
InvalidMonomorphization::ThirdArgumentLength {
16171622
span,
16181623
name,
1619-
in_len,
1620-
in_ty,
1621-
arg_ty: arg_tys[2],
1622-
out_len: mask_len
1624+
in_len: mask_len,
1625+
in_ty: mask_ty,
1626+
arg_ty: values_ty,
1627+
out_len: values_len
16231628
}
16241629
);
16251630

16261631
// The second argument must be a mutable pointer type matching the element type
16271632
require!(
16281633
matches!(
1629-
arg_tys[1].kind(),
1630-
ty::RawPtr(p) if p.ty == in_elem && p.ty.kind() == in_elem.kind() && p.mutbl.is_mut()
1634+
pointer_ty.kind(),
1635+
ty::RawPtr(p) if p.ty == values_elem && p.ty.kind() == values_elem.kind() && p.mutbl.is_mut()
16311636
),
16321637
InvalidMonomorphization::ExpectedElementType {
16331638
span,
16341639
name,
1635-
expected_element: in_elem,
1636-
second_arg: arg_tys[1],
1637-
in_elem,
1638-
in_ty,
1640+
expected_element: values_elem,
1641+
second_arg: pointer_ty,
1642+
in_elem: values_elem,
1643+
in_ty: values_ty,
16391644
mutability: ExpectedPointerMutability::Mut,
16401645
}
16411646
);
16421647

1643-
// Mask needs to be an integer type
1644-
match mask_elem.kind() {
1645-
ty::Int(_) => (),
1646-
_ => {
1647-
return_error!(InvalidMonomorphization::ThirdArgElementType {
1648-
span,
1649-
name,
1650-
expected_element: mask_elem,
1651-
third_arg: arg_tys[2]
1652-
});
1648+
let expected_int_bits = (mask_len.max(8) - 1).next_power_of_two();
1649+
let expected_bytes = mask_len / 8 + ((mask_len % 8 > 0) as u64);
1650+
1651+
require!(
1652+
matches!(mask_elem.kind(), ty::Int(_)),
1653+
InvalidMonomorphization::InvalidBitmask {
1654+
span,
1655+
name,
1656+
mask_ty,
1657+
expected_int_bits,
1658+
expected_bytes
16531659
}
1654-
}
1660+
);
16551661

16561662
// Alignment of T, must be a constant integer value:
16571663
let alignment_ty = bx.type_i32();
1658-
let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32);
1664+
let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32);
16591665

16601666
// Truncate the mask vector to a vector of i1s:
16611667
let (mask, mask_ty) = {
16621668
let i1 = bx.type_i1();
16631669
let i1xn = bx.type_vector(i1, in_len);
1664-
(bx.trunc(args[2].immediate(), i1xn), i1xn)
1670+
(bx.trunc(args[0].immediate(), i1xn), i1xn)
16651671
};
16661672

16671673
let ret_t = bx.type_void();
16681674

16691675
let llvm_pointer = bx.type_ptr();
16701676

16711677
// Type of the vector of elements:
1672-
let llvm_elem_vec_ty = llvm_vector_ty(bx, in_elem, in_len);
1673-
let llvm_elem_vec_str = llvm_vector_str(bx, in_elem, in_len);
1678+
let llvm_elem_vec_ty = llvm_vector_ty(bx, values_elem, values_len);
1679+
let llvm_elem_vec_str = llvm_vector_str(bx, values_elem, values_len);
16741680

16751681
let llvm_intrinsic = format!("llvm.masked.store.{llvm_elem_vec_str}.p0");
16761682
let fn_ty = bx.type_func(&[llvm_elem_vec_ty, llvm_pointer, alignment_ty, mask_ty], ret_t);
@@ -1680,7 +1686,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
16801686
None,
16811687
None,
16821688
f,
1683-
&[args[0].immediate(), args[1].immediate(), alignment, mask],
1689+
&[args[2].immediate(), args[1].immediate(), alignment, mask],
16841690
None,
16851691
);
16861692
return Ok(v);

tests/ui/simd/masked-load-store-build-fail.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
extern "platform-intrinsic" {
55
fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
6-
fn simd_masked_store<T, P, M>(values: T, pointer: P, mask: M) -> ();
6+
fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
77
}
88

99
#[derive(Copy, Clone)]
@@ -44,31 +44,31 @@ fn main() {
4444
//~^^^^^ ERROR invalid bitmask `Simd<u8, 4>`, expected `u8` or `[u8; 1]`
4545

4646
simd_masked_store(
47-
Simd([5u32; 4]),
47+
Simd([-1i8; 4]),
4848
arr.as_ptr(),
49-
Simd([-1i8; 4])
49+
Simd([5u32; 4])
5050
);
5151
//~^^^^^ 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`
5252

5353
simd_masked_store(
54-
Simd([5u8; 4]),
54+
Simd([-1i8; 4]),
5555
arr.as_ptr(),
56-
Simd([-1i8; 4])
56+
Simd([5u8; 4])
5757
);
5858
//~^^^^^ 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`
5959

6060
simd_masked_store(
61-
Simd([5u8; 2]),
61+
Simd([-1i8; 4]),
6262
arr.as_mut_ptr(),
63-
Simd([-1i8; 4])
63+
Simd([5u8; 2])
6464
);
65-
//~^^^^^ ERROR expected third argument with length 2 (same as input type `Simd<u8, 2>`), found `Simd<i8, 4>` with length 4
65+
//~^^^^^ ERROR expected third argument with length 4 (same as input type `Simd<i8, 4>`), found `Simd<u8, 2>` with length 2
6666

6767
simd_masked_store(
68-
Simd([5u8; 4]),
68+
Simd([1u32; 4]),
6969
arr.as_mut_ptr(),
70-
Simd([1u32; 4])
70+
Simd([5u8; 4])
7171
);
72-
//~^^^^^ ERROR expected element type `u32` of third argument `Simd<u32, 4>` to be a signed integer type
72+
//~^^^^^ ERROR invalid bitmask `Simd<u32, 4>`, expected `u8` or `[u8; 1]
7373
}
7474
}

tests/ui/simd/masked-load-store-build-fail.stderr

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,39 +42,39 @@ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expecte
4242
--> $DIR/masked-load-store-build-fail.rs:46:9
4343
|
4444
LL | / simd_masked_store(
45-
LL | | Simd([5u32; 4]),
45+
LL | | Simd([-1i8; 4]),
4646
LL | | arr.as_ptr(),
47-
LL | | Simd([-1i8; 4])
47+
LL | | Simd([5u32; 4])
4848
LL | | );
4949
| |_________^
5050

5151
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`
5252
--> $DIR/masked-load-store-build-fail.rs:53:9
5353
|
5454
LL | / simd_masked_store(
55-
LL | | Simd([5u8; 4]),
55+
LL | | Simd([-1i8; 4]),
5656
LL | | arr.as_ptr(),
57-
LL | | Simd([-1i8; 4])
57+
LL | | Simd([5u8; 4])
5858
LL | | );
5959
| |_________^
6060

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
61+
error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected third argument with length 4 (same as input type `Simd<i8, 4>`), found `Simd<u8, 2>` with length 2
6262
--> $DIR/masked-load-store-build-fail.rs:60:9
6363
|
6464
LL | / simd_masked_store(
65-
LL | | Simd([5u8; 2]),
65+
LL | | Simd([-1i8; 4]),
6666
LL | | arr.as_mut_ptr(),
67-
LL | | Simd([-1i8; 4])
67+
LL | | Simd([5u8; 2])
6868
LL | | );
6969
| |_________^
7070

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
71+
error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: invalid bitmask `Simd<u32, 4>`, expected `u8` or `[u8; 1]`
7272
--> $DIR/masked-load-store-build-fail.rs:67:9
7373
|
7474
LL | / simd_masked_store(
75-
LL | | Simd([5u8; 4]),
75+
LL | | Simd([1u32; 4]),
7676
LL | | arr.as_mut_ptr(),
77-
LL | | Simd([1u32; 4])
77+
LL | | Simd([5u8; 4])
7878
LL | | );
7979
| |_________^
8080

tests/ui/simd/masked-load-store-check-fail.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
extern "platform-intrinsic" {
55
fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
6-
fn simd_masked_store<T, P, M>(values: T, pointer: P, mask: M) -> ();
6+
fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
77
}
88

99
#[derive(Copy, Clone)]

tests/ui/simd/masked-load-store.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
extern "platform-intrinsic" {
55
fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
6-
fn simd_masked_store<T, P, M>(values: T, pointer: P, mask: M) -> ();
6+
fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
77
}
88

99
#[derive(Copy, Clone)]
@@ -25,9 +25,9 @@ fn main() {
2525

2626
let mut output = [u8::MAX; 5];
2727

28-
simd_masked_store(a, output.as_mut_ptr(), Simd::<i8, 4>([-1, -1, -1, 0]));
28+
simd_masked_store(Simd::<i8, 4>([-1, -1, -1, 0]), output.as_mut_ptr(), a);
2929
assert_eq!(&output, &[0, 1, 2, u8::MAX, u8::MAX]);
30-
simd_masked_store(b, output[1..].as_mut_ptr(), Simd::<i8, 4>([0, -1, -1, 0]));
30+
simd_masked_store(Simd::<i8, 4>([0, -1, -1, 0]), output[1..].as_mut_ptr(), b);
3131
assert_eq!(&output, &[0, 1, 9, 6, u8::MAX]);
3232
}
3333
}

0 commit comments

Comments
 (0)