https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95582

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #21 from Richard Biener <rguenth at gcc dot gnu.org> ---
OK, so we recognize _22 = (boolean) _21 as bool pattern (convert from 1-bit
bool to 8-bit ada bool).  vect_recog_bool_pattern has some early-outs like

  if (CONVERT_EXPR_CODE_P (rhs_code)
      || rhs_code == VIEW_CONVERT_EXPR)
    {
      if (! INTEGRAL_TYPE_P (TREE_TYPE (lhs))
          || TYPE_PRECISION (TREE_TYPE (lhs)) == 1)
        return NULL;

which might be trying to rule out VECT_SCALAR_BOOLEAN_TYPE_P lhs.  At least
we're doing

      vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (lhs));
      if (vectype == NULL_TREE)
        return NULL;

on it which will never return a VECTOR_BOOLEAN_TYPE_P and thus necessarily
trip the assert in vect_init_pattern_stmt [in case the stmt is supposed to
use mask precision].

Note the pattern as recognized doesn't necessarily do anything wrong - but
the meta recorded is inconsistent with it:

note:   using boolean precision 16 for _21 = _11 != _12;
note:   using boolean precision 16 for _22 = (boolean) _21;
note:   using boolean precision 16 for _7 = PHI <0(7), _22(5), 1(9)>

the function we trip on here doesn't contain any useful vectorization
opportunity but clearly the "pattern" is to have a "bool" compare
converted to Ada "data bool".

The conversion at hand is exposed by phiopt doing

-  if (_11 != _12)
-    goto <bb 6>; [66.00%]
-  else
-    goto <bb 7>; [34.00%]
-
-  <bb 6> [count: 0]:
+  _21 = _11 != _12;
+  _22 = (boolean) _21;

-  <bb 7> [count: 4858]:
-  # _7 = PHI <0(2), 0(3), 1(4), 0(5), 1(6)>
+  <bb 6> [count: 4858]:
+  # _7 = PHI <0(2), 0(3), 1(4), _22(5)>

where phiopt could have used the PHI arguments boolean type rather than
the LTO middle-end one also avoiding this ICE.  The interesting fact is
that the bool conversion is not useless (it changes precision) but
the IL verifier allows both types to be the result of the _11 != _12
compare (so we could add some fold pattern consuming those conversions
as well).

But this might make constructing a Ada testcase (with -flto of course)
possible by making sure there's a phiopt value-replacement opportunity
(we don't realize those "early" before LTO writeout) feeding bool
memory (so we have a real BB vectorization opportunity as well).

Now, I'm going to test

diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index f2ce75aac3e..bf57c49bf04 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -4067,7 +4067,7 @@ vect_recog_bool_pattern (vec_info *vinfo,
       || rhs_code == VIEW_CONVERT_EXPR)
     {
       if (! INTEGRAL_TYPE_P (TREE_TYPE (lhs))
-         || TYPE_PRECISION (TREE_TYPE (lhs)) == 1)
+         || VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (lhs)))
        return NULL;
       vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (lhs));
       if (vectype == NULL_TREE)

which will definitely solve this instance of the ICE but of course other
fallout is unknown.  I'm leaving the PHI-OPT "optimization" opportunity
to the Ada folks if they care.  Likewise crafting a testcase from the
above [I'm going to think again about how to funnel non-standard bool
types to the GIMPLE FE - likely an additional attribute]

Reply via email to