sparse_strips: Port from `reinterpret_*` methods to `bitcast` (#1773)
Adjusts for https://github.com/linebender/fearless_simd/pull/284
`bitcast()` was already present in earlier versions, so this still works
with fearless_simd v0.4, all the way to the upcoming v0.7
The generated assembly is identical on SSE4.2 and AVX2. AVX-512 adds two
register moves in the large function `pt_splat_simd` gets inlined into
because the change perturbed the IR and resulted in different register
allocator choices.
diff --git a/sparse_strips/vello_common/src/flatten_simd.rs b/sparse_strips/vello_common/src/flatten_simd.rs
index e71df65..0ab71eb 100644
--- a/sparse_strips/vello_common/src/flatten_simd.rs
+++ b/sparse_strips/vello_common/src/flatten_simd.rs
@@ -400,7 +400,7 @@
#[inline(always)]
fn pt_splat_simd<S: Simd>(simd: S, pt: Point32) -> f32x8<S> {
let p_f64: f64 = bytemuck::cast(pt);
- simd.reinterpret_f32_f64x4(f64x4::splat(simd, p_f64))
+ f64x4::splat(simd, p_f64).bitcast()
}
#[inline(always)]
@@ -419,12 +419,12 @@
);
let split_single = |input: f32x4<S>| {
- let t1 = simd.reinterpret_f64_f32x4(input);
+ let t1: f64x2<S> = input.bitcast();
let p0 = simd.zip_low_f64x2(t1, t1);
let p1 = simd.zip_high_f64x2(t1, t1);
- let p0 = simd.reinterpret_f32_f64x2(p0);
- let p1 = simd.reinterpret_f32_f64x2(p1);
+ let p0: f32x4<S> = p0.bitcast();
+ let p1: f32x4<S> = p1.bitcast();
(f32x8::block_splat(p0), f32x8::block_splat(p1))
};
diff --git a/sparse_strips/vello_cpu/src/fine/common/gradient/mod.rs b/sparse_strips/vello_cpu/src/fine/common/gradient/mod.rs
index 4dc6677..422aa6d 100644
--- a/sparse_strips/vello_cpu/src/fine/common/gradient/mod.rs
+++ b/sparse_strips/vello_cpu/src/fine/common/gradient/mod.rs
@@ -145,25 +145,19 @@
indices.simd_eq(u32x8::splat(self.simd, GRADIENT_INVALID_POS));
let (invalid_1, invalid_2) = self.simd.split_mask32x8(invalid);
- let loaded_1 = self
- .simd
- .reinterpret_u32_u8x16(u8x16::from_slice(self.simd, &chunk[..16]));
+ let loaded_1: u32x4<S> =
+ u8x16::from_slice(self.simd, &chunk[..16]).bitcast();
let masked_1 =
self.simd
.select_u32x4(invalid_1, u32x4::splat(self.simd, 0), loaded_1);
- self.simd
- .reinterpret_u8_u32x4(masked_1)
- .store_slice(&mut chunk[..16]);
+ masked_1.bitcast::<u8x16<S>>().store_slice(&mut chunk[..16]);
- let loaded_2 = self
- .simd
- .reinterpret_u32_u8x16(u8x16::from_slice(self.simd, &chunk[16..]));
+ let loaded_2: u32x4<S> =
+ u8x16::from_slice(self.simd, &chunk[16..]).bitcast();
let masked_2 =
self.simd
.select_u32x4(invalid_2, u32x4::splat(self.simd, 0), loaded_2);
- self.simd
- .reinterpret_u8_u32x4(masked_2)
- .store_slice(&mut chunk[16..]);
+ masked_2.bitcast::<u8x16<S>>().store_slice(&mut chunk[16..]);
}
},
);