https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114499
Bug ID: 114499
Summary: MVE: scatter base offset constraints incorrect
Product: gcc
Version: 13.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: kevin.bracey at alifsemi dot com
Target Milestone: ---
An attempt to use
uint32x4_t base;
float32x4_t value;
vstrwq_scatter_base_wb_f32(&base, -sizeof(float), value);
Generates an "unsupported" error. It does not accept -4 as a valid offset, but
it should. It's looking for a multiple of 8 from -1016 to +1016, not a multiple
of 4 from -508 to +508 as it should.
Looking at mve.md, I see a number of scatter/gather_base operations have
incorrect constraints; they're rather random.
Offsets for VLDRW/VSTRW are always 7-bit with a sign bit, representing +/-0 to
+/-127*memory size. So the W and D base forms all take -508 to 508 multiples of
4 ("O"?) or -1016 to +1016 multiples of 8 ("Ri").
The "Rl" constraint was wrongly added for just
mve_vstrwq_scatter_base_wb_p_fv4sf
(https://github.com/gcc-mirror/gcc/commit/ae180f26109bfaebb4ab0f4d45035fd075cf02c8),
and it is not required. If it was really needed for a halfword instruction its
range should be -254 to +254. It seems that mve_vector_mem_operand() handles
this range correctly for non-scatter/gather.
Some corrections I think are needed are:
mve_vldrwq_gather_base_<supf>v4si i -> O
mve_vldrwq_gather_base_<supf>v2di i -> Ri
mve_vldrwq_gather_base_z_<supf>v2di i -> Ri
mve_vldrwq_gather_base_fv4sf i -> O
mve_vldrwq_gather_base_z_fv4sf i -> O
mve_vldrwq_gather_base_wb_<supf>v4si Ri -> O
mve_vldrwq_gather_base_wb_z_<supf>v4si Ri -> O
mve_vldrwq_gather_base_wb_fv4sf Ri -> O
mve_vldrwq_gather_base_wb_z_fv4sf Ri -> O
mve_vstrwq_scatter_base_<supf>v4si i -> O
mve_vstrwq_scatter_base_fv4sf i -> O
mve_vstrwq_scatter_base_wb_<supf>v4si Ri -> O
mve_vstrwq_scatter_base_wb_p_<supf>v4si Ri -> O
mve_vstrwq_scatter_base_wb_fv4sf Ri -> O
mve_vstrwq_scatter_base_wb_p_fv4sf Rl -> O
But I don't know that that's exhaustive.