Skip to content

Commit fe08ba0

Browse files
committed
Re-block SRoA on SIMD types
Fixes 144621
1 parent ba7e63b commit fe08ba0

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

compiler/rustc_mir_transform/src/sroa.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,12 @@ fn escaping_locals<'tcx>(
7272
return true;
7373
}
7474
if let ty::Adt(def, _args) = ty.kind()
75-
&& tcx.is_lang_item(def.did(), LangItem::DynMetadata)
75+
&& (def.repr().simd() || tcx.is_lang_item(def.did(), LangItem::DynMetadata))
7676
{
77+
// Exclude #[repr(simd)] types so that they are not de-optimized into an array
78+
// (MCP#838 banned projections into SIMD types, but if the value is unused
79+
// this pass sees "all the uses are of the fields" and expands it.)
80+
7781
// codegen wants to see the `DynMetadata<T>`,
7882
// not the inner reference-to-opaque-type.
7983
return true;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
- // MIR for `foo` before ScalarReplacementOfAggregates
2+
+ // MIR for `foo` after ScalarReplacementOfAggregates
3+
4+
fn foo(_1: &[Simd<u8, 16>], _2: Simd<u8, 16>) -> () {
5+
debug simds => _1;
6+
debug _unused => _2;
7+
let mut _0: ();
8+
let _3: std::simd::Simd<u8, 16>;
9+
let _4: usize;
10+
let mut _5: usize;
11+
let mut _6: bool;
12+
scope 1 {
13+
debug a => _3;
14+
}
15+
16+
bb0: {
17+
StorageLive(_3);
18+
StorageLive(_4);
19+
_4 = const 0_usize;
20+
_5 = PtrMetadata(copy _1);
21+
_6 = Lt(copy _4, copy _5);
22+
assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
23+
}
24+
25+
bb1: {
26+
_3 = copy (*_1)[_4];
27+
StorageDead(_4);
28+
StorageDead(_3);
29+
return;
30+
}
31+
}
32+

tests/mir-opt/sroa/simd_sroa.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ needs-unwind
2+
#![feature(portable_simd)]
3+
4+
// SRoA expands things even if they're unused
5+
// <https://github.com/rust-lang/rust/issues/144621>
6+
7+
use std::simd::Simd;
8+
9+
// EMIT_MIR simd_sroa.foo.ScalarReplacementOfAggregates.diff
10+
pub(crate) fn foo(simds: &[Simd<u8, 16>], _unused: Simd<u8, 16>) {
11+
// CHECK-LABEL: fn foo
12+
// CHECK-NOT: [u8; 16]
13+
// CHECK: let [[SIMD:_.+]]: std::simd::Simd<u8, 16>;
14+
// CHECK-NOT: [u8; 16]
15+
// CHECK: [[SIMD]] = copy (*_1)[0 of 1];
16+
// CHECK-NOT: [u8; 16]
17+
let a = simds[0];
18+
}

0 commit comments

Comments
 (0)