This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFC] VEC_SELECT sanity checking in genrecog
- From: Richard Biener <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Segher Boessenkool <segher at kernel dot crashing dot org>, Eric Botcazou <ebotcazou at adacore dot com>, Bernd Schmidt <bschmidt at redhat dot com>, Jeff Law <law at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Mon, 6 Mar 2017 12:53:38 +0100 (CET)
- Subject: Re: [RFC] VEC_SELECT sanity checking in genrecog
- Authentication-results: sourceware.org; auth=none
- References: <20170303162827.GD1849@tucnak>
On Fri, 3 Mar 2017, Jakub Jelinek wrote:
> Hi!
>
> When working on PR79812 which was caused by bugs in x86 define_insn
> (used vec_select with parallel as last operand with incorrect number of
> operands), I wrote following sanity checking.
>
> The thing is that e.g. simplify-rtx.c already has such assertions:
> if (!VECTOR_MODE_P (mode))
> {
> gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
> gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
> gcc_assert (GET_CODE (trueop1) == PARALLEL);
> gcc_assert (XVECLEN (trueop1, 0) == 1);
> gcc_assert (CONST_INT_P (XVECEXP (trueop1, 0, 0)));
> ...
> else
> {
> gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
> gcc_assert (GET_MODE_INNER (mode)
> == GET_MODE_INNER (GET_MODE (trueop0)));
> gcc_assert (GET_CODE (trueop1) == PARALLEL);
>
> if (GET_CODE (trueop0) == CONST_VECTOR)
> {
> int elt_size = GET_MODE_UNIT_SIZE (mode);
> unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
> rtvec v = rtvec_alloc (n_elts);
> unsigned int i;
>
> gcc_assert (XVECLEN (trueop1, 0) == (int) n_elts);
> ...
> and documentation says:
> @findex vec_select
> @item (vec_select:@var{m} @var{vec1} @var{selection})
> This describes an operation that selects parts of a vector. @var{vec1} is
> the source vector, and @var{selection} is a @code{parallel} that contains a
> @code{const_int} for each of the subparts of the result vector, giving the
> number of the source subpart that should be stored into it.
> The result mode @var{m} is either the submode for a single element of
> @var{vec1} (if only one subpart is selected), or another vector mode
> with that element submode (if multiple subparts are selected).
>
> Unfortunately, even after fixing 2 x86 bugs with that, I'm seeing tons
> of issues on other targets (many others are ok though) below. So, is the
> verification the right thing and are all these md bugs that should be fixed
> (and then the verification added)? If not, I'd be afraid if people are
> unlucky and combiner constant propagates something or some other pass,
> we can ICE on those in simplify-rtx.c. E.g. in vsx.md the thing is that
> the pattern uses an iterator with 2 V2?? modes in it and then V1TI mode,
> and uses exactly two elements in paralle, which doesn't make any sense
> for V1TI.
>
> ../../gcc/config/rs6000/vsx.md:2063:1: vec_select parallel with 2 elements, expected 1
> ../../gcc/config/rs6000/vsx.md:2112:1: vec_select parallel with 2 elements, expected 1
> ../../gcc/config/rs6000/vsx.md:2161:1: vec_select parallel with 2 elements, expected 1
>
> ../../gcc/config/aarch64/aarch64-simd.md:79:1: DImode of first vec_select operand is not a vector mode
> ../../gcc/config/aarch64/aarch64-simd.md:79:1: DFmode of first vec_select operand is not a vector mode
> ../../gcc/config/aarch64/aarch64-simd.md:588:1: DImode of first vec_select operand is not a vector mode
> ../../gcc/config/aarch64/aarch64-simd.md:588:1: DFmode of first vec_select operand is not a vector mode
> ../../gcc/config/aarch64/aarch64-simd.md:3192:1: DFmode of first vec_select operand is not a vector mode
>
> ../../gcc/config/arm/neon.md:1338:1: element mode mismatch between vec_select HImode and its operand QImode
> ../../gcc/config/arm/neon.md:1338:1: element mode mismatch between vec_select SImode and its operand QImode
> ../../gcc/config/arm/neon.md:1338:1: element mode mismatch between vec_select QImode and its operand HImode
> ../../gcc/config/arm/neon.md:1338:1: element mode mismatch between vec_select SImode and its operand HImode
> ../../gcc/config/arm/neon.md:1338:1: element mode mismatch between vec_select QImode and its operand SImode
> ../../gcc/config/arm/neon.md:1338:1: element mode mismatch between vec_select HImode and its operand SImode
> ../../gcc/config/arm/neon.md:1353:1: element mode mismatch between vec_select HImode and its operand QImode
> ../../gcc/config/arm/neon.md:1353:1: element mode mismatch between vec_select SImode and its operand QImode
> ../../gcc/config/arm/neon.md:1353:1: element mode mismatch between vec_select QImode and its operand HImode
> ../../gcc/config/arm/neon.md:1353:1: element mode mismatch between vec_select SImode and its operand HImode
> ../../gcc/config/arm/neon.md:1353:1: element mode mismatch between vec_select QImode and its operand SImode
> ../../gcc/config/arm/neon.md:1353:1: element mode mismatch between vec_select HImode and its operand SImode
> ../../gcc/config/arm/neon.md:1407:1: element mode mismatch between vec_select HImode and its operand QImode
> ../../gcc/config/arm/neon.md:1407:1: element mode mismatch between vec_select SImode and its operand QImode
> ../../gcc/config/arm/neon.md:1407:1: element mode mismatch between vec_select QImode and its operand HImode
> ../../gcc/config/arm/neon.md:1407:1: element mode mismatch between vec_select SImode and its operand HImode
> ../../gcc/config/arm/neon.md:1407:1: element mode mismatch between vec_select QImode and its operand SImode
> ../../gcc/config/arm/neon.md:1407:1: element mode mismatch between vec_select HImode and its operand SImode
> ../../gcc/config/arm/neon.md:1422:1: element mode mismatch between vec_select HImode and its operand QImode
> ../../gcc/config/arm/neon.md:1422:1: element mode mismatch between vec_select SImode and its operand QImode
> ../../gcc/config/arm/neon.md:1422:1: element mode mismatch between vec_select QImode and its operand HImode
> ../../gcc/config/arm/neon.md:1422:1: element mode mismatch between vec_select SImode and its operand HImode
> ../../gcc/config/arm/neon.md:1422:1: element mode mismatch between vec_select QImode and its operand SImode
> ../../gcc/config/arm/neon.md:1422:1: element mode mismatch between vec_select HImode and its operand SImode
>
> ../../gcc/config/mips/mips-msa.md:1219:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1219:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1219:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1219:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1307:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1307:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1307:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1307:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1401:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1401:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1401:1: vec_select parallel with 2 elements, expected 4
> ../../gcc/config/mips/mips-msa.md:1401:1: vec_select parallel with 2 elements, expected 4
I think these are all bugs and should be fixed and thus this checking
is good.
Of course we'd better not break (too many) targets at this point...
Richard.
> 2017-03-03 Jakub Jelinek <jakub@redhat.com>
>
> * genrecog.c (validate_pattern): Add VEC_SELECT validation.
> * genmodes.c (emit_min_insn_modes_c): Call emit_mode_nunits
> and emit_mode_inner.
>
> --- gcc/genrecog.c.jj 2017-01-01 12:45:35.000000000 +0100
> +++ gcc/genrecog.c 2017-03-03 17:07:23.591178911 +0100
> @@ -737,6 +737,32 @@ validate_pattern (rtx pattern, md_rtx_in
> GET_MODE_NAME (GET_MODE (XEXP (pattern, 0))));
> break;
>
> + case VEC_SELECT:
> + if (GET_MODE (pattern) != VOIDmode)
> + {
> + enum machine_mode mode = GET_MODE (pattern);
> + enum machine_mode imode = GET_MODE (XEXP (pattern, 0));
> + enum machine_mode emode
> + = VECTOR_MODE_P (mode) ? GET_MODE_INNER (mode) : mode;
> + if (GET_CODE (XEXP (pattern, 1)) == PARALLEL)
> + {
> + int expected = VECTOR_MODE_P (mode) ? GET_MODE_NUNITS (mode) : 1;
> + if (XVECLEN (XEXP (pattern, 1), 0) != expected)
> + error_at (info->loc,
> + "vec_select parallel with %d elements, expected %d",
> + XVECLEN (XEXP (pattern, 1), 0), expected);
> + }
> + if (imode != VOIDmode && !VECTOR_MODE_P (imode))
> + error_at (info->loc, "%smode of first vec_select operand is not a "
> + "vector mode", GET_MODE_NAME (imode));
> + else if (imode != VOIDmode && GET_MODE_INNER (imode) != emode)
> + error_at (info->loc, "element mode mismatch between vec_select "
> + "%smode and its operand %smode",
> + GET_MODE_NAME (emode),
> + GET_MODE_NAME (GET_MODE_INNER (imode)));
> + }
> + break;
> +
> default:
> break;
> }
> --- gcc/genmodes.c.jj 2017-01-01 12:45:39.000000000 +0100
> +++ gcc/genmodes.c 2017-03-03 17:06:43.009718721 +0100
> @@ -1789,7 +1789,9 @@ emit_min_insn_modes_c (void)
> emit_min_insn_modes_c_header ();
> emit_mode_name ();
> emit_mode_class ();
> + emit_mode_nunits ();
> emit_mode_wider ();
> + emit_mode_inner ();
> emit_class_narrowest_mode ();
> }
>
>
> Jakub
>
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)