public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-8177] IBM Z: Fix error checking for immediate builtin operands
@ 2021-04-14 14:16 Andreas Krebbel
  0 siblings, 0 replies; only message in thread
From: Andreas Krebbel @ 2021-04-14 14:16 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:3191c1f4488d1f7563b563d7ae2a102a26f16d82

commit r11-8177-g3191c1f4488d1f7563b563d7ae2a102a26f16d82
Author: Andreas Krebbel <krebbel@linux.ibm.com>
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 <vecintrin.h>
+
+__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 <vecintrin.h>
+
+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 } } */


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-04-14 14:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-14 14:16 [gcc r11-8177] IBM Z: Fix error checking for immediate builtin operands Andreas Krebbel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).