diff options
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-mulhrs-1.c | 49 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-mulhrs-2.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-mulhrs-3.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-mulhrs-4.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sve2/mulhrs_1.c | 63 | ||||
-rw-r--r-- | gcc/testsuite/lib/target-supports.exp | 9 |
6 files changed, 149 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/vect-mulhrs-1.c b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-1.c new file mode 100644 index 0000000..8e46ff6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-1.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" +#ifndef SIGNEDNESS +#define SIGNEDNESS signed +#endif +#ifndef BIAS +#define BIAS 0 +#endif + +#define HRS(x) ((((x) >> (15 - BIAS)) + BIAS) >> BIAS) + +void __attribute__ ((noipa)) +f (SIGNEDNESS short *restrict a, SIGNEDNESS short *restrict b, + SIGNEDNESS short *restrict c, __INTPTR_TYPE__ n) +{ + for (__INTPTR_TYPE__ i = 0; i < n; ++i) + a[i] = HRS((SIGNEDNESS int) b[i] * (SIGNEDNESS int) c[i]); +} + +#define N 50 +#define BASE1 ((SIGNEDNESS int) -1 < 0 ? -126 : 4) +#define BASE2 ((SIGNEDNESS int) -1 < 0 ? -101 : 26) +#define CONST1 0x01AB +#define CONST2 0x01CD + +int +main (void) +{ + check_vect (); + + SIGNEDNESS short a[N], b[N], c[N]; + for (int i = 0; i < N; ++i) + { + b[i] = BASE1 + i * CONST1; + c[i] = BASE2 + i * CONST2; + asm volatile ("" ::: "memory"); + } + f (a, b, c, N); + for (int i = 0; i < N; ++i) + if (a[i] != HRS(BASE1 * BASE2 + i * i * (CONST1 * CONST2) + + i * (BASE1 * CONST2 + BASE2 * CONST1))) + __builtin_abort (); + return 0; +} + +/* { dg-final { scan-tree-dump "vect_recog_mulhs_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump {\.MULHS} "vect" { target vect_mulhrs_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_mulhrs_hi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-mulhrs-2.c b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-2.c new file mode 100644 index 0000000..a16e71c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-2.c @@ -0,0 +1,9 @@ +/* { dg-require-effective-target vect_int } */ + +#define SIGNEDNESS unsigned + +#include "vect-mulhrs-1.c" + +/* { dg-final { scan-tree-dump "vect_recog_mulhs_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump {\.MULHS} "vect" { target vect_mulhrs_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_mulhrs_hi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-mulhrs-3.c b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-3.c new file mode 100644 index 0000000..e7d44d7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-3.c @@ -0,0 +1,9 @@ +/* { dg-require-effective-target vect_int } */ + +#define BIAS 1 + +#include "vect-mulhrs-1.c" + +/* { dg-final { scan-tree-dump "vect_recog_mulhs_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump {\.MULHRS} "vect" { target vect_mulhrs_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_mulhrs_hi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-mulhrs-4.c b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-4.c new file mode 100644 index 0000000..e121763 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-4.c @@ -0,0 +1,10 @@ +/* { dg-require-effective-target vect_int } */ + +#define SIGNEDNESS unsigned +#define BIAS 1 + +#include "vect-mulhrs-1.c" + +/* { dg-final { scan-tree-dump "vect_recog_mulhs_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump {\.MULHRS} "vect" { target vect_mulhrs_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_mulhrs_hi } } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/mulhrs_1.c b/gcc/testsuite/gcc.target/aarch64/sve2/mulhrs_1.c new file mode 100644 index 0000000..7970d68 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/mulhrs_1.c @@ -0,0 +1,63 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details --save-temps" } */ + +#include <stdint.h> + +#define MULTHI(TYPE, BIGGER, RND) \ +TYPE __attribute__ ((noinline, noclone)) \ +mulhs_##TYPE##_##RND (TYPE *restrict x, \ + TYPE *restrict y, TYPE *restrict z, int n) \ +{ \ + for (int i = 0; i < n; i++) \ + { \ + z[i] = ((((BIGGER)x[i] * (BIGGER)y[i]) >> \ + (sizeof(BIGGER)*8/2-2)) + RND) >> 1; \ + } \ +} + +MULTHI (int8_t, int16_t, 0) +MULTHI (int16_t, int32_t, 0) +MULTHI (int32_t, int64_t, 0) + +MULTHI (uint8_t, uint16_t, 0) +MULTHI (uint16_t, uint32_t, 0) +MULTHI (uint32_t, uint64_t, 0) + +MULTHI (int8_t, int16_t, 1) +MULTHI (int16_t, int32_t, 1) +MULTHI (int32_t, int64_t, 1) + +MULTHI (uint8_t, uint16_t, 1) +MULTHI (uint16_t, uint32_t, 1) +MULTHI (uint32_t, uint64_t, 1) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 12 "vect" } } */ + +/* { dg-final { scan-assembler-times {\tsmullb\tz[0-9]+\.h, z[0-9]+\.b, z[0-9]+\.b\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsmullt\tz[0-9]+\.h, z[0-9]+\.b, z[0-9]+\.b\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsmullb\tz[0-9]+\.s, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsmullt\tz[0-9]+\.s, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsmullb\tz[0-9]+\.d, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsmullt\tz[0-9]+\.d, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tshrnb\tz[0-9]+\.b, z[0-9]+\.h, #7\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrnt\tz[0-9]+\.b, z[0-9]+\.h, #7\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrnb\tz[0-9]+\.h, z[0-9]+\.s, #15\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrnt\tz[0-9]+\.h, z[0-9]+\.s, #15\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrnb\tz[0-9]+\.s, z[0-9]+\.d, #31\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrnt\tz[0-9]+\.s, z[0-9]+\.d, #31\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tumullb\tz[0-9]+\.h, z[0-9]+\.b, z[0-9]+\.b\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tumullt\tz[0-9]+\.h, z[0-9]+\.b, z[0-9]+\.b\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tumullb\tz[0-9]+\.s, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tumullt\tz[0-9]+\.s, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tumullb\tz[0-9]+\.d, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tumullt\tz[0-9]+\.d, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\trshrnb\tz[0-9]+\.b, z[0-9]+\.h, #7\n} 2 } } */ +/* { dg-final { scan-assembler-times {\trshrnt\tz[0-9]+\.b, z[0-9]+\.h, #7\n} 2 } } */ +/* { dg-final { scan-assembler-times {\trshrnb\tz[0-9]+\.h, z[0-9]+\.s, #15\n} 2 } } */ +/* { dg-final { scan-assembler-times {\trshrnt\tz[0-9]+\.h, z[0-9]+\.s, #15\n} 2 } } */ +/* { dg-final { scan-assembler-times {\trshrnb\tz[0-9]+\.s, z[0-9]+\.d, #31\n} 2 } } */ +/* { dg-final { scan-assembler-times {\trshrnt\tz[0-9]+\.s, z[0-9]+\.d, #31\n} 2 } } */ + diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 4f7d6cb..f05a093 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -6175,6 +6175,15 @@ proc check_effective_target_vect_avg_qi {} { && ![check_effective_target_aarch64_sve1_only] }] } +# Return 1 if the target plus current options supports both signed +# and unsigned multiply-high-with-round-and-scale operations +# on vectors of half-words. + +proc check_effective_target_vect_mulhrs_hi {} { + return [expr { [istarget aarch64*-*-*] + && [check_effective_target_aarch64_sve2] }] +} + # Return 1 if the target plus current options supports a vector # demotion (packing) of shorts (to chars) and ints (to shorts) # using modulo arithmetic, 0 otherwise. |