The documentation says: ------------------------------------------------------------------------- @cindex @code{vec_extract@var{m}@var{n}} instruction pattern @item @samp{vec_extract@var{m}@var{n}} Extract given field from the vector value. [...] The @var{n} mode is the mode of the field or vector of fields that should be extracted, [...] If @var{n} is a vector mode, the index is counted in units of that mode. -------------------------------------------------------------------------
However, Robin pointed out that, in practice, the index is counted in whole multiples of @var{n}. These are the semantics that x86 and target-independent code follow. This patch updates the aarch64 pattern to match, which also removes the FAIL. I think Robin has patches that update the documentation and make more use of the de facto semantics. I haven't found an existing testcase that shows the difference. We do now use the pattern for: union u { int32x4_t x; int32x2_t y[2]; }; int32x2_t f(int32x4_t x) { union u u = { x }; return u.y[1]; } but we were already generating perfect code for it. Because of that, it didn't really seem worth adding a specific dump test. Tested on aarch64-linux-gnu & pushed. Richard gcc/ * config/aarch64/aarch64-simd.md (vec_extract<mode><Vhalf>): Expect the index to be 0 or 1. --- gcc/config/aarch64/aarch64-simd.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index f1687d92eb2..d9539410147 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -8755,8 +8755,8 @@ (define_expand "vec_extract<mode><Vhalf>" "TARGET_SIMD" { int start = INTVAL (operands[2]); - if (start != 0 && start != <nunits> / 2) - FAIL; + gcc_assert (start == 0 || start == 1); + start *= <nunits> / 2; rtx sel = aarch64_gen_stepped_int_parallel (<nunits> / 2, start, 1); emit_insn (gen_aarch64_get_half<mode> (operands[0], operands[1], sel)); DONE; -- 2.25.1