aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/aarch64
diff options
context:
space:
mode:
authorYuliang Wang <yuliang.wang@arm.com>2019-10-17 13:23:52 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-10-17 13:23:52 +0000
commit2d57b12e2acd52b843adbcd6d5909cb0b9f7196b (patch)
treef6350632f43285714ca4ca45428d2d9eb4e72ad4 /gcc/config/aarch64
parent9309a5470833460a6ee80cfa422b5258411be29e (diff)
downloadgcc-2d57b12e2acd52b843adbcd6d5909cb0b9f7196b.zip
gcc-2d57b12e2acd52b843adbcd6d5909cb0b9f7196b.tar.gz
gcc-2d57b12e2acd52b843adbcd6d5909cb0b9f7196b.tar.bz2
[AArch64][SVE2] Support for EOR3 and variants of BSL
2019-10-17 Yuliang Wang <yuliang.wang@arm.com> gcc/ * config/aarch64/aarch64-sve2.md (aarch64_sve2_eor3<mode>) (aarch64_sve2_nor<mode>, aarch64_sve2_nand<mode>) (aarch64_sve2_bsl<mode>, aarch64_sve2_nbsl<mode>) (aarch64_sve2_bsl1n<mode>, aarch64_sve2_bsl2n<mode>): New combine patterns. * config/aarch64/iterators.md (BSL_DUP): New int iterator for the above. (bsl_1st, bsl_2nd, bsl_dup, bsl_mov): Attributes for the above. gcc/testsuite/ * gcc.target/aarch64/sve2/eor3_1.c: New test. * gcc.target/aarch64/sve2/nlogic_1.c: As above. * gcc.target/aarch64/sve2/nlogic_2.c: As above. * gcc.target/aarch64/sve2/bitsel_1.c: As above. * gcc.target/aarch64/sve2/bitsel_2.c: As above. * gcc.target/aarch64/sve2/bitsel_3.c: As above. * gcc.target/aarch64/sve2/bitsel_4.c: As above. From-SVN: r277110
Diffstat (limited to 'gcc/config/aarch64')
-rw-r--r--gcc/config/aarch64/aarch64-sve2.md184
-rw-r--r--gcc/config/aarch64/iterators.md14
2 files changed, 198 insertions, 0 deletions
diff --git a/gcc/config/aarch64/aarch64-sve2.md b/gcc/config/aarch64/aarch64-sve2.md
index b018f5b..ecbee97 100644
--- a/gcc/config/aarch64/aarch64-sve2.md
+++ b/gcc/config/aarch64/aarch64-sve2.md
@@ -142,3 +142,187 @@
}
)
+;; Unpredicated 3-way exclusive OR.
+(define_insn "*aarch64_sve2_eor3<mode>"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w, ?&w")
+ (xor:SVE_I
+ (xor:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "0, w, w, w")
+ (match_operand:SVE_I 2 "register_operand" "w, 0, w, w"))
+ (match_operand:SVE_I 3 "register_operand" "w, w, 0, w")))]
+ "TARGET_SVE2"
+ "@
+ eor3\t%0.d, %0.d, %2.d, %3.d
+ eor3\t%0.d, %0.d, %1.d, %3.d
+ eor3\t%0.d, %0.d, %1.d, %2.d
+ movprfx\t%0, %1\;eor3\t%0.d, %0.d, %2.d, %3.d"
+ [(set_attr "movprfx" "*,*,*,yes")]
+)
+
+;; Use NBSL for vector NOR.
+(define_insn_and_rewrite "*aarch64_sve2_nor<mode>"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand 3)
+ (and:SVE_I
+ (not:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "%0, w"))
+ (not:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "w, w")))]
+ UNSPEC_PRED_X))]
+ "TARGET_SVE2"
+ "@
+ nbsl\t%0.d, %0.d, %2.d, %0.d
+ movprfx\t%0, %1\;nbsl\t%0.d, %0.d, %2.d, %0.d"
+ "&& !CONSTANT_P (operands[3])"
+ {
+ operands[3] = CONSTM1_RTX (<VPRED>mode);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Use NBSL for vector NAND.
+(define_insn_and_rewrite "*aarch64_sve2_nand<mode>"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand 3)
+ (ior:SVE_I
+ (not:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "%0, w"))
+ (not:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "w, w")))]
+ UNSPEC_PRED_X))]
+ "TARGET_SVE2"
+ "@
+ nbsl\t%0.d, %0.d, %2.d, %2.d
+ movprfx\t%0, %1\;nbsl\t%0.d, %0.d, %2.d, %2.d"
+ "&& !CONSTANT_P (operands[3])"
+ {
+ operands[3] = CONSTM1_RTX (<VPRED>mode);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Unpredicated bitwise select.
+;; (op3 ? bsl_mov : bsl_dup) == (((bsl_mov ^ bsl_dup) & op3) ^ bsl_dup)
+(define_insn "*aarch64_sve2_bsl<mode>"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (xor:SVE_I
+ (and:SVE_I
+ (xor:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "<bsl_1st>, w")
+ (match_operand:SVE_I 2 "register_operand" "<bsl_2nd>, w"))
+ (match_operand:SVE_I 3 "register_operand" "w, w"))
+ (match_dup BSL_DUP)))]
+ "TARGET_SVE2"
+ "@
+ bsl\t%0.d, %0.d, %<bsl_dup>.d, %3.d
+ movprfx\t%0, %<bsl_mov>\;bsl\t%0.d, %0.d, %<bsl_dup>.d, %3.d"
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Unpredicated bitwise inverted select.
+;; (~(op3 ? bsl_mov : bsl_dup)) == (~(((bsl_mov ^ bsl_dup) & op3) ^ bsl_dup))
+(define_insn_and_rewrite "*aarch64_sve2_nbsl<mode>"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand 4)
+ (not:SVE_I
+ (xor:SVE_I
+ (and:SVE_I
+ (xor:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "<bsl_1st>, w")
+ (match_operand:SVE_I 2 "register_operand" "<bsl_2nd>, w"))
+ (match_operand:SVE_I 3 "register_operand" "w, w"))
+ (match_dup BSL_DUP)))]
+ UNSPEC_PRED_X))]
+ "TARGET_SVE2"
+ "@
+ nbsl\t%0.d, %0.d, %<bsl_dup>.d, %3.d
+ movprfx\t%0, %<bsl_mov>\;nbsl\t%0.d, %0.d, %<bsl_dup>.d, %3.d"
+ "&& !CONSTANT_P (operands[4])"
+ {
+ operands[4] = CONSTM1_RTX (<VPRED>mode);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Unpredicated bitwise select with inverted first operand.
+;; (op3 ? ~bsl_mov : bsl_dup) == ((~(bsl_mov ^ bsl_dup) & op3) ^ bsl_dup)
+(define_insn_and_rewrite "*aarch64_sve2_bsl1n<mode>"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (xor:SVE_I
+ (and:SVE_I
+ (unspec:SVE_I
+ [(match_operand 4)
+ (not:SVE_I
+ (xor:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "<bsl_1st>, w")
+ (match_operand:SVE_I 2 "register_operand" "<bsl_2nd>, w")))]
+ UNSPEC_PRED_X)
+ (match_operand:SVE_I 3 "register_operand" "w, w"))
+ (match_dup BSL_DUP)))]
+ "TARGET_SVE2"
+ "@
+ bsl1n\t%0.d, %0.d, %<bsl_dup>.d, %3.d
+ movprfx\t%0, %<bsl_mov>\;bsl1n\t%0.d, %0.d, %<bsl_dup>.d, %3.d"
+ "&& !CONSTANT_P (operands[4])"
+ {
+ operands[4] = CONSTM1_RTX (<VPRED>mode);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Unpredicated bitwise select with inverted second operand.
+;; (bsl_dup ? bsl_mov : ~op3) == ((bsl_dup & bsl_mov) | (~op3 & ~bsl_dup))
+(define_insn_and_rewrite "*aarch64_sve2_bsl2n<mode>"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (ior:SVE_I
+ (and:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "<bsl_1st>, w")
+ (match_operand:SVE_I 2 "register_operand" "<bsl_2nd>, w"))
+ (unspec:SVE_I
+ [(match_operand 4)
+ (and:SVE_I
+ (not:SVE_I
+ (match_operand:SVE_I 3 "register_operand" "w, w"))
+ (not:SVE_I
+ (match_dup BSL_DUP)))]
+ UNSPEC_PRED_X)))]
+ "TARGET_SVE2"
+ "@
+ bsl2n\t%0.d, %0.d, %3.d, %<bsl_dup>.d
+ movprfx\t%0, %<bsl_mov>\;bsl2n\t%0.d, %0.d, %3.d, %<bsl_dup>.d"
+ "&& !CONSTANT_P (operands[4])"
+ {
+ operands[4] = CONSTM1_RTX (<VPRED>mode);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Unpredicated bitwise select with inverted second operand, alternative form.
+;; (bsl_dup ? bsl_mov : ~op3) == ((bsl_dup & bsl_mov) | (~bsl_dup & ~op3))
+(define_insn_and_rewrite "*aarch64_sve2_bsl2n<mode>"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (ior:SVE_I
+ (and:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "<bsl_1st>, w")
+ (match_operand:SVE_I 2 "register_operand" "<bsl_2nd>, w"))
+ (unspec:SVE_I
+ [(match_operand 4)
+ (and:SVE_I
+ (not:SVE_I
+ (match_dup BSL_DUP))
+ (not:SVE_I
+ (match_operand:SVE_I 3 "register_operand" "w, w")))]
+ UNSPEC_PRED_X)))]
+ "TARGET_SVE2"
+ "@
+ bsl2n\t%0.d, %0.d, %3.d, %<bsl_dup>.d
+ movprfx\t%0, %<bsl_mov>\;bsl2n\t%0.d, %0.d, %3.d, %<bsl_dup>.d"
+ "&& !CONSTANT_P (operands[4])"
+ {
+ operands[4] = CONSTM1_RTX (<VPRED>mode);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 1e321af..f879fad 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1611,6 +1611,8 @@
(define_int_iterator SHRNT [UNSPEC_SHRNT UNSPEC_RSHRNT])
+(define_int_iterator BSL_DUP [1 2])
+
(define_int_iterator DOTPROD [UNSPEC_SDOT UNSPEC_UDOT])
(define_int_iterator ADDSUBHN [UNSPEC_ADDHN UNSPEC_RADDHN
@@ -1976,6 +1978,18 @@
(UNSPEC_RADDHN2 "add")
(UNSPEC_RSUBHN2 "sub")])
+;; BSL variants: first commutative operand.
+(define_int_attr bsl_1st [(1 "w") (2 "0")])
+
+;; BSL variants: second commutative operand.
+(define_int_attr bsl_2nd [(1 "0") (2 "w")])
+
+;; BSL variants: duplicated input operand.
+(define_int_attr bsl_dup [(1 "1") (2 "2")])
+
+;; BSL variants: operand which requires preserving via movprfx.
+(define_int_attr bsl_mov [(1 "2") (2 "1")])
+
(define_int_attr offsetlr [(UNSPEC_SSLI "") (UNSPEC_USLI "")
(UNSPEC_SSRI "offset_")
(UNSPEC_USRI "offset_")])