From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 2BC323858D3C; Thu, 9 Nov 2023 09:55:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2BC323858D3C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1699523731; bh=BcSqJiFlMzT17reOqnJktbflCKuMCKcfWmqpSfgyGAE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Um6yVG1hiZmzMSdD240ByuvHlSaH4AjFRGk9j4OnUbb7XTJOuQPMSXofQUR/KUfyk suF2t89V4j0h13AapmQ/fq20/6GadA5DSJFN8ymT8mbAfep96dd1xPiEzUY1jzk6ls 2eITDGzidzk44HXrnATdvOuQsKdemHs+4YZgdG4c= From: "rguenth at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/112450] RVV vectorization ICE in vect_get_loop_mask, at tree-vect-loop.cc:11037 Date: Thu, 09 Nov 2023 09:55:29 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: tree-optimization X-Bugzilla-Version: 14.0 X-Bugzilla-Keywords: ice-on-valid-code X-Bugzilla-Severity: normal X-Bugzilla-Who: rguenth at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cf_reconfirmed_on cc everconfirmed bug_status Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D112450 Richard Biener changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed| |2023-11-09 CC| |rsandifo at gcc dot gnu.org Ever confirmed|0 |1 Status|UNCONFIRMED |NEW --- Comment #6 from Richard Biener --- So in fact RVV with it's single-bit element mask and the ability to produce it from a V64QImode unsigned LT compare (but not from V64SImode?) is supposed to be able to handle the "AVX512" style masking as far as checking in vect_verify_full_masking_avx512 is concerned. What I failed to implement (and check) is that the mask types have an integer mode, thus we run into if (known_eq (TYPE_VECTOR_SUBPARTS (rgm->type), TYPE_VECTOR_SUBPARTS (vectype))) return rgm->controls[index]; /* Split the vector if needed. Since we are dealing with integer mode masks with AVX512 we can operate on the integer representation performing the whole vector shifting. */ unsigned HOST_WIDE_INT factor; bool ok =3D constant_multiple_p (TYPE_VECTOR_SUBPARTS (rgm->type), TYPE_VECTOR_SUBPARTS (vectype), &facto= r); gcc_assert (ok); gcc_assert (GET_MODE_CLASS (TYPE_MODE (rgm->type)) =3D=3D MODE_INT); it would be fine if we didn't need to split the 64 element mask into two halves for a V32SImode vector op we need to mask here. We try to look at the subset of the mask by converting it to a same size integer type, right-rshift it, truncate and covert back to the mask type. That might or might not be possible with RVV masks (might or might not be the "optimal" way to do things). We can "fix" this by doing diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index a544bc9b059..c7a92354578 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -11034,24 +11034,24 @@ vect_get_loop_mask (loop_vec_info loop_vinfo, bool ok =3D constant_multiple_p (TYPE_VECTOR_SUBPARTS (rgm->type), TYPE_VECTOR_SUBPARTS (vectype), &facto= r); gcc_assert (ok); - gcc_assert (GET_MODE_CLASS (TYPE_MODE (rgm->type)) =3D=3D MODE_INT); tree mask_type =3D truth_type_for (vectype); - gcc_assert (GET_MODE_CLASS (TYPE_MODE (mask_type)) =3D=3D MODE_INT); unsigned vi =3D index / factor; unsigned vpart =3D index % factor; tree vec =3D rgm->controls[vi]; gimple_seq seq =3D NULL; vec =3D gimple_build (&seq, VIEW_CONVERT_EXPR, - lang_hooks.types.type_for_mode - (TYPE_MODE (rgm->type), 1), vec); + lang_hooks.types.type_for_size + (GET_MODE_BITSIZE (TYPE_MODE (rgm->type)) + .to_constant (), 1), vec); /* For integer mode masks simply shift the right bits into position.= */ if (vpart !=3D 0) vec =3D gimple_build (&seq, RSHIFT_EXPR, TREE_TYPE (vec), vec, build_int_cst (integer_type_node, (TYPE_VECTOR_SUBPARTS (vectype) * vpart))); - vec =3D gimple_convert (&seq, lang_hooks.types.type_for_mode - (TYPE_MODE (mask_type), 1), vec); + vec =3D gimple_convert (&seq, lang_hooks.types.type_for_size + (GET_MODE_BITSIZE (TYPE_MODE (mask_type= )) + .to_constant (), 1), vec); vec =3D gimple_build (&seq, VIEW_CONVERT_EXPR, mask_type, vec); if (seq) gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT); which then generates the "expected" partial vector code. If you don't want partial vectors for VLS modes then I guess we could also enhance the vector_modes "iteration" to allow the target to override --param vect-partial-vector-usage on a per-mode base. Or I can simply not "fix" the code above but instead add an integer mode check to vect_verify_full_masking_avx512. But as said, in principle this scheme works. That fix would be diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index a544bc9b059..0b364ac1c6e 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -1462,7 +1462,10 @@ vect_verify_full_masking_avx512 (loop_vec_info loop_vinfo ) if (!mask_type) continue; - if (TYPE_PRECISION (TREE_TYPE (mask_type)) !=3D 1) + /* For now vect_get_loop_mask only supports integer mode masks + when we need to split it. */ + if (GET_MODE_CLASS (TYPE_MODE (mask_type)) !=3D MODE_INT + || TYPE_PRECISION (TREE_TYPE (mask_type)) !=3D 1) { ok =3D false; break;=