If I put exactly this into ndarray’s mapv_inplace, the loop autovectorizes pretty well (Element type is f64). But it can also be ndarray’s own responsibility to provide an array wide clamp.
a.mapv_inplace(|mut x| {
if x < min { x = min };
if x > max { x = max };
x
})
(AVX instructions)
│140:┌─→vmovup xmm2,XMMWORD PTR [rcx-0x20]
│ │ vmovup xmm3,XMMWORD PTR [rcx]
│ │ vinser ymm2,ymm2,XMMWORD PTR [rcx-0x10],0x1
│ │ vinser ymm3,ymm3,XMMWORD PTR [rcx+0x10],0x1
│ │ vmaxpd ymm2,ymm0,ymm2
│ │ vmaxpd ymm3,ymm0,ymm3
│ │ vminpd ymm2,ymm1,ymm2
│ │ vminpd ymm3,ymm1,ymm3
│ │ vextra XMMWORD PTR [rcx-0x10],ymm2,0x1
│ │ vmovup XMMWORD PTR [rcx-0x20],xmm2
│ │ vextra XMMWORD PTR [rcx+0x10],ymm3,0x1
│ │ vmovup XMMWORD PTR [rcx],xmm3
│ │ add rcx,0x40
│ │ add rdx,0xfffffffffffffff8
│ └──jne 140