From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1448) id 4CA083851C18; Wed, 14 Apr 2021 14:16:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4CA083851C18 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Andreas Krebbel To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-8177] IBM Z: Fix error checking for immediate builtin operands X-Act-Checkin: gcc X-Git-Author: Andreas Krebbel X-Git-Refname: refs/heads/master X-Git-Oldrev: 527bc0181d3ea36f11dcaa8aea7704466bd0f01b X-Git-Newrev: 3191c1f4488d1f7563b563d7ae2a102a26f16d82 Message-Id: <20210414141625.4CA083851C18@sourceware.org> Date: Wed, 14 Apr 2021 14:16:25 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 14 Apr 2021 14:16:25 -0000 https://gcc.gnu.org/g:3191c1f4488d1f7563b563d7ae2a102a26f16d82 commit r11-8177-g3191c1f4488d1f7563b563d7ae2a102a26f16d82 Author: Andreas Krebbel Date: Wed Apr 14 16:07:17 2021 +0200 IBM Z: Fix error checking for immediate builtin operands This fixes the error checking for two of the vector builtins which accept irregular (e.g. non-contigiuous) ranges of values. gcc/ChangeLog: * config/s390/s390-builtins.def (O_M5, O_M12, ...): Add new macros for mask operand types. (s390_vec_permi_s64, s390_vec_permi_b64, s390_vec_permi_u64) (s390_vec_permi_dbl, s390_vpdi): Use the M5 type for the immediate operand. (s390_vec_msum_u128, s390_vmslg): Use the M12 type for the immediate operand. * config/s390/s390.c (s390_const_operand_ok): Check the new operand types and generate a list of valid values. gcc/testsuite/ChangeLog: * gcc.target/s390/zvector/imm-range-error-1.c: New test. * gcc.target/s390/zvector/vec_msum_u128-1.c: New test. Diff: --- gcc/config/s390/s390-builtins.def | 85 ++++++++++++++-------- gcc/config/s390/s390.c | 35 +++++++-- .../gcc.target/s390/zvector/imm-range-error-1.c | 26 +++++++ .../gcc.target/s390/zvector/vec_msum_u128-1.c | 45 ++++++++++++ 4 files changed, 156 insertions(+), 35 deletions(-) diff --git a/gcc/config/s390/s390-builtins.def b/gcc/config/s390/s390-builtins.def index 129d7124cba..f77ab750d22 100644 --- a/gcc/config/s390/s390-builtins.def +++ b/gcc/config/s390/s390-builtins.def @@ -29,6 +29,9 @@ #undef O_U16 #undef O_U32 +#undef O_M5 +#undef O_M12 + #undef O_S2 #undef O_S3 #undef O_S4 @@ -37,6 +40,7 @@ #undef O_S12 #undef O_S16 #undef O_S32 + #undef O_ELEM #undef O_LIT @@ -85,6 +89,16 @@ #undef O3_U32 #undef O4_U32 +#undef O1_M5 +#undef O2_M5 +#undef O3_M5 +#undef O4_M5 + +#undef O1_M12 +#undef O2_M12 +#undef O3_M12 +#undef O4_M12 + #undef O1_S2 #undef O2_S2 #undef O3_S2 @@ -140,31 +154,34 @@ #undef O_UIMM_P #undef O_SIMM_P -#define O_U1 1 /* unsigned 1 bit literal */ -#define O_U2 2 /* unsigned 2 bit literal */ -#define O_U3 3 /* unsigned 3 bit literal */ -#define O_U4 4 /* unsigned 4 bit literal */ -#define O_U5 5 /* unsigned 5 bit literal */ -#define O_U8 6 /* unsigned 8 bit literal */ -#define O_U12 7 /* unsigned 16 bit literal */ -#define O_U16 8 /* unsigned 16 bit literal */ -#define O_U32 9 /* unsigned 32 bit literal */ - -#define O_S2 10 /* signed 2 bit literal */ -#define O_S3 11 /* signed 3 bit literal */ -#define O_S4 12 /* signed 4 bit literal */ -#define O_S5 13 /* signed 5 bit literal */ -#define O_S8 14 /* signed 8 bit literal */ -#define O_S12 15 /* signed 12 bit literal */ -#define O_S16 16 /* signed 16 bit literal */ -#define O_S32 17 /* signed 32 bit literal */ - -#define O_ELEM 18 /* Element selector requiring modulo arithmetic. */ -#define O_LIT 19 /* Operand must be a literal fitting the target type. */ +#define O_U1 1 /* unsigned 1 bit literal */ +#define O_U2 2 /* unsigned 2 bit literal */ +#define O_U3 3 /* unsigned 3 bit literal */ +#define O_U4 4 /* unsigned 4 bit literal */ +#define O_U5 5 /* unsigned 5 bit literal */ +#define O_U8 6 /* unsigned 8 bit literal */ +#define O_U12 7 /* unsigned 16 bit literal */ +#define O_U16 8 /* unsigned 16 bit literal */ +#define O_U32 9 /* unsigned 32 bit literal */ + +#define O_M5 10 /* matches bitmask of 5 */ +#define O_M12 11 /* matches bitmask of 12 */ + +#define O_S2 12 /* signed 2 bit literal */ +#define O_S3 13 /* signed 3 bit literal */ +#define O_S4 14 /* signed 4 bit literal */ +#define O_S5 15 /* signed 5 bit literal */ +#define O_S8 16 /* signed 8 bit literal */ +#define O_S12 17 /* signed 12 bit literal */ +#define O_S16 18 /* signed 16 bit literal */ +#define O_S32 19 /* signed 32 bit literal */ + +#define O_ELEM 20 /* Element selector requiring modulo arithmetic. */ +#define O_LIT 21 /* Operand must be a literal fitting the target type. */ #define O_SHIFT 5 -#define O_UIMM_P(X) ((X) >= O_U1 && (X) <= O_U32) +#define O_UIMM_P(X) ((X) >= O_U1 && (X) <= O_M12) #define O_SIMM_P(X) ((X) >= O_S2 && (X) <= O_S32) #define O_IMM_P(X) ((X) == O_LIT || ((X) >= O_U1 && (X) <= O_S32)) @@ -213,6 +230,16 @@ #define O3_U32 (O_U32 << (2 * O_SHIFT)) #define O4_U32 (O_U32 << (3 * O_SHIFT)) +#define O1_M5 O_M5 +#define O2_M5 (O_M5 << O_SHIFT) +#define O3_M5 (O_M5 << (2 * O_SHIFT)) +#define O4_M5 (O_M5 << (3 * O_SHIFT)) + +#define O1_M12 O_M12 +#define O2_M12 (O_M12 << O_SHIFT) +#define O3_M12 (O_M12 << (2 * O_SHIFT)) +#define O4_M12 (O_M12 << (3 * O_SHIFT)) + #define O1_S2 O_S2 #define O2_S2 (O_S2 << O_SHIFT) @@ -644,12 +671,12 @@ OB_DEF_VAR (s390_vec_perm_dbl, s390_vperm, 0, B_DEF (s390_vperm, vec_permv16qi, 0, B_VX, 0, BT_FN_UV16QI_UV16QI_UV16QI_UV16QI) OB_DEF (s390_vec_permi, s390_vec_permi_s64, s390_vec_permi_dbl, B_VX, BT_FN_OV4SI_OV4SI_OV4SI_INT) -OB_DEF_VAR (s390_vec_permi_s64, s390_vpdi, 0, O3_U2, BT_OV_V2DI_V2DI_V2DI_INT) -OB_DEF_VAR (s390_vec_permi_b64, s390_vpdi, 0, O3_U2, BT_OV_BV2DI_BV2DI_BV2DI_INT) -OB_DEF_VAR (s390_vec_permi_u64, s390_vpdi, 0, O3_U2, BT_OV_UV2DI_UV2DI_UV2DI_INT) -OB_DEF_VAR (s390_vec_permi_dbl, s390_vpdi, 0, O3_U2, BT_OV_V2DF_V2DF_V2DF_INT) +OB_DEF_VAR (s390_vec_permi_s64, s390_vpdi, 0, O3_M5, BT_OV_V2DI_V2DI_V2DI_INT) +OB_DEF_VAR (s390_vec_permi_b64, s390_vpdi, 0, O3_M5, BT_OV_BV2DI_BV2DI_BV2DI_INT) +OB_DEF_VAR (s390_vec_permi_u64, s390_vpdi, 0, O3_M5, BT_OV_UV2DI_UV2DI_UV2DI_INT) +OB_DEF_VAR (s390_vec_permi_dbl, s390_vpdi, 0, O3_M5, BT_OV_V2DF_V2DF_V2DF_INT) -B_DEF (s390_vpdi, vec_permiv2di, 0, B_VX, O3_U2, BT_FN_UV2DI_UV2DI_UV2DI_INT) +B_DEF (s390_vpdi, vec_permiv2di, 0, B_VX, O3_M5, BT_FN_UV2DI_UV2DI_UV2DI_INT) OB_DEF (s390_vec_splat, s390_vec_splat2_s8, s390_vec_splat2_dbl,B_VX, BT_FN_OV4SI_OV4SI_UCHAR) OB_DEF_VAR (s390_vec_splat2_s8, s390_vrepb, 0, O2_U4, BT_OV_V16QI_V16QI_UCHAR) @@ -2287,8 +2314,8 @@ OB_DEF_VAR (s390_vec_test_mask_dbl, s390_vtm, 0, B_DEF (s390_vtm, vec_test_mask_intv16qi,0, B_VX, 0, BT_FN_INT_UV16QI_UV16QI) -B_DEF (s390_vec_msum_u128, vec_msumv2di, 0, B_VXE, O4_U2, BT_FN_UV16QI_UV2DI_UV2DI_UV16QI_INT) -B_DEF (s390_vmslg, vmslg, 0, B_VXE, O4_U4, BT_FN_INT128_UV2DI_UV2DI_INT128_INT) +B_DEF (s390_vec_msum_u128, vec_msumv2di, 0, B_VXE, O4_M12, BT_FN_UV16QI_UV2DI_UV2DI_UV16QI_INT) +B_DEF (s390_vmslg, vmslg, 0, B_VXE, O4_M12, BT_FN_INT128_UV2DI_UV2DI_INT128_INT) OB_DEF (s390_vec_eqv, s390_vec_eqv_b8, s390_vec_eqv_dbl_c, B_VXE, BT_FN_OV4SI_OV4SI_OV4SI) OB_DEF_VAR (s390_vec_eqv_b8, s390_vnx, 0, 0, BT_OV_BV16QI_BV16QI_BV16QI) diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index f7b1c03561e..a9c945c5ee9 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -734,15 +734,38 @@ s390_const_operand_ok (tree arg, int argnum, int op_flags, tree decl) { if (O_UIMM_P (op_flags)) { - int bitwidths[] = { 1, 2, 3, 4, 5, 8, 12, 16, 32 }; - int bitwidth = bitwidths[op_flags - O_U1]; + unsigned HOST_WIDE_INT bitwidths[] = { 1, 2, 3, 4, 5, 8, 12, 16, 32, 4, 4 }; + unsigned HOST_WIDE_INT bitmasks[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 12 }; + unsigned HOST_WIDE_INT bitwidth = bitwidths[op_flags - O_U1]; + unsigned HOST_WIDE_INT bitmask = bitmasks[op_flags - O_U1]; if (!tree_fits_uhwi_p (arg) - || tree_to_uhwi (arg) > (HOST_WIDE_INT_1U << bitwidth) - 1) + || tree_to_uhwi (arg) > (HOST_WIDE_INT_1U << bitwidth) - 1 + || (bitmask && tree_to_uhwi (arg) & ~bitmask)) { - error ("constant argument %d for builtin %qF is out of range " - "(0..%wu)", argnum, decl, - (HOST_WIDE_INT_1U << bitwidth) - 1); + if (bitmask) + { + gcc_assert (bitmask < 16); + char values[120] = ""; + + for (unsigned HOST_WIDE_INT i = 0; i <= bitmask; i++) + { + char buf[5]; + if (i & ~bitmask) + continue; + int ret = snprintf (buf, 5, HOST_WIDE_INT_PRINT_UNSIGNED, i & bitmask); + gcc_assert (ret < 5); + strcat (values, buf); + if (i < bitmask) + strcat (values, ", "); + } + error ("constant argument %d for builtin %qF is invalid (%s)", + argnum, decl, values); + } + else + error ("constant argument %d for builtin %qF is out of range (0..%wu)", + argnum, decl, (HOST_WIDE_INT_1U << bitwidth) - 1); + return false; } } diff --git a/gcc/testsuite/gcc.target/s390/zvector/imm-range-error-1.c b/gcc/testsuite/gcc.target/s390/zvector/imm-range-error-1.c new file mode 100644 index 00000000000..1fe68f57e4f --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/zvector/imm-range-error-1.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -march=z14 -mzvector" } */ + +#include + +__vector unsigned char q; +__vector unsigned short int h; +__vector unsigned int s; +__vector unsigned long long d; + +int +main () +{ + vec_msum_u128 (d, d, q, 5); /* { dg-error "constant argument 4 for builtin '__builtin_s390_vec_msum_u128' is invalid \\(0, 4, 8, 12\\)" } */ + + /* Using the resolved low-level builtins here makes the errors to be + triggered from s390_expand_builtin. Otherwise they would come + from the parser already preventing other errors from showing + up. */ + __builtin_s390_vrepb (q, 17); /* { dg-error "constant argument 2 for builtin '__builtin_s390_vrepb' is out of range \\(0..15\\)" } */ + __builtin_s390_vreph (h, 8); /* { dg-error "constant argument 2 for builtin '__builtin_s390_vreph' is out of range \\(0..7\\)" } */ + __builtin_s390_vrepf (s, 4); /* { dg-error "constant argument 2 for builtin '__builtin_s390_vrepf' is out of range \\(0..3\\)" } */ + __builtin_s390_vrepg (d, 2); /* { dg-error "constant argument 2 for builtin '__builtin_s390_vrepg' is out of range \\(0..1\\)" } */ + + __builtin_s390_vpdi (d, d, 2); /* { dg-error "constant argument 3 for builtin '__builtin_s390_vpdi' is invalid \\(0, 1, 4, 5\\)" } */ +} diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec_msum_u128-1.c b/gcc/testsuite/gcc.target/s390/zvector/vec_msum_u128-1.c new file mode 100644 index 00000000000..2f5fbcacafe --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/zvector/vec_msum_u128-1.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ +/* { dg-require-effective-target s390_vxe } */ +/* { dg-options "-O3 -mzarch -march=z14 -mzvector --save-temps" } */ + +#include + +typedef vector unsigned char uv16qi; +typedef vector unsigned long long uv2di; + +uv2di a = (uv2di){ 12, 42 }; +uv2di b = (uv2di){ 54, 120 }; +uv2di c = (uv2di){ 0, 200 }; + +int +main () +{ + uv2di result; + + result = (uv2di)vec_msum_u128 (a, b, (uv16qi)c, 0); + + if (result[1] != a[0] * b[0] + a[1] * b[1] + c[1]) + __builtin_abort(); + + result = (uv2di)vec_msum_u128 (a, b, (uv16qi)c, 4); + + if (result[1] != a[0] * b[0] + a[1] * b[1] * 2 + c[1]) + __builtin_abort(); + + result = (uv2di)vec_msum_u128 (a, b, (uv16qi)c, 8); + + if (result[1] != a[0] * b[0] * 2 + a[1] * b[1] + c[1]) + __builtin_abort(); + + result = (uv2di)vec_msum_u128 (a, b, (uv16qi)c, 12); + + if (result[1] != a[0] * b[0] * 2 + a[1] * b[1] * 2 + c[1]) + __builtin_abort(); + + return 0; +} + +/* { dg-final { scan-assembler-times "vmslg\t.*0" 1 } } */ +/* { dg-final { scan-assembler-times "vmslg\t.*4" 1 } } */ +/* { dg-final { scan-assembler-times "vmslg\t.*8" 1 } } */ +/* { dg-final { scan-assembler-times "vmslg\t.*12" 1 } } */