Commit 06b3ba23 by Richard Sandiford Committed by Richard Sandiford

[AArch64] Add MOVPRFX alternatives for SVE EXT patterns

We use EXT both to implement vec_extract for large indices and as a
permute.  In both cases we can use MOVPRFX to handle the case in which
the first input and output can't be tied.

2019-08-15  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* config/aarch64/aarch64-sve.md (*vec_extract<mode><Vel>_ext)
	(*aarch64_sve_ext<mode>): Add MOVPRFX alternatives.

gcc/testsuite/
	* gcc.target/aarch64/sve/ext_2.c: Expect a MOVPRFX.
	* gcc.target/aarch64/sve/ext_3.c: New test.

From-SVN: r274515
parent 2ae21bd1
2019-08-15 Richard Sandiford <richard.sandiford@arm.com> 2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
* config/aarch64/aarch64-sve.md (*vec_extract<mode><Vel>_ext)
(*aarch64_sve_ext<mode>): Add MOVPRFX alternatives.
2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
* config/aarch64/aarch64-sve.md (*sub<SVE_F:mode>3): Remove immediate * config/aarch64/aarch64-sve.md (*sub<SVE_F:mode>3): Remove immediate
FADD and FSUB alternatives. Add a MOVPRFX alternative for FSUBR. FADD and FSUB alternatives. Add a MOVPRFX alternative for FSUBR.
......
...@@ -1356,16 +1356,19 @@ ...@@ -1356,16 +1356,19 @@
;; Extract an element outside the range of DUP. This pattern requires the ;; Extract an element outside the range of DUP. This pattern requires the
;; source and destination to be the same. ;; source and destination to be the same.
(define_insn "*vec_extract<mode><Vel>_ext" (define_insn "*vec_extract<mode><Vel>_ext"
[(set (match_operand:<VEL> 0 "register_operand" "=w") [(set (match_operand:<VEL> 0 "register_operand" "=w, ?&w")
(vec_select:<VEL> (vec_select:<VEL>
(match_operand:SVE_ALL 1 "register_operand" "0") (match_operand:SVE_ALL 1 "register_operand" "0, w")
(parallel [(match_operand:SI 2 "const_int_operand")])))] (parallel [(match_operand:SI 2 "const_int_operand")])))]
"TARGET_SVE && INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode) >= 64" "TARGET_SVE && INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode) >= 64"
{ {
operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0])); operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0]));
operands[2] = GEN_INT (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode)); operands[2] = GEN_INT (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode));
return "ext\t%0.b, %0.b, %0.b, #%2"; return (which_alternative == 0
? "ext\t%0.b, %0.b, %0.b, #%2"
: "movprfx\t%0, %1\;ext\t%0.b, %0.b, %1.b, #%2");
} }
[(set_attr "movprfx" "*,yes")]
) )
;; ------------------------------------------------------------------------- ;; -------------------------------------------------------------------------
...@@ -4700,17 +4703,20 @@ ...@@ -4700,17 +4703,20 @@
;; Concatenate two vectors and extract a subvector. Note that the ;; Concatenate two vectors and extract a subvector. Note that the
;; immediate (third) operand is the lane index not the byte index. ;; immediate (third) operand is the lane index not the byte index.
(define_insn "*aarch64_sve_ext<mode>" (define_insn "*aarch64_sve_ext<mode>"
[(set (match_operand:SVE_ALL 0 "register_operand" "=w") [(set (match_operand:SVE_ALL 0 "register_operand" "=w, ?&w")
(unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "0") (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "0, w")
(match_operand:SVE_ALL 2 "register_operand" "w") (match_operand:SVE_ALL 2 "register_operand" "w, w")
(match_operand:SI 3 "const_int_operand")] (match_operand:SI 3 "const_int_operand")]
UNSPEC_EXT))] UNSPEC_EXT))]
"TARGET_SVE "TARGET_SVE
&& IN_RANGE (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode), 0, 255)" && IN_RANGE (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode), 0, 255)"
{ {
operands[3] = GEN_INT (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode)); operands[3] = GEN_INT (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode));
return "ext\\t%0.b, %0.b, %2.b, #%3"; return (which_alternative == 0
? "ext\\t%0.b, %0.b, %2.b, #%3"
: "movprfx\t%0, %1\;ext\\t%0.b, %0.b, %2.b, #%3");
} }
[(set_attr "movprfx" "*,yes")]
) )
;; ------------------------------------------------------------------------- ;; -------------------------------------------------------------------------
......
2019-08-15 Richard Sandiford <richard.sandiford@arm.com> 2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
* gcc.target/aarch64/sve/ext_2.c: Expect a MOVPRFX.
* gcc.target/aarch64/sve/ext_3.c: New test.
2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
* gcc.target/aarch64/sve/shift_1.c: Accept reversed shifts. * gcc.target/aarch64/sve/shift_1.c: Accept reversed shifts.
......
...@@ -14,5 +14,4 @@ foo (void) ...@@ -14,5 +14,4 @@ foo (void)
asm volatile ("" :: "w" (x)); asm volatile ("" :: "w" (x));
} }
/* { dg-final { scan-assembler {\tmov\tz0\.d, z1\.d\n} } } */ /* { dg-final { scan-assembler {\tmovprfx\tz0, z1\n\text\tz0\.b, z0\.b, z1\.b, #4\n} } } */
/* { dg-final { scan-assembler {\text\tz0\.b, z0\.b, z[01]\.b, #4\n} } } */
/* { dg-do compile } */
/* { dg-options "-O -msve-vector-bits=1024" } */
typedef int vnx4si __attribute__((vector_size (128)));
void
foo (void)
{
register int x asm ("z0");
register vnx4si y asm ("z1");
asm volatile ("" : "=w" (y));
x = y[21];
asm volatile ("" :: "w" (x));
}
/* { dg-final { scan-assembler {\tmovprfx\tz0, z1\n\text\tz0\.b, z0\.b, z1\.b, #84\n} } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment