| Issue |
207880
|
| Summary |
[SLP] masked {s,u}{div,rem} support
|
| Labels |
llvm:SLPVectorizer,
missed-optimization
|
| Assignees |
|
| Reporter |
Andarwinux
|
https://godbolt.org/z/f6YaEYnxj
```c
#include <stdint.h>
void div_vec(uint32_t *restrict dst,const uint32_t *restrict x, const uint32_t *restrict y)
{
for (int i = 0; i < 7; i++){
dst[i] = (x[i] / y[i]);
}
}
```
LV:
```llvm
define dso_local void @div_vec(ptr noalias nofree noundef writeonly captures(none) %dst, ptr noalias nofree noundef readonly captures(none) %x, ptr noalias nofree noundef readonly captures(none) %y) local_unnamed_addr {
entry:
%active.lane.mask.entry = tail call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64 0, i64 7)
%wide.masked.load = tail call <vscale x 4 x i32> @llvm.masked.load.nxv4i32.p0(ptr align 4 %x, <vscale x 4 x i1> %active.lane.mask.entry, <vscale x 4 x i32> poison)
%wide.masked.load11 = tail call <vscale x 4 x i32> @llvm.masked.load.nxv4i32.p0(ptr align 4 %y, <vscale x 4 x i1> %active.lane.mask.entry, <vscale x 4 x i32> poison)
%0 = tail call <vscale x 4 x i32> @llvm.masked.udiv.nxv4i32(<vscale x 4 x i32> %wide.masked.load, <vscale x 4 x i32> %wide.masked.load11, <vscale x 4 x i1> %active.lane.mask.entry)
tail call void @llvm.masked.store.nxv4i32.p0(<vscale x 4 x i32> %0, ptr align 4 %dst, <vscale x 4 x i1> %active.lane.mask.entry)
ret void
}
```
```asm
div_vec:
ptrue p0.s, vl7
ld1w { z0.s }, p0/z, [x1]
ld1w { z1.s }, p0/z, [x2]
udiv z0.s, p0/m, z0.s, z1.s
st1w { z0.s }, p0, [x0]
ret
```
SLP
```llvm
define dso_local void @div_vec(ptr noalias nofree noundef writeonly captures(none) initializes((0, 28)) %dst, ptr noalias nofree noundef readonly captures(none) %x, ptr noalias nofree noundef readonly captures(none) %y) local_unnamed_addr {
entry:
%0 = load <7 x i32>, ptr %x, align 4
%1 = load <7 x i32>, ptr %y, align 4
%2 = udiv <7 x i32> %0, %1
store <7 x i32> %2, ptr %dst, align 4
ret void
}
```
```asm
div_vec:
ptrue p0.s, vl2
ldr d0, [x1, #16]
ldr d1, [x2, #16]
ldr q2, [x1]
ldr q3, [x2]
ldr w8, [x1, #24]
udivr z1.s, p0/m, z1.s, z0.s
ptrue p0.s, vl4
ldr w9, [x2, #24]
udiv w8, w8, w9
str w8, [x0, #24]
udiv z2.s, p0/m, z2.s, z3.s
splice z0.s, p0, { z0.s, z1.s }
mov z0.d, z0.d[2]
str d0, [x0, #16]
str q2, [x0]
ret
```
Similar to load/store in #203756, backend codegen for unmasked non-pow2 {s,u}{div,rem} is not as good as masked pow2 - for non-pow2 SLP, it is best to convert them to masked pow2.
Use SVE VLS-256 as a demo, since X86 vector div/rem [support](https://github.com/llvm/llvm-project/pull/205263) is not yet available.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs