aarch64: Add support for unpacked SVE conditional BIC

This patch adds support for unpacked conditional BIC.  The type suffix
could be taken from the element size or the container size, so the
patch continues to use the element size.  This is consistent with
the existing support for unconditional BIC.

gcc/
	* config/aarch64/aarch64-sve.md (*cond_bic<mode>_2): Extend from
	SVE_FULL_I to SVE_I.
	(*cond_bic<mode>_any): Likewise.

gcc/testsuite/
	* g++.target/aarch64/sve/cond_bic_1.C: New test.
	* g++.target/aarch64/sve/cond_bic_2.C: Likewise.
	* g++.target/aarch64/sve/cond_bic_3.C: Likewise.
	* g++.target/aarch64/sve/cond_bic_4.C: Likewise.
This commit is contained in:
Richard Sandiford 2021-01-11 18:03:25 +00:00
parent 7446de5a2a
commit 37426e0f06
5 changed files with 156 additions and 13 deletions

View File

@ -4475,13 +4475,13 @@
;; Predicated integer BIC, merging with the first input.
(define_insn "*cond_bic<mode>_2"
[(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, ?&w")
(unspec:SVE_FULL_I
[(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
(unspec:SVE_I
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(and:SVE_FULL_I
(not:SVE_FULL_I
(match_operand:SVE_FULL_I 3 "register_operand" "w, w"))
(match_operand:SVE_FULL_I 2 "register_operand" "0, w"))
(and:SVE_I
(not:SVE_I
(match_operand:SVE_I 3 "register_operand" "w, w"))
(match_operand:SVE_I 2 "register_operand" "0, w"))
(match_dup 2)]
UNSPEC_SEL))]
"TARGET_SVE"
@ -4493,14 +4493,14 @@
;; Predicated integer BIC, merging with an independent value.
(define_insn_and_rewrite "*cond_bic<mode>_any"
[(set (match_operand:SVE_FULL_I 0 "register_operand" "=&w, &w, &w, ?&w")
(unspec:SVE_FULL_I
[(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, ?&w")
(unspec:SVE_I
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
(and:SVE_FULL_I
(not:SVE_FULL_I
(match_operand:SVE_FULL_I 3 "register_operand" "w, w, w, w"))
(match_operand:SVE_FULL_I 2 "register_operand" "0, w, w, w"))
(match_operand:SVE_FULL_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")]
(and:SVE_I
(not:SVE_I
(match_operand:SVE_I 3 "register_operand" "w, w, w, w"))
(match_operand:SVE_I 2 "register_operand" "0, w, w, w"))
(match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")]
UNSPEC_SEL))]
"TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
"@

View File

@ -0,0 +1,40 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=2048 -save-temps" } */
#include <stdint.h>
#define TEST_OP(TYPE) \
TYPE \
test##_##TYPE##_reg (TYPE a, TYPE b, TYPE c) \
{ \
return c == 0 ? a & ~b : a; \
}
#define TEST_TYPE(TYPE, SIZE) \
typedef TYPE TYPE##SIZE __attribute__((vector_size(SIZE))); \
TEST_OP (TYPE##SIZE)
TEST_TYPE (uint8_t, 32)
TEST_TYPE (uint8_t, 64)
TEST_TYPE (uint16_t, 64)
TEST_TYPE (uint8_t, 128)
TEST_TYPE (uint16_t, 128)
TEST_TYPE (uint32_t, 128)
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.h, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.s, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */
/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.s, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */
/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */
/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.s, p[0-7]/m, \1\.s, z[0-9]+\.s\n} } } */
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.h, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, \1\.b\n} } } */
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.s, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, \1\.b\n} } } */
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.d, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, \1\.b\n} } } */
/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.s, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, \1\.h\n} } } */
/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.d, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, \1\.h\n} } } */
/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+)\.d, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, \1\.s\n} } } */
/* { dg-final { scan-assembler-not {\tsel\t} } } */

View File

@ -0,0 +1,31 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=2048 -save-temps" } */
#include <stdint.h>
#define TEST_OP(TYPE) \
TYPE \
test##_##TYPE##_reg (TYPE a, TYPE b, TYPE c) \
{ \
return c == 0 ? a & ~b : b; \
}
#define TEST_TYPE(TYPE, SIZE) \
typedef TYPE TYPE##SIZE __attribute__((vector_size(SIZE))); \
TEST_OP (TYPE##SIZE)
TEST_TYPE (uint8_t, 32)
TEST_TYPE (uint8_t, 64)
TEST_TYPE (uint16_t, 64)
TEST_TYPE (uint8_t, 128)
TEST_TYPE (uint16_t, 128)
TEST_TYPE (uint32_t, 128)
/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 3 } } */
/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
/* { dg-final { scan-assembler-times {\tsel\t} 6 } } */

View File

@ -0,0 +1,36 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=2048 -save-temps" } */
#include <stdint.h>
#define TEST_OP(TYPE) \
TYPE \
test##_##TYPE##_reg (TYPE a, TYPE b, TYPE c) \
{ \
return c == 0 ? a & ~b : c; \
}
#define TEST_TYPE(TYPE, SIZE) \
typedef TYPE TYPE##SIZE __attribute__((vector_size(SIZE))); \
TEST_OP (TYPE##SIZE)
TEST_TYPE (uint8_t, 32)
TEST_TYPE (uint8_t, 64)
TEST_TYPE (uint16_t, 64)
TEST_TYPE (uint8_t, 128)
TEST_TYPE (uint16_t, 128)
TEST_TYPE (uint32_t, 128)
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.h, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.s, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.d, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */
/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.s, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */
/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.d, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */
/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+)\.d, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.s, p[0-7]/m, \1\.s, z[0-9]+\.s\n} } } */
/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b\n} 3 } } */
/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 2 } } */
/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 1 } } */
/* { dg-final { scan-assembler-not {\tsel\t} } } */

View File

@ -0,0 +1,36 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=2048 -save-temps" } */
#include <stdint.h>
#define TEST_OP(TYPE) \
TYPE \
test##_##TYPE##_reg (TYPE a, TYPE b, TYPE c) \
{ \
return c == 0 ? a & ~b : 0; \
}
#define TEST_TYPE(TYPE, SIZE) \
typedef TYPE TYPE##SIZE __attribute__((vector_size(SIZE))); \
TEST_OP (TYPE##SIZE)
TEST_TYPE (uint8_t, 32)
TEST_TYPE (uint8_t, 64)
TEST_TYPE (uint16_t, 64)
TEST_TYPE (uint8_t, 128)
TEST_TYPE (uint16_t, 128)
TEST_TYPE (uint32_t, 128)
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.h, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.s, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */
/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */
/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.s, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */
/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */
/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.s, p[0-7]/m, \1\.s, z[0-9]+\.s\n} } } */
/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/z, z[0-9]+\.b\n} 3 } } */
/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/z, z[0-9]+\.h\n} 2 } } */
/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 1 } } */
/* { dg-final { scan-assembler-not {\tsel\t} } } */