diff options
author | Yuliang Wang <yuliang.wang@arm.com> | 2019-09-12 09:59:58 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-09-12 09:59:58 +0000 |
commit | 58cc98767aa1d8136d36467b892dc4adaf427acc (patch) | |
tree | 6b0b99d529e0034fbf28907e2a8dcc95ba22df37 /gcc/config/aarch64/aarch64-sve2.md | |
parent | 8c58d9d837098d692d313a7116ed7d4a9e271287 (diff) | |
download | gcc-58cc98767aa1d8136d36467b892dc4adaf427acc.zip gcc-58cc98767aa1d8136d36467b892dc4adaf427acc.tar.gz gcc-58cc98767aa1d8136d36467b892dc4adaf427acc.tar.bz2 |
Vectorise multiply high with scaling operations (PR 89386)
2019-09-12 Yuliang Wang <yuliang.wang@arm.com>
gcc/
PR tree-optimization/89386
* config/aarch64/aarch64-sve2.md (<su>mull<bt><Vwide>)
(<r>shrnb<mode>, <r>shrnt<mode>): New SVE2 patterns.
(<su>mulh<r>s<mode>3): New pattern for MULHRS.
* config/aarch64/iterators.md (UNSPEC_SMULLB, UNSPEC_SMULLT)
(UNSPEC_UMULLB, UNSPEC_UMULLT, UNSPEC_SHRNB, UNSPEC_SHRNT)
(UNSPEC_RSHRNB, UNSPEC_RSHRNT, UNSPEC_SMULHS, UNSPEC_SMULHRS)
UNSPEC_UMULHS, UNSPEC_UMULHRS): New unspecs.
(MULLBT, SHRNB, SHRNT, MULHRS): New int iterators.
(su, r): Handle the unspecs above.
(bt): New int attribute.
* internal-fn.def (IFN_MULHS, IFN_MULHRS): New internal functions.
* internal-fn.c (first_commutative_argument): Commutativity info for
above.
* optabs.def (smulhs_optab, smulhrs_optab, umulhs_optab)
(umulhrs_optab): New optabs.
* doc/md.texi (smulhs$var{m3}, umulhs$var{m3})
(smulhrs$var{m3}, umulhrs$var{m3}): Documentation for the above.
* tree-vect-patterns.c (vect_recog_mulhs_pattern): New pattern
function.
(vect_vect_recog_func_ptrs): Add it.
* testsuite/gcc.target/aarch64/sve2/mulhrs_1.c: New test.
* testsuite/gcc.dg/vect/vect-mulhrs-1.c: As above.
* testsuite/gcc.dg/vect/vect-mulhrs-2.c: As above.
* testsuite/gcc.dg/vect/vect-mulhrs-3.c: As above.
* testsuite/gcc.dg/vect/vect-mulhrs-4.c: As above.
* doc/sourcebuild.texi (vect_mulhrs_hi): Document new target selector.
* testsuite/lib/target-supports.exp
(check_effective_target_vect_mulhrs_hi): Return true for AArch64
with SVE2.
From-SVN: r275682
Diffstat (limited to 'gcc/config/aarch64/aarch64-sve2.md')
-rw-r--r-- | gcc/config/aarch64/aarch64-sve2.md | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/gcc/config/aarch64/aarch64-sve2.md b/gcc/config/aarch64/aarch64-sve2.md index 2334e5a..ee9acdc 100644 --- a/gcc/config/aarch64/aarch64-sve2.md +++ b/gcc/config/aarch64/aarch64-sve2.md @@ -63,3 +63,63 @@ movprfx\t%0, %2\;<sur>h<addsub>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>" [(set_attr "movprfx" "*,yes")] ) + +;; Multiply long top / bottom. +(define_insn "<su>mull<bt><Vwide>" + [(set (match_operand:<VWIDE> 0 "register_operand" "=w") + (unspec:<VWIDE> [(match_operand:SVE_BHSI 1 "register_operand" "w") + (match_operand:SVE_BHSI 2 "register_operand" "w")] + MULLBT))] + "TARGET_SVE2" + "<su>mull<bt>\t%0.<Vewtype>, %1.<Vetype>, %2.<Vetype>" +) + +;; (Rounding) Right shift narrow bottom. +(define_insn "<r>shrnb<mode>" + [(set (match_operand:SVE_BHSI 0 "register_operand" "=w") + (unspec:SVE_BHSI + [(match_operand:<VWIDE> 1 "register_operand" "w") + (match_operand 2 "aarch64_simd_shift_imm_offset_<Vel>" "")] + SHRNB))] + "TARGET_SVE2" + "<r>shrnb\t%0.<Vetype>, %1.<Vewtype>, #%2" +) + +;; (Rounding) Right shift narrow top. +(define_insn "<r>shrnt<mode>" + [(set (match_operand:SVE_BHSI 0 "register_operand" "=w") + (unspec:SVE_BHSI + [(match_operand:SVE_BHSI 1 "register_operand" "0") + (match_operand:<VWIDE> 2 "register_operand" "w") + (match_operand 3 "aarch64_simd_shift_imm_offset_<Vel>" "i")] + SHRNT))] + "TARGET_SVE2" + "<r>shrnt\t%0.<Vetype>, %2.<Vewtype>, #%3" +) + +;; Unpredicated integer multiply-high-with-(round-and-)scale. +(define_expand "<su>mulh<r>s<mode>3" + [(set (match_operand:SVE_BHSI 0 "register_operand") + (unspec:SVE_BHSI + [(match_dup 3) + (unspec:SVE_BHSI [(match_operand:SVE_BHSI 1 "register_operand") + (match_operand:SVE_BHSI 2 "register_operand")] + MULHRS)] + UNSPEC_PRED_X))] + "TARGET_SVE2" + { + operands[3] = aarch64_ptrue_reg (<VPRED>mode); + + rtx prod_b = gen_reg_rtx (<VWIDE>mode); + rtx prod_t = gen_reg_rtx (<VWIDE>mode); + emit_insn (gen_<su>mullb<Vwide> (prod_b, operands[1], operands[2])); + emit_insn (gen_<su>mullt<Vwide> (prod_t, operands[1], operands[2])); + + rtx shift = GEN_INT (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1); + emit_insn (gen_<r>shrnb<mode> (operands[0], prod_b, shift)); + emit_insn (gen_<r>shrnt<mode> (operands[0], operands[0], prod_t, shift)); + + DONE; + } +) + |