Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit822039b

Browse files
committed
fix simd_bitmask return type for non-power-of-two inputs, and add tests
1 parent004f5b8 commit822039b

File tree

2 files changed

+118
-15
lines changed

2 files changed

+118
-15
lines changed

‎compiler/rustc_codegen_llvm/src/intrinsic.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
11201120
let(len, _) =require_simd!(arg_tys[1],SimdArgument);
11211121

11221122
let expected_int_bits =(len.max(8) -1).next_power_of_two();
1123-
let expected_bytes = len /8 +((len %8 >0)asu64);
1123+
let expected_bytes = len.div_ceil(8);
11241124

11251125
let mask_ty = arg_tys[0];
11261126
let mask =match mask_ty.kind(){
@@ -1386,8 +1386,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
13861386
//
13871387
// The bit order of the result depends on the byte endianness, LSB-first for little
13881388
// endian and MSB-first for big endian.
1389-
let expected_int_bits = in_len.max(8);
1390-
let expected_bytes =expected_int_bits /8 +((expected_int_bits %8 >0)asu64);
1389+
let expected_int_bits =(in_len.max(8) -1).next_power_of_two();
1390+
let expected_bytes =in_len.div_ceil(8);
13911391

13921392
// Integer vector <i{in_bitwidth} x in_len>:
13931393
let(i_xn, in_elem_bitwidth) =match in_elem.kind(){
@@ -1408,6 +1408,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
14081408
};
14091409

14101410
// Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position.
1411+
// FIXME: the docs say that valid inputs are `0` or `!0`, so the shift seems unnecessary.
14111412
let shift_indices =
14121413
vec![
14131414
bx.cx.const_int(bx.type_ix(in_elem_bitwidth),(in_elem_bitwidth -1)as _);

‎tests/ui/simd/simd-bitmask.rs‎

Lines changed: 114 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//@run-pass
2-
//@ignore-endian-big behavior of simd_select_bitmask is endian-specific
32
#![feature(repr_simd, intrinsics)]
43

54
extern"rust-intrinsic"{
@@ -17,36 +16,139 @@ fn main() {
1716
let i:u8 =simd_bitmask(v);
1817
let a:[u8;1] =simd_bitmask(v);
1918

20-
assert_eq!(i,0b0101);
21-
assert_eq!(a,[0b0101]);
19+
ifcfg!(target_endian ="little"){
20+
assert_eq!(i,0b0101);
21+
assert_eq!(a,[0b0101]);
22+
}else{
23+
assert_eq!(i,0b1010);
24+
assert_eq!(a,[0b1010]);
25+
}
2226

2327
let v =Simd::<i8,16>([0,0, -1, -1,0,0,0,0,0,0,0,0, -1,0, -1,0]);
2428
let i:u16 =simd_bitmask(v);
2529
let a:[u8;2] =simd_bitmask(v);
2630

27-
assert_eq!(i,0b0101000000001100);
28-
assert_eq!(a,[0b1100,0b01010000]);
31+
ifcfg!(target_endian ="little"){
32+
assert_eq!(i,0b0101000000001100);
33+
assert_eq!(a,[0b00001100,0b01010000]);
34+
}else{
35+
assert_eq!(i,0b0011000000001010);
36+
assert_eq!(a,[0b00110000,0b00001010]);
37+
}
2938
}
3039

3140
unsafe{
32-
let a =Simd::<i32,8>([0,1,2,3,4,5,6,7]);
33-
let b =Simd::<i32,8>([8,9,10,11,12,13,14,15]);
34-
let e =[0,9,2,11,12,13,14,15];
41+
let a =Simd::<i32,4>([0,1,2,3]);
42+
let b =Simd::<i32,4>([8,9,10,11]);
43+
let e =[0,9,2,11];
3544

36-
let r =simd_select_bitmask(0b0101u8, a, b);
45+
let mask =ifcfg!(target_endian ="little"){0b0101u8}else{0b1010u8};
46+
let r =simd_select_bitmask(mask, a, b);
3747
assert_eq!(r.0, e);
3848

39-
let r =simd_select_bitmask([0b0101u8], a, b);
49+
let mask =ifcfg!(target_endian ="little"){[0b0101u8]}else{[0b1010u8]};
50+
let r =simd_select_bitmask(mask, a, b);
4051
assert_eq!(r.0, e);
4152

4253
let a =Simd::<i32,16>([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
4354
let b =Simd::<i32,16>([16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]);
4455
let e =[16,17,2,3,20,21,22,23,24,25,26,27,12,29,14,31];
4556

46-
let r =simd_select_bitmask(0b0101000000001100u16, a, b);
57+
let mask =ifcfg!(target_endian ="little"){
58+
0b0101000000001100u16
59+
}else{
60+
0b0011000000001010u16
61+
};
62+
let r =simd_select_bitmask(mask, a, b);
4763
assert_eq!(r.0, e);
4864

49-
let r =simd_select_bitmask([0b1100u8,0b01010000u8], a, b);
65+
let mask =ifcfg!(target_endian ="little"){
66+
[0b00001100u8,0b01010000u8]
67+
}else{
68+
[0b00110000u8,0b00001010u8]
69+
};
70+
let r =simd_select_bitmask(mask, a, b);
5071
assert_eq!(r.0, e);
5172
}
73+
74+
non_pow2();
75+
}
76+
77+
fnnon_pow2(){
78+
// Non-power-of-2 multi-byte mask.
79+
#[repr(simd, packed)]
80+
#[allow(non_camel_case_types)]
81+
#[derive(Copy,Clone,Debug,PartialEq)]
82+
structi32x10([i32;10]);
83+
impli32x10{
84+
fnsplat(x:i32) ->Self{
85+
Self([x;10])
86+
}
87+
}
88+
unsafe{
89+
let mask =i32x10([!0, !0,0, !0,0,0, !0,0, !0,0]);
90+
let mask_bits =ifcfg!(target_endian ="little"){0b0101001011}else{0b1101001010};
91+
let mask_bytes =
92+
ifcfg!(target_endian ="little"){[0b01001011,0b01]}else{[0b11,0b01001010]};
93+
94+
let bitmask1:u16 =simd_bitmask(mask);
95+
let bitmask2:[u8;2] =simd_bitmask(mask);
96+
assert_eq!(bitmask1, mask_bits);
97+
assert_eq!(bitmask2, mask_bytes);
98+
99+
let selected1 =simd_select_bitmask::<u16,_>(
100+
mask_bits,
101+
i32x10::splat(!0),// yes
102+
i32x10::splat(0),// no
103+
);
104+
let selected2 =simd_select_bitmask::<[u8;2],_>(
105+
mask_bytes,
106+
i32x10::splat(!0),// yes
107+
i32x10::splat(0),// no
108+
);
109+
assert_eq!(selected1, mask);
110+
assert_eq!(selected2, mask);
111+
}
112+
113+
// Test for a mask where the next multiple of 8 is not a power of two.
114+
#[repr(simd, packed)]
115+
#[allow(non_camel_case_types)]
116+
#[derive(Copy,Clone,Debug,PartialEq)]
117+
structi32x20([i32;20]);
118+
impli32x20{
119+
fnsplat(x:i32) ->Self{
120+
Self([x;20])
121+
}
122+
}
123+
unsafe{
124+
let mask =i32x20([!0, !0,0, !0,0,0, !0,0, !0,0,0,0,0, !0, !0, !0, !0, !0, !0, !0]);
125+
let mask_bits =ifcfg!(target_endian ="little"){
126+
0b11111110000101001011
127+
}else{
128+
0b11010010100001111111
129+
};
130+
let mask_bytes =ifcfg!(target_endian ="little"){
131+
[0b01001011,0b11100001,0b1111]
132+
}else{
133+
[0b1101,0b00101000,0b01111111]
134+
};
135+
136+
let bitmask1:u32 =simd_bitmask(mask);
137+
let bitmask2:[u8;3] =simd_bitmask(mask);
138+
assert_eq!(bitmask1, mask_bits);
139+
assert_eq!(bitmask2, mask_bytes);
140+
141+
let selected1 =simd_select_bitmask::<u32,_>(
142+
mask_bits,
143+
i32x20::splat(!0),// yes
144+
i32x20::splat(0),// no
145+
);
146+
let selected2 =simd_select_bitmask::<[u8;3],_>(
147+
mask_bytes,
148+
i32x20::splat(!0),// yes
149+
i32x20::splat(0),// no
150+
);
151+
assert_eq!(selected1, mask);
152+
assert_eq!(selected2, mask);
153+
}
52154
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp