This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RE: [PATCH] MIPS MSA: Fix ICE when using out-of-range values to intrinsics
- From: Robert Suchanek <Robert dot Suchanek at imgtec dot com>
- To: Matthew Fortune <Matthew dot Fortune at imgtec dot com>, "Catherine_Moore at mentor dot com" <Catherine_Moore at mentor dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 5 Dec 2016 09:02:36 +0000
- Subject: RE: [PATCH] MIPS MSA: Fix ICE when using out-of-range values to intrinsics
- Authentication-results: sourceware.org; auth=none
- References: <B5E67142681B53468FAF6B7C31356562519C72FF@HHMAIL01.hh.imgtec.org> <6D39441BF12EF246A7ABCE6654B0235380ADFFC6@HHMAIL01.hh.imgtec.org>
Hi,
> Robert Suchanek <Robert.Suchanek@imgtec.com> writes:
> > The patch primarily fixes an ICE with out-of-range values to the
> > __builtin_msa_insve* intrinsics.
> >
> > The compiler segfaults in mips_legitimize_const_move () as it tries to
> > split symbol that has NULL_RTX value and gets here because the patterns
> > reject the operand and a new move for the constant is being introduced.
> >
> > The INSVE.DF instruction cannot use register based access to the
> > element, thus, the attempt is obviously wrong and I think that we should
> > be catching this invalid input early.
>
> Agreed, catching problems with arguments to builtins early sounds better
> to me generally.
>
> > I took the opportunity to check all the builtins with literal integers
> > except those that use full range of a type as truncation warnings are
> > generated. The diagnostics is slightly more meaningful and the valid
> > ranges align with the documentation.
>
> Some comments on the implementation below. Just some further cleanup.
>
> > gcc/
> > * config/mips/mips.c (mips_expand_builtin_insn): Check input ranges
> > of literal integer arguments.
> >
> > gcc/testsuite/
> >
> > * gcc.target/mips/msa-builtins-err.c: New test.
> > ---
> > gcc/config/mips/mips.c | 56 +++++-
> > gcc/testsuite/gcc.target/mips/msa-builtins-err.c | 241
> > +++++++++++++++++++++++
> > 2 files changed, 289 insertions(+), 8 deletions(-) create mode 100644
> > gcc/testsuite/gcc.target/mips/msa-builtins-err.c
> >
> > diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index
> > 44cdeb7..ddb64fb 100644
> > --- a/gcc/config/mips/mips.c
> > +++ b/gcc/config/mips/mips.c
> > @@ -16542,6 +16542,7 @@ mips_expand_builtin_insn (enum insn_code icode,
> > unsigned int nops,
> > struct expand_operand *ops, bool has_target_p) {
> > machine_mode imode;
> > + HOST_WIDE_INT arglo, arghi, argno = -1;
>
> arglo/arghi should really be initialised to zero as the control flow is
> complex that ensures they are set when argno != -1. Perhaps rangelo
> and rangehi to distinguish from the operand numbers.
>
> argno (perhaps error_opno) can be an int.
>
> >
> > switch (icode)
> > {
> > @@ -16570,11 +16571,18 @@ mips_expand_builtin_insn (enum insn_code
> > icode, unsigned int nops,
> > case CODE_FOR_msa_subvi_w:
> > case CODE_FOR_msa_subvi_d:
> > gcc_assert (has_target_p && nops == 3);
> > + arglo = 0;
> > + arghi = 31;
> > /* We only generate a vector of constants iff the second argument
> > is an immediate. We also validate the range of the immediate. */
> > - if (!CONST_INT_P (ops[2].value)
> > - || !IN_RANGE (INTVAL (ops[2].value), 0, 31))
> > + if (!CONST_INT_P (ops[2].value))
> > break;
> > + if (CONST_INT_P (ops[2].value)
> > + && !IN_RANGE (INTVAL (ops[2].value), arglo, arghi))
> > + {
> > + argno = 2;
> > + break;
> > + }
>
> The error should really be shown if a !CONST_INT_P is found too. I.e.
As discussed offline, unfortunately we fake some of the built-ins by creating
aliases and a single pattern may handle a built-in with an immediate or register
operand. I applied suggestions with some modifications. It's still not ideal
but slightly easier to understand the code and flow.
>
> if (!CONST_INT_P (ops[2].value)
> || !IN_RANGE (INTVAL (ops[2].value), 0, 31))
> {
> error_opno = 2;
> break;
> }
>
> Similarly throughout.
>
> > ops[2].mode = ops[0].mode;
> > ops[2].value = mips_gen_const_int_vector (ops[2].mode,
> > INTVAL (ops[2].value));
> > @@ -16601,11 +16609,18 @@ mips_expand_builtin_insn (enum insn_code
> > icode, unsigned int nops,
> > case CODE_FOR_msa_mini_s_w:
> > case CODE_FOR_msa_mini_s_d:
> > gcc_assert (has_target_p && nops == 3);
> > + arglo = -16;
> > + arghi = 15;
> > /* We only generate a vector of constants iff the second argument
> > is an immediate. We also validate the range of the immediate. */
> > - if (!CONST_INT_P (ops[2].value)
> > - || !IN_RANGE (INTVAL (ops[2].value), -16, 15))
> > + if (!CONST_INT_P (ops[2].value))
> > break;
> > + if (CONST_INT_P (ops[2].value)
> > + && !IN_RANGE (INTVAL (ops[2].value), arglo, arghi))
> > + {
> > + argno = 2;
> > + break;
> > + }
> > ops[2].mode = ops[0].mode;
> > ops[2].value = mips_gen_const_int_vector (ops[2].mode,
> > INTVAL (ops[2].value));
> > @@ -16688,10 +16703,16 @@ mips_expand_builtin_insn (enum insn_code
> > icode, unsigned int nops,
> > case CODE_FOR_msa_srli_w:
> > case CODE_FOR_msa_srli_d:
> > gcc_assert (has_target_p && nops == 3);
> > - if (!CONST_INT_P (ops[2].value)
> > - || !IN_RANGE (INTVAL (ops[2].value), 0,
> > - GET_MODE_UNIT_PRECISION (ops[0].mode) - 1))
> > + if (!CONST_INT_P (ops[2].value))
> > break;
> > + arglo = 0;
> > + arghi = GET_MODE_UNIT_BITSIZE (ops[0].mode) - 1;
> > + if (CONST_INT_P (ops[2].value)
> > + && !IN_RANGE (INTVAL (ops[2].value), arglo, arghi))
> > + {
> > + argno = 2;
> > + break;
> > + }
> > ops[2].mode = ops[0].mode;
> > ops[2].value = mips_gen_const_int_vector (ops[2].mode,
> > INTVAL (ops[2].value));
> > @@ -16710,6 +16731,14 @@ mips_expand_builtin_insn (enum insn_code icode,
> > unsigned int nops,
> > imode = GET_MODE_INNER (ops[0].mode);
> > ops[1].value = lowpart_subreg (imode, ops[1].value, ops[1].mode);
> > ops[1].mode = imode;
> > + arglo = 0;
> > + arghi = GET_MODE_NUNITS (ops[0].mode) - 1;
> > + if (!CONST_INT_P (ops[3].value)
> > + || !IN_RANGE (INTVAL (ops[3].value), arglo, arghi))
> > + {
> > + argno = 2;
> > + break;
> > + }
> > ops[3].value = GEN_INT (1 << INTVAL (ops[3].value));
> > break;
> >
> > @@ -16722,6 +16751,14 @@ mips_expand_builtin_insn (enum insn_code icode,
> > unsigned int nops,
> > gcc_assert (has_target_p && nops == 4);
> > std::swap (ops[1], ops[2]);
> > std::swap (ops[1], ops[3]);
> > + arglo = 0;
> > + arghi = GET_MODE_NUNITS (ops[0].mode) - 1;
> > + if (!CONST_INT_P (ops[3].value)
> > + || !IN_RANGE (INTVAL (ops[3].value), arglo, arghi))
> > + {
> > + argno = 2;
> > + break;
> > + }
> > ops[3].value = GEN_INT (1 << INTVAL (ops[3].value));
> > break;
> >
> > @@ -16746,7 +16783,10 @@ mips_expand_builtin_insn (enum insn_code icode,
> > unsigned int nops,
> > break;
> > }
> >
> > - if (!maybe_expand_insn (icode, nops, ops))
> > + if (argno != -1)
> > + error ("%s argument to the built-in must be in range %ld to %ld",
> > + argno == 2 ? "second" : "third", arglo, arghi);
>
> I'd reword this to avoid the 2/3 etc and mention the need for a constant
> given it will appear when a variable is used now as well.
>
> error ("argument %d to the built-in must be a constant in range %ld to %ld",
> error_opno, rangelo, rangehi);
>
> Given we go to the effort of faking a return when the instruction fails
> to expand then we should do the same here:
>
> return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
Added.
The revised patch attached below.
Regards,
Robert
gcc/
* config/mips/mips.c (mips_expand_builtin_insn): Check input ranges
of literal integer arguments.
gcc/testsuite/
* gcc.target/mips/msa-builtins-err.c: New test.
---
gcc/config/mips/mips.c | 83 +++++---
gcc/testsuite/gcc.target/mips/msa-builtins-err.c | 241 +++++++++++++++++++++++
2 files changed, 302 insertions(+), 22 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/mips/msa-builtins-err.c
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 0e83cb4..c7eb2a8 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -16570,6 +16570,7 @@ mips_expand_builtin_insn (enum insn_code icode, unsigned int nops,
struct expand_operand *ops, bool has_target_p)
{
machine_mode imode;
+ int rangelo = 0, rangehi = 0, error_opno = 0;
switch (icode)
{
@@ -16600,12 +16601,19 @@ mips_expand_builtin_insn (enum insn_code icode, unsigned int nops,
gcc_assert (has_target_p && nops == 3);
/* We only generate a vector of constants iff the second argument
is an immediate. We also validate the range of the immediate. */
- if (!CONST_INT_P (ops[2].value)
- || !IN_RANGE (INTVAL (ops[2].value), 0, 31))
- break;
- ops[2].mode = ops[0].mode;
- ops[2].value = mips_gen_const_int_vector (ops[2].mode,
- INTVAL (ops[2].value));
+ if (CONST_INT_P (ops[2].value))
+ {
+ rangelo = 0;
+ rangehi = 31;
+ if (IN_RANGE (INTVAL (ops[2].value), rangelo, rangehi))
+ {
+ ops[2].mode = ops[0].mode;
+ ops[2].value = mips_gen_const_int_vector (ops[2].mode,
+ INTVAL (ops[2].value));
+ }
+ else
+ error_opno = 2;
+ }
break;
case CODE_FOR_msa_ceqi_b:
@@ -16631,12 +16639,19 @@ mips_expand_builtin_insn (enum insn_code icode, unsigned int nops,
gcc_assert (has_target_p && nops == 3);
/* We only generate a vector of constants iff the second argument
is an immediate. We also validate the range of the immediate. */
- if (!CONST_INT_P (ops[2].value)
- || !IN_RANGE (INTVAL (ops[2].value), -16, 15))
- break;
- ops[2].mode = ops[0].mode;
- ops[2].value = mips_gen_const_int_vector (ops[2].mode,
- INTVAL (ops[2].value));
+ if (CONST_INT_P (ops[2].value))
+ {
+ rangelo = -16;
+ rangehi = 15;
+ if (IN_RANGE (INTVAL (ops[2].value), rangelo, rangehi))
+ {
+ ops[2].mode = ops[0].mode;
+ ops[2].value = mips_gen_const_int_vector (ops[2].mode,
+ INTVAL (ops[2].value));
+ }
+ else
+ error_opno = 2;
+ }
break;
case CODE_FOR_msa_andi_b:
@@ -16716,13 +16731,19 @@ mips_expand_builtin_insn (enum insn_code icode, unsigned int nops,
case CODE_FOR_msa_srli_w:
case CODE_FOR_msa_srli_d:
gcc_assert (has_target_p && nops == 3);
- if (!CONST_INT_P (ops[2].value)
- || !IN_RANGE (INTVAL (ops[2].value), 0,
- GET_MODE_UNIT_PRECISION (ops[0].mode) - 1))
- break;
- ops[2].mode = ops[0].mode;
- ops[2].value = mips_gen_const_int_vector (ops[2].mode,
- INTVAL (ops[2].value));
+ if (CONST_INT_P (ops[2].value))
+ {
+ rangelo = 0;
+ rangehi = GET_MODE_UNIT_BITSIZE (ops[0].mode) - 1;
+ if (IN_RANGE (INTVAL (ops[2].value), rangelo, rangehi))
+ {
+ ops[2].mode = ops[0].mode;
+ ops[2].value = mips_gen_const_int_vector (ops[2].mode,
+ INTVAL (ops[2].value));
+ }
+ else
+ error_opno = 2;
+ }
break;
case CODE_FOR_msa_insert_b:
@@ -16738,7 +16759,13 @@ mips_expand_builtin_insn (enum insn_code icode, unsigned int nops,
imode = GET_MODE_INNER (ops[0].mode);
ops[1].value = lowpart_subreg (imode, ops[1].value, ops[1].mode);
ops[1].mode = imode;
- ops[3].value = GEN_INT (1 << INTVAL (ops[3].value));
+ rangelo = 0;
+ rangehi = GET_MODE_NUNITS (ops[0].mode) - 1;
+ if (CONST_INT_P (ops[3].value)
+ && IN_RANGE (INTVAL (ops[3].value), rangelo, rangehi))
+ ops[3].value = GEN_INT (1 << INTVAL (ops[3].value));
+ else
+ error_opno = 2;
break;
case CODE_FOR_msa_insve_b:
@@ -16750,7 +16777,13 @@ mips_expand_builtin_insn (enum insn_code icode, unsigned int nops,
gcc_assert (has_target_p && nops == 4);
std::swap (ops[1], ops[2]);
std::swap (ops[1], ops[3]);
- ops[3].value = GEN_INT (1 << INTVAL (ops[3].value));
+ rangelo = 0;
+ rangehi = GET_MODE_NUNITS (ops[0].mode) - 1;
+ if (CONST_INT_P (ops[3].value)
+ && IN_RANGE (INTVAL (ops[3].value), rangelo, rangehi))
+ ops[3].value = GEN_INT (1 << INTVAL (ops[3].value));
+ else
+ error_opno = 2;
break;
case CODE_FOR_msa_shf_b:
@@ -16774,7 +16807,13 @@ mips_expand_builtin_insn (enum insn_code icode, unsigned int nops,
break;
}
- if (!maybe_expand_insn (icode, nops, ops))
+ if (error_opno != 0)
+ {
+ error ("argument %d to the built-in must be a constant"
+ " in range %d to %d", error_opno, rangelo, rangehi);
+ return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
+ }
+ else if (!maybe_expand_insn (icode, nops, ops))
{
error ("invalid argument to built-in function");
return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
diff --git a/gcc/testsuite/gcc.target/mips/msa-builtins-err.c b/gcc/testsuite/gcc.target/mips/msa-builtins-err.c
new file mode 100644
index 0000000..041b7f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/msa-builtins-err.c
@@ -0,0 +1,241 @@
+/* Test builtins for MIPS MSA ASE instructions */
+/* { dg-do compile } */
+/* { dg-options "-mfp64 -mhard-float -mmsa" } */
+
+#include <msa.h>
+
+v16i8 v16i8_x;
+v16u8 v16u8_x;
+v8i16 v8i16_x;
+v8u16 v8u16_x;
+v4i32 v4i32_x;
+v4u32 v4u32_x;
+v2i64 v2i64_x;
+v2u64 v2u64_x;
+
+volatile v16i8 v16i8_r;
+volatile v16u8 v16u8_r;
+volatile v8i16 v8i16_r;
+volatile v8u16 v8u16_r;
+volatile v4i32 v4i32_r;
+volatile v4u32 v4u32_r;
+volatile v2i64 v2i64_r;
+volatile v2u64 v2u64_r;
+
+/* MSA builtins with literal range of 0 to 31. */
+
+void
+msa_add ()
+{
+ v16i8_r = __builtin_msa_addvi_b (v16i8_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v16i8_r = __builtin_msa_addvi_b (v16i8_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8i16_r = __builtin_msa_addvi_h (v8i16_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8i16_r = __builtin_msa_addvi_h (v8i16_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_addvi_w (v4i32_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_addvi_w (v4i32_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_addvi_d (v2i64_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_addvi_d (v2i64_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+}
+
+void
+msa_sub ()
+{
+ v16i8_r = __builtin_msa_subvi_b (v16i8_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v16i8_r = __builtin_msa_subvi_b (v16i8_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8i16_r = __builtin_msa_subvi_h (v8i16_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8i16_r = __builtin_msa_subvi_h (v8i16_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_subvi_w (v4i32_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_subvi_w (v4i32_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_subvi_d (v2i64_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_subvi_d (v2i64_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+}
+
+void
+msa_mini_u ()
+{
+ v16u8_r = __builtin_msa_mini_u_b (v16u8_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v16u8_r = __builtin_msa_mini_u_b (v16u8_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8u16_r = __builtin_msa_mini_u_h (v8u16_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8u16_r = __builtin_msa_mini_u_h (v8u16_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4u32_r = __builtin_msa_mini_u_w (v4u32_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4u32_r = __builtin_msa_mini_u_w (v4u32_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2u64_r = __builtin_msa_mini_u_d (v2u64_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2u64_r = __builtin_msa_mini_u_d (v2u64_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+}
+
+void
+msa_maxi_u ()
+{
+ v16u8_r = __builtin_msa_maxi_u_b (v16u8_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v16u8_r = __builtin_msa_maxi_u_b (v16u8_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8u16_r = __builtin_msa_maxi_u_h (v8u16_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8u16_r = __builtin_msa_maxi_u_h (v8u16_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4u32_r = __builtin_msa_maxi_u_w (v4u32_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4u32_r = __builtin_msa_maxi_u_w (v4u32_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2u64_r = __builtin_msa_maxi_u_d (v2u64_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2u64_r = __builtin_msa_maxi_u_d (v2u64_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+}
+
+void
+msa_clti_u ()
+{
+ v16i8_r = __builtin_msa_clti_u_b (v16u8_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v16i8_r = __builtin_msa_clti_u_b (v16u8_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8i16_r = __builtin_msa_clti_u_h (v8u16_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8i16_r = __builtin_msa_clti_u_h (v8u16_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_clti_u_w (v4u32_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_clti_u_w (v4u32_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_clti_u_d (v2u64_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_clti_u_d (v2u64_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+}
+
+void
+msa_clei_u ()
+{
+ v16i8_r = __builtin_msa_clei_u_b (v16u8_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v16i8_r = __builtin_msa_clei_u_b (v16u8_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8i16_r = __builtin_msa_clei_u_h (v8u16_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v8i16_r = __builtin_msa_clei_u_h (v8u16_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_clei_u_w (v4u32_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_clei_u_w (v4u32_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_clei_u_d (v2u64_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_clei_u_d (v2u64_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+}
+
+/* MSA builtins with literal range of -16 to 15. */
+
+void
+msa_mini_s ()
+{
+ v16i8_r = __builtin_msa_mini_s_b (v16i8_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v16i8_r = __builtin_msa_mini_s_b (v16i8_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v8i16_r = __builtin_msa_mini_s_h (v8i16_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v8i16_r = __builtin_msa_mini_s_h (v8i16_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v4i32_r = __builtin_msa_mini_s_w (v4i32_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v4i32_r = __builtin_msa_mini_s_w (v4i32_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v2i64_r = __builtin_msa_mini_s_d (v2i64_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v2i64_r = __builtin_msa_mini_s_d (v2i64_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+}
+
+void
+msa_maxi_s ()
+{
+ v16i8_r = __builtin_msa_maxi_s_b (v16i8_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v16i8_r = __builtin_msa_maxi_s_b (v16i8_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v8i16_r = __builtin_msa_maxi_s_h (v8i16_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v8i16_r = __builtin_msa_maxi_s_h (v8i16_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v4i32_r = __builtin_msa_maxi_s_w (v4i32_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v4i32_r = __builtin_msa_maxi_s_w (v4i32_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v2i64_r = __builtin_msa_maxi_s_d (v2i64_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v2i64_r = __builtin_msa_maxi_s_d (v2i64_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+}
+
+void
+msa_ceqi ()
+{
+ v16i8_r = __builtin_msa_ceqi_b (v16i8_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v16i8_r = __builtin_msa_ceqi_b (v16i8_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v8i16_r = __builtin_msa_ceqi_h (v8i16_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v8i16_r = __builtin_msa_ceqi_h (v8i16_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v4i32_r = __builtin_msa_ceqi_w (v4i32_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v4i32_r = __builtin_msa_ceqi_w (v4i32_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v2i64_r = __builtin_msa_ceqi_d (v2i64_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v2i64_r = __builtin_msa_ceqi_d (v2i64_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+}
+
+void
+msa_clti_s ()
+{
+ v16i8_r = __builtin_msa_clti_s_b (v16i8_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v16i8_r = __builtin_msa_clti_s_b (v16i8_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v8i16_r = __builtin_msa_clti_s_h (v8i16_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v8i16_r = __builtin_msa_clti_s_h (v8i16_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v4i32_r = __builtin_msa_clti_s_w (v4i32_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v4i32_r = __builtin_msa_clti_s_w (v4i32_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v2i64_r = __builtin_msa_clti_s_d (v2i64_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v2i64_r = __builtin_msa_clti_s_d (v2i64_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+}
+
+void
+msa_clei_s ()
+{
+ v16i8_r = __builtin_msa_clei_s_b (v16i8_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v16i8_r = __builtin_msa_clei_s_b (v16i8_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v8i16_r = __builtin_msa_clei_s_h (v8i16_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v8i16_r = __builtin_msa_clei_s_h (v8i16_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v4i32_r = __builtin_msa_clei_s_w (v4i32_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v4i32_r = __builtin_msa_clei_s_w (v4i32_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+ v2i64_r = __builtin_msa_clei_s_d (v2i64_x, -17); /* { dg-error "must be a constant in range -16 to 15" } */
+ v2i64_r = __builtin_msa_clei_s_d (v2i64_x, 16); /* { dg-error "must be a constant in range -16 to 15" } */
+}
+
+/* MSA builtins with literal range of 0 to 7/15/31/63 for
+ byte/halfwords/words/doublewords elements, respectively. */
+
+void
+msa_slli ()
+{
+ v16i8_r = __builtin_msa_slli_b (v16i8_x, -1); /* { dg-error "must be a constant in range 0 to 7" } */
+ v16i8_r = __builtin_msa_slli_b (v16i8_x, 8); /* { dg-error "must be a constant in range 0 to 7" } */
+ v8i16_r = __builtin_msa_slli_h (v8i16_x, -1); /* { dg-error "must be a constant in range 0 to 15" } */
+ v8i16_r = __builtin_msa_slli_h (v8i16_x, 16); /* { dg-error "must be a constant in range 0 to 15" } */
+ v4i32_r = __builtin_msa_slli_w (v4i32_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_slli_w (v4i32_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_slli_d (v2i64_x, -1); /* { dg-error "must be a constant in range 0 to 63" } */
+ v2i64_r = __builtin_msa_slli_d (v2i64_x, 64); /* { dg-error "must be a constant in range 0 to 63" } */
+}
+
+void
+msa_srai ()
+{
+ v16i8_r = __builtin_msa_srai_b (v16i8_x, -1); /* { dg-error "must be a constant in range 0 to 7" } */
+ v16i8_r = __builtin_msa_srai_b (v16i8_x, 8); /* { dg-error "must be a constant in range 0 to 7" } */
+ v8i16_r = __builtin_msa_srai_h (v8i16_x, -1); /* { dg-error "must be a constant in range 0 to 15" } */
+ v8i16_r = __builtin_msa_srai_h (v8i16_x, 16); /* { dg-error "must be a constant in range 0 to 15" } */
+ v4i32_r = __builtin_msa_srai_w (v4i32_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_srai_w (v4i32_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_srai_d (v2i64_x, -1); /* { dg-error "must be a constant in range 0 to 63" } */
+ v2i64_r = __builtin_msa_srai_d (v2i64_x, 64); /* { dg-error "must be a constant in range 0 to 63" } */
+}
+
+void
+msa_srli ()
+{
+ v16i8_r = __builtin_msa_srli_b (v16i8_x, -1); /* { dg-error "must be a constant in range 0 to 7" } */
+ v16i8_r = __builtin_msa_srli_b (v16i8_x, 8); /* { dg-error "must be a constant in range 0 to 7" } */
+ v8i16_r = __builtin_msa_srli_h (v8i16_x, -1); /* { dg-error "must be a constant in range 0 to 15" } */
+ v8i16_r = __builtin_msa_srli_h (v8i16_x, 16); /* { dg-error "must be a constant in range 0 to 15" } */
+ v4i32_r = __builtin_msa_srli_w (v4i32_x, -1); /* { dg-error "must be a constant in range 0 to 31" } */
+ v4i32_r = __builtin_msa_srli_w (v4i32_x, 32); /* { dg-error "must be a constant in range 0 to 31" } */
+ v2i64_r = __builtin_msa_srli_d (v2i64_x, -1); /* { dg-error "must be a constant in range 0 to 63" } */
+ v2i64_r = __builtin_msa_srli_d (v2i64_x, 64); /* { dg-error "must be a constant in range 0 to 63" } */
+}
+
+/* MSA builtins with literal range of 0 to 15/7/3/1 for
+ byte/halfwords/words/doublewords elements, respectively. */
+
+void
+msa_insert (int a)
+{
+ v16i8_r = __builtin_msa_insert_b (v16i8_x, -1, a); /* { dg-error "must be a constant in range 0 to 15" } */
+ v16i8_r = __builtin_msa_insert_b (v16i8_x, 16, a); /* { dg-error "must be a constant in range 0 to 15" } */
+ v8i16_r = __builtin_msa_insert_h (v8i16_x, -1, a); /* { dg-error "must be a constant in range 0 to 7" } */
+ v8i16_r = __builtin_msa_insert_h (v8i16_x, 8, a); /* { dg-error "must be a constant in range 0 to 7" } */
+ v4i32_r = __builtin_msa_insert_w (v4i32_x, -1, a); /* { dg-error "must be a constant in range 0 to 3" } */
+ v4i32_r = __builtin_msa_insert_w (v4i32_x, 4, a); /* { dg-error "must be a constant in range 0 to 3" } */
+ v2i64_r = __builtin_msa_insert_d (v2i64_x, -1, a); /* { dg-error "must be a constant in range 0 to 1" } */
+ v2i64_r = __builtin_msa_insert_d (v2i64_x, 2, a); /* { dg-error "must be a constant in range 0 to 1" } */
+}
+
+void
+msa_insve ()
+{
+ v16i8_r = __builtin_msa_insve_b (v16i8_x, -1, v16i8_x); /* { dg-error "must be a constant in range 0 to 15" } */
+ v16i8_r = __builtin_msa_insve_b (v16i8_x, 16, v16i8_x); /* { dg-error "must be a constant in range 0 to 15" } */
+ v8i16_r = __builtin_msa_insve_h (v8i16_x, -1, v8i16_x); /* { dg-error "must be a constant in range 0 to 7" } */
+ v8i16_r = __builtin_msa_insve_h (v8i16_x, 8, v8i16_x); /* { dg-error "must be a constant in range 0 to 7" } */
+ v4i32_r = __builtin_msa_insve_w (v4i32_x, -1, v4i32_x); /* { dg-error "must be a constant in range 0 to 3" } */
+ v4i32_r = __builtin_msa_insve_w (v4i32_x, 4, v4i32_x); /* { dg-error "must be a constant in range 0 to 3" } */
+ v2i64_r = __builtin_msa_insve_d (v2i64_x, -1, v2i64_x); /* { dg-error "must be a constant in range 0 to 1" } */
+ v2i64_r = __builtin_msa_insve_d (v2i64_x, 2, v2i64_x); /* { dg-error "must be a constant in range 0 to 1" } */
+}
--
2.9.3