From patchwork Mon Dec 5 09:02:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Suchanek X-Patchwork-Id: 702637 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tXJhL1ZFJz9t0v for ; Mon, 5 Dec 2016 20:03:23 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="JYc/ghJD"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:references:in-reply-to :content-type:content-transfer-encoding:mime-version; q=dns; s= default; b=DiWvSd6E2ypN/9xa7XZuUoS5sT9Mw3M8MIZKgSXlw2TDZju7G3PoQ kZb0S0Wkm29zk2jq2Xr5XdyyA3Wmiyr/lICWqpIMhHBA1pTmvMU+W4n7Nr45CeiG X1m9vTKVNEWe90ndHAW6RE+KFDgHSyAeMfxqQkKOKk2hliHaYmaipE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:references:in-reply-to :content-type:content-transfer-encoding:mime-version; s=default; bh=J4TJOZ2Z3sSJwJdl7kk4dm+qApE=; b=JYc/ghJD43uqXo4IerL3cOmPO1Xo Oi1hqExHQKnlABPjJBpK41OKDK3rhBbWLN5PBjzTw+SufiKrv1WfS0s9jYhKXEW5 EnOQ/DjKKAA6AdvGd2/KZbCMJ4bXBEqBJHeeozqWNw4TPVvwqvuktwYy/jCtA6R6 LaX4ggZEGfNAe9I= Received: (qmail 2019 invoked by alias); 5 Dec 2016 09:03:14 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 1096 invoked by uid 89); 5 Dec 2016 09:03:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=Similarly, robert, HX-Envelope-From:sk:Robert., Robert X-HELO: mailapp01.imgtec.com Received: from Unknown (HELO mailapp01.imgtec.com) (195.59.15.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 05 Dec 2016 09:03:02 +0000 Received: from HHMAIL01.hh.imgtec.org (unknown [10.100.10.19]) by Forcepoint Email with ESMTPS id AD834183958BC; Mon, 5 Dec 2016 09:02:34 +0000 (GMT) Received: from HHMAIL-X.hh.imgtec.org (10.100.10.113) by HHMAIL01.hh.imgtec.org (10.100.10.19) with Microsoft SMTP Server (TLS) id 14.3.294.0; Mon, 5 Dec 2016 09:02:36 +0000 Received: from HHMAIL01.hh.imgtec.org ([fe80::710b:f219:72bc:e0b3]) by HHMAIL-X.hh.imgtec.org ([fe80::3509:b0ce:371:2b%18]) with mapi id 14.03.0294.000; Mon, 5 Dec 2016 09:02:36 +0000 From: Robert Suchanek To: Matthew Fortune , "Catherine_Moore@mentor.com" CC: "gcc-patches@gcc.gnu.org" Subject: RE: [PATCH] MIPS MSA: Fix ICE when using out-of-range values to intrinsics Date: Mon, 5 Dec 2016 09:02:36 +0000 Message-ID: References: <6D39441BF12EF246A7ABCE6654B0235380ADFFC6@HHMAIL01.hh.imgtec.org> In-Reply-To: <6D39441BF12EF246A7ABCE6654B0235380ADFFC6@HHMAIL01.hh.imgtec.org> MIME-Version: 1.0 X-IsSubscribed: yes Hi, > Robert Suchanek 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 + +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" } */ +}